initial commit

This commit is contained in:
Rik Berkelder 2026-01-27 02:21:31 +01:00
commit 9eee1ce3c2
7 changed files with 1939 additions and 0 deletions

2
.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
dist
node_modules

889
package-lock.json generated Normal file
View file

@ -0,0 +1,889 @@
{
"name": "xr18-midi",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "xr18-midi",
"version": "1.0.0",
"license": "ISC",
"dependencies": {
"easymidi": "^3.1.0",
"osc": "^2.4.5",
"osc-js": "^2.4.1",
"ts-osc": "^0.3.2"
},
"devDependencies": {
"@types/node": "^25.0.10",
"tsc-watch": "^7.2.0",
"typescript": "^5.9.3"
}
},
"node_modules/@julusian/midi": {
"version": "3.6.1",
"resolved": "https://registry.npmjs.org/@julusian/midi/-/midi-3.6.1.tgz",
"integrity": "sha512-sC6tTMAMZsHOQILAv/R0On5tKKhzBQUjdyYWzh9l0UQeNry12CFIyRWK1Mep5xCHWCTUB0w4gxngpciA5PgN/Q==",
"hasInstallScript": true,
"license": "MIT",
"dependencies": {
"node-addon-api": "^6.1.0",
"pkg-prebuilds": "^1.0.0"
},
"engines": {
"node": ">=14.15"
}
},
"node_modules/@serialport/binding-mock": {
"version": "10.2.2",
"resolved": "https://registry.npmjs.org/@serialport/binding-mock/-/binding-mock-10.2.2.tgz",
"integrity": "sha512-HAFzGhk9OuFMpuor7aT5G1ChPgn5qSsklTFOTUX72Rl6p0xwcSVsRtG/xaGp6bxpN7fI9D/S8THLBWbBgS6ldw==",
"license": "MIT",
"optional": true,
"dependencies": {
"@serialport/bindings-interface": "^1.2.1",
"debug": "^4.3.3"
},
"engines": {
"node": ">=12.0.0"
}
},
"node_modules/@serialport/bindings-cpp": {
"version": "12.0.1",
"resolved": "https://registry.npmjs.org/@serialport/bindings-cpp/-/bindings-cpp-12.0.1.tgz",
"integrity": "sha512-r2XOwY2dDvbW7dKqSPIk2gzsr6M6Qpe9+/Ngs94fNaNlcTRCV02PfaoDmRgcubpNVVcLATlxSxPTIDw12dbKOg==",
"hasInstallScript": true,
"license": "MIT",
"optional": true,
"dependencies": {
"@serialport/bindings-interface": "1.2.2",
"@serialport/parser-readline": "11.0.0",
"debug": "4.3.4",
"node-addon-api": "7.0.0",
"node-gyp-build": "4.6.0"
},
"engines": {
"node": ">=16.0.0"
},
"funding": {
"url": "https://opencollective.com/serialport/donate"
}
},
"node_modules/@serialport/bindings-cpp/node_modules/@serialport/parser-delimiter": {
"version": "11.0.0",
"resolved": "https://registry.npmjs.org/@serialport/parser-delimiter/-/parser-delimiter-11.0.0.tgz",
"integrity": "sha512-aZLJhlRTjSmEwllLG7S4J8s8ctRAS0cbvCpO87smLvl3e4BgzbVgF6Z6zaJd3Aji2uSiYgfedCdNc4L6W+1E2g==",
"license": "MIT",
"optional": true,
"engines": {
"node": ">=12.0.0"
},
"funding": {
"url": "https://opencollective.com/serialport/donate"
}
},
"node_modules/@serialport/bindings-cpp/node_modules/@serialport/parser-readline": {
"version": "11.0.0",
"resolved": "https://registry.npmjs.org/@serialport/parser-readline/-/parser-readline-11.0.0.tgz",
"integrity": "sha512-rRAivhRkT3YO28WjmmG4FQX6L+KMb5/ikhyylRfzWPw0nSXy97+u07peS9CbHqaNvJkMhH1locp2H36aGMOEIA==",
"license": "MIT",
"optional": true,
"dependencies": {
"@serialport/parser-delimiter": "11.0.0"
},
"engines": {
"node": ">=12.0.0"
},
"funding": {
"url": "https://opencollective.com/serialport/donate"
}
},
"node_modules/@serialport/bindings-cpp/node_modules/node-addon-api": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.0.0.tgz",
"integrity": "sha512-vgbBJTS4m5/KkE16t5Ly0WW9hz46swAstv0hYYwMtbG7AznRhNyfLRe8HZAiWIpcHzoO7HxhLuBQj9rJ/Ho0ZA==",
"license": "MIT",
"optional": true
},
"node_modules/@serialport/bindings-interface": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/@serialport/bindings-interface/-/bindings-interface-1.2.2.tgz",
"integrity": "sha512-CJaUd5bLvtM9c5dmO9rPBHPXTa9R2UwpkJ0wdh9JCYcbrPWsKz+ErvR0hBLeo7NPeiFdjFO4sonRljiw4d2XiA==",
"license": "MIT",
"optional": true,
"engines": {
"node": "^12.22 || ^14.13 || >=16"
}
},
"node_modules/@serialport/parser-byte-length": {
"version": "12.0.0",
"resolved": "https://registry.npmjs.org/@serialport/parser-byte-length/-/parser-byte-length-12.0.0.tgz",
"integrity": "sha512-0ei0txFAj+s6FTiCJFBJ1T2hpKkX8Md0Pu6dqMrYoirjPskDLJRgZGLqoy3/lnU1bkvHpnJO+9oJ3PB9v8rNlg==",
"license": "MIT",
"optional": true,
"engines": {
"node": ">=12.0.0"
},
"funding": {
"url": "https://opencollective.com/serialport/donate"
}
},
"node_modules/@serialport/parser-cctalk": {
"version": "12.0.0",
"resolved": "https://registry.npmjs.org/@serialport/parser-cctalk/-/parser-cctalk-12.0.0.tgz",
"integrity": "sha512-0PfLzO9t2X5ufKuBO34DQKLXrCCqS9xz2D0pfuaLNeTkyGUBv426zxoMf3rsMRodDOZNbFblu3Ae84MOQXjnZw==",
"license": "MIT",
"optional": true,
"engines": {
"node": ">=12.0.0"
},
"funding": {
"url": "https://opencollective.com/serialport/donate"
}
},
"node_modules/@serialport/parser-delimiter": {
"version": "12.0.0",
"resolved": "https://registry.npmjs.org/@serialport/parser-delimiter/-/parser-delimiter-12.0.0.tgz",
"integrity": "sha512-gu26tVt5lQoybhorLTPsH2j2LnX3AOP2x/34+DUSTNaUTzu2fBXw+isVjQJpUBFWu6aeQRZw5bJol5X9Gxjblw==",
"license": "MIT",
"optional": true,
"engines": {
"node": ">=12.0.0"
},
"funding": {
"url": "https://opencollective.com/serialport/donate"
}
},
"node_modules/@serialport/parser-inter-byte-timeout": {
"version": "12.0.0",
"resolved": "https://registry.npmjs.org/@serialport/parser-inter-byte-timeout/-/parser-inter-byte-timeout-12.0.0.tgz",
"integrity": "sha512-GnCh8K0NAESfhCuXAt+FfBRz1Cf9CzIgXfp7SdMgXwrtuUnCC/yuRTUFWRvuzhYKoAo1TL0hhUo77SFHUH1T/w==",
"license": "MIT",
"optional": true,
"engines": {
"node": ">=12.0.0"
},
"funding": {
"url": "https://opencollective.com/serialport/donate"
}
},
"node_modules/@serialport/parser-packet-length": {
"version": "12.0.0",
"resolved": "https://registry.npmjs.org/@serialport/parser-packet-length/-/parser-packet-length-12.0.0.tgz",
"integrity": "sha512-p1hiCRqvGHHLCN/8ZiPUY/G0zrxd7gtZs251n+cfNTn+87rwcdUeu9Dps3Aadx30/sOGGFL6brIRGK4l/t7MuQ==",
"license": "MIT",
"optional": true,
"engines": {
"node": ">=8.6.0"
}
},
"node_modules/@serialport/parser-readline": {
"version": "12.0.0",
"resolved": "https://registry.npmjs.org/@serialport/parser-readline/-/parser-readline-12.0.0.tgz",
"integrity": "sha512-O7cywCWC8PiOMvo/gglEBfAkLjp/SENEML46BXDykfKP5mTPM46XMaX1L0waWU6DXJpBgjaL7+yX6VriVPbN4w==",
"license": "MIT",
"optional": true,
"dependencies": {
"@serialport/parser-delimiter": "12.0.0"
},
"engines": {
"node": ">=12.0.0"
},
"funding": {
"url": "https://opencollective.com/serialport/donate"
}
},
"node_modules/@serialport/parser-ready": {
"version": "12.0.0",
"resolved": "https://registry.npmjs.org/@serialport/parser-ready/-/parser-ready-12.0.0.tgz",
"integrity": "sha512-ygDwj3O4SDpZlbrRUraoXIoIqb8sM7aMKryGjYTIF0JRnKeB1ys8+wIp0RFMdFbO62YriUDextHB5Um5cKFSWg==",
"license": "MIT",
"optional": true,
"engines": {
"node": ">=12.0.0"
},
"funding": {
"url": "https://opencollective.com/serialport/donate"
}
},
"node_modules/@serialport/parser-regex": {
"version": "12.0.0",
"resolved": "https://registry.npmjs.org/@serialport/parser-regex/-/parser-regex-12.0.0.tgz",
"integrity": "sha512-dCAVh4P/pZrLcPv9NJ2mvPRBg64L5jXuiRxIlyxxdZGH4WubwXVXY/kBTihQmiAMPxbT3yshSX8f2+feqWsxqA==",
"license": "MIT",
"optional": true,
"engines": {
"node": ">=12.0.0"
},
"funding": {
"url": "https://opencollective.com/serialport/donate"
}
},
"node_modules/@serialport/parser-slip-encoder": {
"version": "12.0.0",
"resolved": "https://registry.npmjs.org/@serialport/parser-slip-encoder/-/parser-slip-encoder-12.0.0.tgz",
"integrity": "sha512-0APxDGR9YvJXTRfY+uRGhzOhTpU5akSH183RUcwzN7QXh8/1jwFsFLCu0grmAUfi+fItCkR+Xr1TcNJLR13VNA==",
"license": "MIT",
"optional": true,
"engines": {
"node": ">=12.0.0"
},
"funding": {
"url": "https://opencollective.com/serialport/donate"
}
},
"node_modules/@serialport/parser-spacepacket": {
"version": "12.0.0",
"resolved": "https://registry.npmjs.org/@serialport/parser-spacepacket/-/parser-spacepacket-12.0.0.tgz",
"integrity": "sha512-dozONxhPC/78pntuxpz/NOtVps8qIc/UZzdc/LuPvVsqCoJXiRxOg6ZtCP/W58iibJDKPZPAWPGYeZt9DJxI+Q==",
"license": "MIT",
"optional": true,
"engines": {
"node": ">=12.0.0"
},
"funding": {
"url": "https://opencollective.com/serialport/donate"
}
},
"node_modules/@serialport/stream": {
"version": "12.0.0",
"resolved": "https://registry.npmjs.org/@serialport/stream/-/stream-12.0.0.tgz",
"integrity": "sha512-9On64rhzuqKdOQyiYLYv2lQOh3TZU/D3+IWCR5gk0alPel2nwpp4YwDEGiUBfrQZEdQ6xww0PWkzqth4wqwX3Q==",
"license": "MIT",
"optional": true,
"dependencies": {
"@serialport/bindings-interface": "1.2.2",
"debug": "4.3.4"
},
"engines": {
"node": ">=12.0.0"
},
"funding": {
"url": "https://opencollective.com/serialport/donate"
}
},
"node_modules/@types/node": {
"version": "25.0.10",
"resolved": "https://registry.npmjs.org/@types/node/-/node-25.0.10.tgz",
"integrity": "sha512-zWW5KPngR/yvakJgGOmZ5vTBemDoSqF3AcV/LrO5u5wTWyEAVVh+IT39G4gtyAkh3CtTZs8aX/yRM82OfzHJRg==",
"dev": true,
"license": "MIT",
"dependencies": {
"undici-types": "~7.16.0"
}
},
"node_modules/ansi-regex": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"license": "MIT",
"dependencies": {
"color-convert": "^2.0.1"
},
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
"node_modules/binpack": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/binpack/-/binpack-0.1.0.tgz",
"integrity": "sha512-KcSrsGiIKgklTWweVb9XnZPWO1/rGSsK3fwR7VnbDPbLKPlkvSKd/ZrJ1W712r6HzH5u0fa/AZCftATO09x8Aw=="
},
"node_modules/cliui": {
"version": "8.0.1",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
"integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
"license": "ISC",
"dependencies": {
"string-width": "^4.2.0",
"strip-ansi": "^6.0.1",
"wrap-ansi": "^7.0.0"
},
"engines": {
"node": ">=12"
}
},
"node_modules/color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"license": "MIT",
"dependencies": {
"color-name": "~1.1.4"
},
"engines": {
"node": ">=7.0.0"
}
},
"node_modules/color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"license": "MIT"
},
"node_modules/cross-spawn": {
"version": "7.0.6",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
"integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
"dev": true,
"license": "MIT",
"dependencies": {
"path-key": "^3.1.0",
"shebang-command": "^2.0.0",
"which": "^2.0.1"
},
"engines": {
"node": ">= 8"
}
},
"node_modules/debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
"license": "MIT",
"optional": true,
"dependencies": {
"ms": "2.1.2"
},
"engines": {
"node": ">=6.0"
},
"peerDependenciesMeta": {
"supports-color": {
"optional": true
}
}
},
"node_modules/duplexer": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz",
"integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==",
"dev": true,
"license": "MIT"
},
"node_modules/easymidi": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/easymidi/-/easymidi-3.1.0.tgz",
"integrity": "sha512-bxEwfPysM1L+SO/qwHaYu9dvTxw2QHFjGV9EMzqGQJbhEP2MupKpg6eJMkj+uoXN0Ep1JhVPLbNLPmt3UkZRTw==",
"license": "MIT",
"dependencies": {
"@julusian/midi": "^3.0.0-3"
},
"engines": {
"node": ">=14.15"
}
},
"node_modules/emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
"license": "MIT"
},
"node_modules/escalade": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
"integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
"license": "MIT",
"engines": {
"node": ">=6"
}
},
"node_modules/event-stream": {
"version": "3.3.4",
"resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz",
"integrity": "sha512-QHpkERcGsR0T7Qm3HNJSyXKEEj8AHNxkY3PK8TS2KJvQ7NiSHe3DDpwVKKtoYprL/AreyzFBeIkBIWChAqn60g==",
"dev": true,
"license": "MIT",
"dependencies": {
"duplexer": "~0.1.1",
"from": "~0",
"map-stream": "~0.1.0",
"pause-stream": "0.0.11",
"split": "0.3",
"stream-combiner": "~0.0.4",
"through": "~2.3.1"
}
},
"node_modules/from": {
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz",
"integrity": "sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==",
"dev": true,
"license": "MIT"
},
"node_modules/get-caller-file": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
"license": "ISC",
"engines": {
"node": "6.* || 8.* || >= 10.*"
}
},
"node_modules/is-fullwidth-code-point": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/isexe": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
"dev": true,
"license": "ISC"
},
"node_modules/long": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz",
"integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==",
"license": "Apache-2.0"
},
"node_modules/map-stream": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz",
"integrity": "sha512-CkYQrPYZfWnu/DAmVCpTSX/xHpKZ80eKh2lAkyA6AJTef6bW+6JpbQZN5rofum7da+SyN1bi5ctTm+lTfcCW3g==",
"dev": true
},
"node_modules/ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"license": "MIT",
"optional": true
},
"node_modules/node-addon-api": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-6.1.0.tgz",
"integrity": "sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==",
"license": "MIT"
},
"node_modules/node-cleanup": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/node-cleanup/-/node-cleanup-2.1.2.tgz",
"integrity": "sha512-qN8v/s2PAJwGUtr1/hYTpNKlD6Y9rc4p8KSmJXyGdYGZsDGKXrGThikLFP9OCHFeLeEpQzPwiAtdIvBLqm//Hw==",
"dev": true,
"license": "MIT"
},
"node_modules/node-gyp-build": {
"version": "4.6.0",
"resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.0.tgz",
"integrity": "sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==",
"license": "MIT",
"optional": true,
"bin": {
"node-gyp-build": "bin.js",
"node-gyp-build-optional": "optional.js",
"node-gyp-build-test": "build-test.js"
}
},
"node_modules/osc": {
"version": "2.4.5",
"resolved": "https://registry.npmjs.org/osc/-/osc-2.4.5.tgz",
"integrity": "sha512-Nc4/qcl+vA/CMxiKS1xrYgzjfnyB3W94gZnrkn3eTzihlndbEml6+wj1YQNKBI4r+qrw3obCcEoU7SVH/OxpxA==",
"license": "(MIT OR GPL-2.0)",
"dependencies": {
"long": "4.0.0",
"slip": "1.0.2",
"wolfy87-eventemitter": "5.2.9",
"ws": "8.18.0"
},
"optionalDependencies": {
"serialport": "12.0.0"
}
},
"node_modules/osc-js": {
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/osc-js/-/osc-js-2.4.1.tgz",
"integrity": "sha512-QlSeRKJclL47FNvO1MUCAAp9frmCF9zcYbnf6R9HpcklAst8ZyX3ISsk1v/Vghr/5GmXn0bhVjFXF9h+hfnl4Q==",
"license": "MIT",
"dependencies": {
"ws": "^8.16.0"
}
},
"node_modules/osc-min": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/osc-min/-/osc-min-1.1.2.tgz",
"integrity": "sha512-8DbiO8ME85R75stgNVCZtHxB9MNBBNcyy+isNBXrsFeinXGjwNAauvKVmGlfRas5VJWC/mhzIx7spR2gFvWxvg==",
"license": "Zlib",
"dependencies": {
"binpack": "~0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/osc/node_modules/ws": {
"version": "8.18.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz",
"integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==",
"license": "MIT",
"engines": {
"node": ">=10.0.0"
},
"peerDependencies": {
"bufferutil": "^4.0.1",
"utf-8-validate": ">=5.0.2"
},
"peerDependenciesMeta": {
"bufferutil": {
"optional": true
},
"utf-8-validate": {
"optional": true
}
}
},
"node_modules/path-key": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/pause-stream": {
"version": "0.0.11",
"resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz",
"integrity": "sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==",
"dev": true,
"license": [
"MIT",
"Apache2"
],
"dependencies": {
"through": "~2.3"
}
},
"node_modules/pkg-prebuilds": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/pkg-prebuilds/-/pkg-prebuilds-1.0.0.tgz",
"integrity": "sha512-D9wlkXZCmjxj2kBHTw3fGSyjoahr33breGBoJcoezpi7ouYS59DJVOHMZ+dgqacSrZiJo4qtkXxLQTE+BqXJmQ==",
"license": "MIT",
"dependencies": {
"yargs": "^17.7.2"
},
"bin": {
"pkg-prebuilds-copy": "bin/copy.mjs",
"pkg-prebuilds-verify": "bin/verify.mjs"
},
"engines": {
"node": ">= 14.15.0"
}
},
"node_modules/ps-tree": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/ps-tree/-/ps-tree-1.2.0.tgz",
"integrity": "sha512-0VnamPPYHl4uaU/nSFeZZpR21QAWRz+sRv4iW9+v/GS/J5U5iZB5BNN6J0RMoOvdx2gWM2+ZFMIm58q24e4UYA==",
"dev": true,
"license": "MIT",
"dependencies": {
"event-stream": "=3.3.4"
},
"bin": {
"ps-tree": "bin/ps-tree.js"
},
"engines": {
"node": ">= 0.10"
}
},
"node_modules/require-directory": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
"integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/serialport": {
"version": "12.0.0",
"resolved": "https://registry.npmjs.org/serialport/-/serialport-12.0.0.tgz",
"integrity": "sha512-AmH3D9hHPFmnF/oq/rvigfiAouAKyK/TjnrkwZRYSFZxNggJxwvbAbfYrLeuvq7ktUdhuHdVdSjj852Z55R+uA==",
"license": "MIT",
"optional": true,
"dependencies": {
"@serialport/binding-mock": "10.2.2",
"@serialport/bindings-cpp": "12.0.1",
"@serialport/parser-byte-length": "12.0.0",
"@serialport/parser-cctalk": "12.0.0",
"@serialport/parser-delimiter": "12.0.0",
"@serialport/parser-inter-byte-timeout": "12.0.0",
"@serialport/parser-packet-length": "12.0.0",
"@serialport/parser-readline": "12.0.0",
"@serialport/parser-ready": "12.0.0",
"@serialport/parser-regex": "12.0.0",
"@serialport/parser-slip-encoder": "12.0.0",
"@serialport/parser-spacepacket": "12.0.0",
"@serialport/stream": "12.0.0",
"debug": "4.3.4"
},
"engines": {
"node": ">=16.0.0"
},
"funding": {
"url": "https://opencollective.com/serialport/donate"
}
},
"node_modules/shebang-command": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
"dev": true,
"license": "MIT",
"dependencies": {
"shebang-regex": "^3.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/shebang-regex": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/slip": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/slip/-/slip-1.0.2.tgz",
"integrity": "sha512-XrcHe3NAcyD3wO+O4I13RcS4/3AF+S9RvGNj9JhJeS02HyImwD2E3QWLrmn9hBfL+fB6yapagwxRkeyYzhk98g==",
"license": "(MIT OR GPL-2.0)"
},
"node_modules/split": {
"version": "0.3.3",
"resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz",
"integrity": "sha512-wD2AeVmxXRBoX44wAycgjVpMhvbwdI2aZjCkvfNcH1YqHQvJVa1duWc73OyVGJUc05fhFaTZeQ/PYsrmyH0JVA==",
"dev": true,
"license": "MIT",
"dependencies": {
"through": "2"
},
"engines": {
"node": "*"
}
},
"node_modules/stream-combiner": {
"version": "0.0.4",
"resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz",
"integrity": "sha512-rT00SPnTVyRsaSz5zgSPma/aHSOic5U1prhYdRy5HS2kTZviFpmDgzilbtsJsxiroqACmayynDN/9VzIbX5DOw==",
"dev": true,
"license": "MIT",
"dependencies": {
"duplexer": "~0.1.1"
}
},
"node_modules/string-argv": {
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz",
"integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=0.6.19"
}
},
"node_modules/string-width": {
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
"license": "MIT",
"dependencies": {
"emoji-regex": "^8.0.0",
"is-fullwidth-code-point": "^3.0.0",
"strip-ansi": "^6.0.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/strip-ansi": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
"license": "MIT",
"dependencies": {
"ansi-regex": "^5.0.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/through": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
"integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==",
"dev": true,
"license": "MIT"
},
"node_modules/ts-osc": {
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/ts-osc/-/ts-osc-0.3.2.tgz",
"integrity": "sha512-ph+RVCILqDd28g8S/njCFaHvTWVOWU9VYJ1Z1+q/1ZobK5iE3sJPoXfvuy3Ft7nrE2leqfgRLe2cjm0qSQUhsQ==",
"license": "MIT",
"dependencies": {
"osc-min": "^1.1.2"
}
},
"node_modules/tsc-watch": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/tsc-watch/-/tsc-watch-7.2.0.tgz",
"integrity": "sha512-4gRFawQD1cVSaILvG7wl2x6NtteKbS2dGBMbL7Q6n1ldLIOKXCJUoEwUXdGuee4dp+zcnA6tukBBLz1lZrNI9w==",
"dev": true,
"license": "MIT",
"dependencies": {
"cross-spawn": "^7.0.6",
"node-cleanup": "^2.1.2",
"ps-tree": "^1.2.0",
"string-argv": "^0.3.2"
},
"bin": {
"tsc-watch": "dist/lib/tsc-watch.js"
},
"engines": {
"node": ">=12.12.0"
},
"peerDependencies": {
"typescript": "*"
}
},
"node_modules/typescript": {
"version": "5.9.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
"dev": true,
"license": "Apache-2.0",
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
},
"engines": {
"node": ">=14.17"
}
},
"node_modules/undici-types": {
"version": "7.16.0",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz",
"integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==",
"dev": true,
"license": "MIT"
},
"node_modules/which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
"dev": true,
"license": "ISC",
"dependencies": {
"isexe": "^2.0.0"
},
"bin": {
"node-which": "bin/node-which"
},
"engines": {
"node": ">= 8"
}
},
"node_modules/wolfy87-eventemitter": {
"version": "5.2.9",
"resolved": "https://registry.npmjs.org/wolfy87-eventemitter/-/wolfy87-eventemitter-5.2.9.tgz",
"integrity": "sha512-P+6vtWyuDw+MB01X7UeF8TaHBvbCovf4HPEMF/SV7BdDc1SMTiBy13SRD71lQh4ExFTG1d/WNzDGDCyOKSMblw==",
"license": "Unlicense"
},
"node_modules/wrap-ansi": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
"license": "MIT",
"dependencies": {
"ansi-styles": "^4.0.0",
"string-width": "^4.1.0",
"strip-ansi": "^6.0.0"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
}
},
"node_modules/ws": {
"version": "8.19.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz",
"integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==",
"license": "MIT",
"engines": {
"node": ">=10.0.0"
},
"peerDependencies": {
"bufferutil": "^4.0.1",
"utf-8-validate": ">=5.0.2"
},
"peerDependenciesMeta": {
"bufferutil": {
"optional": true
},
"utf-8-validate": {
"optional": true
}
}
},
"node_modules/y18n": {
"version": "5.0.8",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
"integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
"license": "ISC",
"engines": {
"node": ">=10"
}
},
"node_modules/yargs": {
"version": "17.7.2",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
"integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
"license": "MIT",
"dependencies": {
"cliui": "^8.0.1",
"escalade": "^3.1.1",
"get-caller-file": "^2.0.5",
"require-directory": "^2.1.1",
"string-width": "^4.2.3",
"y18n": "^5.0.5",
"yargs-parser": "^21.1.1"
},
"engines": {
"node": ">=12"
}
},
"node_modules/yargs-parser": {
"version": "21.1.1",
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
"integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
"license": "ISC",
"engines": {
"node": ">=12"
}
}
}
}

25
package.json Normal file
View file

@ -0,0 +1,25 @@
{
"name": "xr18-midi",
"version": "1.0.0",
"main": "dist/index.js",
"scripts": {
"start": "node dist/index.js",
"dev": "tsc-watch --onSuccess \"npm start\""
},
"author": "Rik Berkelder <mail@riksolo.com> (https://riksolo.com)",
"license": "ISC",
"description": "",
"type": "module",
"devDependencies": {
"@types/node": "^25.0.10",
"tsc-watch": "^7.2.0",
"typescript": "^5.9.3"
},
"dependencies": {
"easymidi": "^3.1.0",
"osc": "^2.4.5",
"osc-js": "^2.4.1",
"ts-osc": "^0.3.2"
},
"packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
}

383
src/index.ts Normal file
View file

@ -0,0 +1,383 @@
import * as midi from 'easymidi';
import type { EventEmitter } from 'node:stream';
import osc from 'osc';
console.log(midi.getInputs())
function mapNumber(value: number, fromMin: number, fromMax: number, toMin: number, toMax: number): number {
if (value <= fromMin) return toMin;
if (value >= fromMax) return toMax;
const absFromMax = fromMax - fromMin;
const absToMax = toMax - toMin;
const mapped = (value / absFromMax) * absToMax;
return mapped + toMin;
}
enum MessageType {
NoteOn = 'noteon',
NoteOff = 'noteoff',
Pitch = 'pitch'
}
type DataLookup = {
[MessageType.NoteOn]: midi.Note,
[MessageType.NoteOff]: midi.Note,
[MessageType.Pitch]: midi.Pitch
}
const defaultData = {
[MessageType.NoteOn]: { channel: 0, note: 0, velocity: 0 },
[MessageType.NoteOff]: { channel: 0, note: 0, velocity: 0 },
[MessageType.Pitch]: { channel: 0, value: 0 }
}
interface IMidiControlOptions {
feedbackInput: boolean,
noPageFeedback: boolean,
noStoreInput: boolean
}
class MidiControl<T extends MessageType> {
public values: { [page: number]: DataLookup[T] } = [];
private outputs: { [page: number]: (data: any) => void } = [];
private page: number = 0;
constructor(
private device: MidiDevice,
public type: MessageType,
private filter: Partial<DataLookup[T]>,
private options: Partial<IMidiControlOptions> = {}
) {
this.device.input.addListener(type, (data: DataLookup[T]) => {
// Check incoming data against filter
for (const [k, v] of Object.entries(this.filter)) {
const rawData = data as unknown as { [key: string]: string | number };
if (typeof rawData !== 'object' || rawData === null) return;
if (!(k in rawData)) return;
if (rawData[k] !== v) return;
}
//console.debug('matched data', data);
// store new value
if (!this.options.noStoreInput) this.values[this.page] = data;
if (this.options.feedbackInput) this.feedback(data);
const output = this.outputs[this.page];
if (!output || output === undefined) return;
output(data);
})
}
private defaultData<D extends DataLookup[T]>(): D {
return defaultData[this.type] as D;
}
private feedback(data: DataLookup[T]) {
// ugly typing here, but library overloads are a little annoying to work around. worst case scenario nothing happens
this.device.output.send(this.type as any, { ...data, ...this.filter } as any);
}
public getPage(): number { return this.page };
public getValue(page: number): DataLookup[T] | undefined {
return this.values[page];
}
public setPage(page: number) {
this.page = page;
const values = this.values[page] ?? this.defaultData();
if (!this.options.noPageFeedback) this.feedback(values);
}
public addOutput<D extends DataLookup[T]>(pages: number | number[], cb: (D: D) => void): void {
if (typeof pages === 'number') pages = [pages];
for (const page of pages) {
this.outputs[page] = cb;
}
}
public handleFeedback<D extends DataLookup[T]>(pages: number | number[], data: Partial<D>, noStore?: boolean): void {
if (typeof pages === 'number') pages = [pages];
const newValue = { ...this.defaultData(), ...this.filter, ...data };
for (const page of pages) {
if (!noStore) this.values[page] = newValue;
if (page === this.page) {
this.feedback(newValue)
}
}
}
}
class MidiDevice {
public input: midi.Input;
public output: midi.Output;
private _page: number = 0;
public controls: Array<MidiControl<MessageType>> = [];
constructor(device: string) {
this.input = new midi.Input(device);
this.output = new midi.Output(device);
}
public addControl<T extends MessageType>(type: T, filter: Partial<DataLookup[T]>, options: Partial<IMidiControlOptions> = {}): MidiControl<T> {
const control = new MidiControl(this, type, filter, options);
this.controls.push(control);
return control;
}
public setPage(page: number) {
this._page = page;
for (const control of this.controls) {
control.setPage(page);
}
}
public get page(): number {
return this._page;
}
}
interface IOSCEvent {
address: string;
handler: (message: osc.ResponseMessage<osc.MessageArg>) => void;
}
class OSCDevice {
private port: osc.UDPPort;
private listeners: Array<IOSCEvent> = [];
constructor(localHost: string, remoteHost: string, port: number) {
this.port = new osc.UDPPort({
localAddress: localHost,
remoteAddress: remoteHost,
localPort: port,
remotePort: port
});
this.port.on('message', msg => {
// console.log('msg', msg)
for (const listener of this.listeners) {
if (msg.address !== listener.address) continue;
listener.handler(msg);
}
})
this.port.open();
this.pollFeedback()
setInterval(() => {
this.pollFeedback()
}, 5000);
}
private pollFeedback() {
this.port.send({
address: '/xremote',
args: [{ type: 'i', value: 1 }]
})
}
public sendInt(address: string, value: number) {
this.port.send({ address, args: [{ type: 'i', value }] });
}
public sendFloat(address: string, value: number) {
this.port.send({ address, args: [{ type: 'f', value }] });
}
public sendString(address: string, value: string) {
this.port.send({ address, args: [{ type: 's', value }] });
}
public sendBytes(address: string, value: osc.Uint8Array) {
this.port.send({ address, args: [{ type: 's', value }] });
}
public addListener(address: string, handler: IOSCEvent['handler']): number {
const newLength = this.listeners.push({
address,
handler
});
return newLength - 1;
}
}
const mdev = new MidiDevice('Platform X+1 V2.10');
const odev = new OSCDevice('0.0.0.0', '192.168.0.47', 10024);
// const client = new osc.OSCClient('192.168.0.26', 9889);
// DEBUG OUT
//['noteon', 'pitch'].map((v) => mdev.input.addListener(v, (data) => { console.log('data', data) }))
// MM MM MMMM MMMMMM MMMMMM MMMMMM MM MM MMMM MMMM
// MMMM MMMM MM MM MM MM MM MM MM MMMM MM MM MM MM MM
// MM MM MM MMMMMMMM MM MM MM MM MM MM MMMM MM MM
// MM MM MM MM MMMMMM MMMMMM MM MM MM MM MMMM MM
// MM MM MM MM MM MM MM MM MM MM MM MM MM
// MM MM MM MM MM MM MMMMMM MM MM MMMM MMMM
const PAGE_MAIN = 0;
const PAGE_HP = 1;
const PAGE_PC = 2;
const ALL_PAGES = [PAGE_MAIN, PAGE_HP, PAGE_PC];
const OSC_LEVEL_0 = 0.75;
// TURN OFF ALL LEDS
const feedbackOff = () => {
for (const control of mdev.controls) {
if (control.type === MessageType.NoteOn) {
control.handleFeedback(ALL_PAGES, { velocity: 0 }, true);
}
}
}
const offButton = mdev.addControl(MessageType.NoteOn, { channel: 0, note: 39 }, { noPageFeedback: true })
offButton.addOutput(ALL_PAGES, (d) => feedbackOff());
// PAGE SWITCHING
const pageFeedback = () => {
const page = mdev.page;
buttonSel1.handleFeedback(ALL_PAGES, { velocity: page === PAGE_MAIN ? 127 : 0 })
buttonSel2.handleFeedback(ALL_PAGES, { velocity: page === PAGE_HP ? 127 : 0 })
buttonSel3.handleFeedback(ALL_PAGES, { velocity: page === PAGE_PC ? 127 : 0 })
}
const buttonSel1 = mdev.addControl(MessageType.NoteOn, { channel: 0, note: 8 }, { noPageFeedback: true })
buttonSel1.addOutput(ALL_PAGES, (d) => {
if (d.velocity === 127) mdev.setPage(PAGE_MAIN)
pageFeedback();
});
const buttonSel2 = mdev.addControl(MessageType.NoteOn, { channel: 0, note: 9 }, { noPageFeedback: true })
buttonSel2.addOutput(ALL_PAGES, (d) => {
if (d.velocity === 127) mdev.setPage(PAGE_HP)
pageFeedback();
});
const buttonSel3 = mdev.addControl(MessageType.NoteOn, { channel: 0, note: 10 }, { noPageFeedback: true })
buttonSel3.addOutput(ALL_PAGES, (d) => {
if (d.velocity === 127) mdev.setPage(PAGE_PC)
pageFeedback();
});
// FADERS
const faders = [0, 1, 2, 3, 4, 5, 6, 7].map((f) => mdev.addControl(MessageType.Pitch, { channel: f as midi.Channel }, { feedbackInput: true }));
const setLevel = (addr: string, value: number, max: number = 1) => odev.sendFloat(addr, mapNumber(value, 0, 16383, 0, max));
const levelFeedback = (fader: number, page: number, value: number, max: number = 1) => {
faders[fader]?.handleFeedback(page, { value: mapNumber(value, 0, max, 0, 16383) });
}
const fader2way = (fader: number, page: number, addr: string, max: number = 1) => {
faders[fader]?.addOutput(page, d => setLevel(addr, d.value, max));
odev.addListener(addr, d => { levelFeedback(fader, page, (d.args as any)[0], max) });
}
// PAGE 1: Main
fader2way(0, PAGE_MAIN, '/dca/1/fader', OSC_LEVEL_0)
fader2way(1, PAGE_MAIN, '/rtn/1/mix/fader')
fader2way(2, PAGE_MAIN, '/bus/1/mix/fader')
fader2way(3, PAGE_MAIN, '/ch/01/mix/fader')
fader2way(4, PAGE_MAIN, '/ch/03/mix/fader')
fader2way(5, PAGE_MAIN, '/ch/05/mix/fader')
fader2way(6, PAGE_MAIN, '/ch/07/mix/fader')
fader2way(7, PAGE_MAIN, '/ch/09/mix/fader')
// PAGE 2: Headphones
fader2way(0, PAGE_HP, '/bus/1/mix/fader')
fader2way(1, PAGE_HP, '/ch/15/mix/01/level')
fader2way(2, PAGE_HP, '/ch/16/mix/01/level')
fader2way(3, PAGE_HP, '/ch/01/mix/01/level')
fader2way(4, PAGE_HP, '/ch/03/mix/01/level')
fader2way(5, PAGE_HP, '/ch/05/mix/01/level')
fader2way(6, PAGE_HP, '/ch/07/mix/01/level')
fader2way(7, PAGE_HP, '/ch/09/mix/01/level')
// PAGE 3: PC
fader2way(0, PAGE_PC, '/bus/1/mix/fader')
fader2way(1, PAGE_PC, '/ch/15/mix/03/level')
fader2way(2, PAGE_PC, '/ch/16/mix/03/level')
fader2way(3, PAGE_PC, '/ch/01/mix/03/level')
fader2way(4, PAGE_PC, '/ch/03/mix/03/level')
fader2way(5, PAGE_PC, '/ch/05/mix/03/level')
fader2way(6, PAGE_PC, '/ch/07/mix/03/level')
fader2way(7, PAGE_PC, '/ch/09/mix/03/level')
const button = (note: number) => mdev.addControl(MessageType.NoteOn, { channel: 0, note }, { feedbackInput: false, noStoreInput: true });
const mutes = [16, 17, 18, 19, 20, 21, 22, 23].map(n => button(n));
// MUTE BUTTONS
const buttonToggle = (control: MidiControl<MessageType.NoteOn> | undefined, page: number, addr: string) => {
if (!control) return;
control.addOutput(page, (d) => {
if (d.velocity !== 127) return;
const value = control.getValue(page);
if (!value || value.velocity > 1) {
control.handleFeedback(page, { velocity: 0 });
odev.sendInt(addr, 1);
} else {
control.handleFeedback(page, { velocity: 127 });
odev.sendInt(addr, 0);
}
})
odev.addListener(addr, d => {
console.log('fb page', page, 'val', d.args)
control.handleFeedback(page, { velocity: (d.args as any)[0] === 0 ? 127 : 0 });
})
}
// PAGE 1: Main
buttonToggle(mutes[0], PAGE_MAIN, '/dca/1/on')
buttonToggle(mutes[1], PAGE_MAIN, '/rtn/1/mix/on')
buttonToggle(mutes[2], PAGE_MAIN, '/bus/1/mix/on')
buttonToggle(mutes[3], PAGE_MAIN, '/ch/01/mix/on')
buttonToggle(mutes[4], PAGE_MAIN, '/ch/03/mix/on')
buttonToggle(mutes[5], PAGE_MAIN, '/ch/05/mix/on')
buttonToggle(mutes[6], PAGE_MAIN, '/ch/07/mix/on')
buttonToggle(mutes[7], PAGE_MAIN, '/ch/09/mix/on')
// PAGE 2: Headphones
buttonToggle(mutes[0], PAGE_HP, '/bus/1/mix/on')
buttonToggle(mutes[1], PAGE_HP, '/ch/15/mix/on')
buttonToggle(mutes[2], PAGE_HP, '/ch/16/mix/on')
buttonToggle(mutes[3], PAGE_HP, '/ch/01/mix/on')
buttonToggle(mutes[4], PAGE_HP, '/ch/03/mix/on')
buttonToggle(mutes[5], PAGE_HP, '/ch/05/mix/on')
buttonToggle(mutes[6], PAGE_HP, '/ch/07/mix/on')
buttonToggle(mutes[7], PAGE_HP, '/ch/09/mix/on')
// PAGE 3: PC
buttonToggle(mutes[0], PAGE_PC, '/bus/1/mix/on')
buttonToggle(mutes[1], PAGE_PC, '/ch/15/mix/on')
buttonToggle(mutes[2], PAGE_PC, '/ch/16/mix/on')
buttonToggle(mutes[3], PAGE_PC, '/ch/01/mix/on')
buttonToggle(mutes[4], PAGE_PC, '/ch/03/mix/on')
buttonToggle(mutes[5], PAGE_PC, '/ch/05/mix/on')
buttonToggle(mutes[6], PAGE_PC, '/ch/07/mix/on')
buttonToggle(mutes[7], PAGE_PC, '/ch/09/mix/on')

120
src/types/osc/osc.d.ts vendored Normal file
View file

@ -0,0 +1,120 @@
// Right types
type UDPPortOptions = {
localPort?: number
localAddress?: string
remotePort?: number
remoteAddress?: string
broadcast?: boolean
multicastTTL?: number
multicastMembership?: string[]
socket?: any
socketId?: any
metadata?: boolean
}
type MessageArgFloat = {
type: "f"
value: number
}
type MessageArgInt = {
type: "i"
value: number
}
type MessageArgString = {
type: "s"
value: string
}
type MessageArgBytes = {
type: "s"
value: Uint8Array
}
type MessageArg =
| MessageArgFloat
| MessageArgString
| MessageArgInt
| MessageArgBytes
type SendMessage<ARG_A = MessageArg[]> = {
address: string
args?: ARG_A
}
type ResponseMessage<ARG_A = MessageArg[]> = {
address: string
args: ARG_A
}
type OnListenerReady = () => void
type OnListenerMessage<ARG_T = MessageArg[]> = (
message: ResponseMessage<ARG_T>,
timeTag: FullTimeTag,
info: any
) => void
type OnListenerError = (error: any) => void
type OnListeners = OnListenerReady | OnListenerMessage | OnListenerError
declare class OscBase {
open(): void
listen(): void
close(): void
}
declare class OscEventsAndBase extends OscBase {
// Send message.
send(oscPacket: SendMessage): void
// On every time.
on(event: "ready", listener: OnListenerReady): void
on<ARG_T = MessageArg>(
event: "message",
listener: OnListenerMessage<ARG_T>
): void
on(event: "error", listener: OnListenerError): void
// Only on single time - auto off after first time.
once(event: "ready", listener: OnListenerReady): void
once<ARG_T = MessageArg>(
event: "message",
listener: OnListenerMessage<ARG_T>
): void
once(event: "error", listener: OnListenerError): void
// Any here because the shape of the return arg does not matter.
off<ARG_T = any>(
event: "read" | "message" | "error",
listener: OnListeners<ARG_T>
): void
}
class UDPPort extends OscEventsAndBase {
constructor(options?: UDPPortOptions)
}
declare module "osc" {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
// import osc from "osc"
// import { UDPPort } from "./osc"
export {
UDPPort,
UDPPortOptions,
MessageArgFloat,
MessageArgInt,
MessageArgString,
MessageArgBytes,
Uint8Array,
MessageArg,
SendMessage,
ResponseMessage,
OnListenerReady,
OnListenerError,
OscBase,
OscEventsAndBase,
OnListenerMessage,
}
}

47
tsconfig.json Normal file
View file

@ -0,0 +1,47 @@
{
// Visit https://aka.ms/tsconfig to read more about this file
"compilerOptions": {
// File Layout
"rootDir": "./src",
"outDir": "./dist",
// Environment Settings
// See also https://aka.ms/tsconfig/module
"module": "nodenext",
"target": "esnext",
"types": [],
// For nodejs:
"lib": [
"esnext"
],
"types": [
"node"
],
"typeRoots": [
"./node_modules/@types",
"./src/types"
],
// and npm install -D @types/node
// Other Outputs
"sourceMap": true,
"declaration": true,
"declarationMap": true,
// Stricter Typechecking Options
"noUncheckedIndexedAccess": true,
"exactOptionalPropertyTypes": true,
// Style Options
// "noImplicitReturns": true,
// "noImplicitOverride": true,
// "noUnusedLocals": true,
// "noUnusedParameters": true,
// "noFallthroughCasesInSwitch": true,
// "noPropertyAccessFromIndexSignature": true,
// Recommended Options
"strict": true,
"jsx": "react-jsx",
"verbatimModuleSyntax": true,
"isolatedModules": true,
"noUncheckedSideEffectImports": true,
"moduleDetection": "force",
"skipLibCheck": true,
}
}

473
yarn.lock Normal file
View file

@ -0,0 +1,473 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
"@julusian/midi@^3.0.0-3":
version "3.6.1"
resolved "https://registry.npmjs.org/@julusian/midi/-/midi-3.6.1.tgz"
integrity sha512-sC6tTMAMZsHOQILAv/R0On5tKKhzBQUjdyYWzh9l0UQeNry12CFIyRWK1Mep5xCHWCTUB0w4gxngpciA5PgN/Q==
dependencies:
node-addon-api "^6.1.0"
pkg-prebuilds "^1.0.0"
"@serialport/binding-mock@10.2.2":
version "10.2.2"
resolved "https://registry.npmjs.org/@serialport/binding-mock/-/binding-mock-10.2.2.tgz"
integrity sha512-HAFzGhk9OuFMpuor7aT5G1ChPgn5qSsklTFOTUX72Rl6p0xwcSVsRtG/xaGp6bxpN7fI9D/S8THLBWbBgS6ldw==
dependencies:
"@serialport/bindings-interface" "^1.2.1"
debug "^4.3.3"
"@serialport/bindings-cpp@12.0.1":
version "12.0.1"
resolved "https://registry.npmjs.org/@serialport/bindings-cpp/-/bindings-cpp-12.0.1.tgz"
integrity sha512-r2XOwY2dDvbW7dKqSPIk2gzsr6M6Qpe9+/Ngs94fNaNlcTRCV02PfaoDmRgcubpNVVcLATlxSxPTIDw12dbKOg==
dependencies:
"@serialport/bindings-interface" "1.2.2"
"@serialport/parser-readline" "11.0.0"
debug "4.3.4"
node-addon-api "7.0.0"
node-gyp-build "4.6.0"
"@serialport/bindings-interface@^1.2.1", "@serialport/bindings-interface@1.2.2":
version "1.2.2"
resolved "https://registry.npmjs.org/@serialport/bindings-interface/-/bindings-interface-1.2.2.tgz"
integrity sha512-CJaUd5bLvtM9c5dmO9rPBHPXTa9R2UwpkJ0wdh9JCYcbrPWsKz+ErvR0hBLeo7NPeiFdjFO4sonRljiw4d2XiA==
"@serialport/parser-byte-length@12.0.0":
version "12.0.0"
resolved "https://registry.npmjs.org/@serialport/parser-byte-length/-/parser-byte-length-12.0.0.tgz"
integrity sha512-0ei0txFAj+s6FTiCJFBJ1T2hpKkX8Md0Pu6dqMrYoirjPskDLJRgZGLqoy3/lnU1bkvHpnJO+9oJ3PB9v8rNlg==
"@serialport/parser-cctalk@12.0.0":
version "12.0.0"
resolved "https://registry.npmjs.org/@serialport/parser-cctalk/-/parser-cctalk-12.0.0.tgz"
integrity sha512-0PfLzO9t2X5ufKuBO34DQKLXrCCqS9xz2D0pfuaLNeTkyGUBv426zxoMf3rsMRodDOZNbFblu3Ae84MOQXjnZw==
"@serialport/parser-delimiter@11.0.0":
version "11.0.0"
resolved "https://registry.npmjs.org/@serialport/parser-delimiter/-/parser-delimiter-11.0.0.tgz"
integrity sha512-aZLJhlRTjSmEwllLG7S4J8s8ctRAS0cbvCpO87smLvl3e4BgzbVgF6Z6zaJd3Aji2uSiYgfedCdNc4L6W+1E2g==
"@serialport/parser-delimiter@12.0.0":
version "12.0.0"
resolved "https://registry.npmjs.org/@serialport/parser-delimiter/-/parser-delimiter-12.0.0.tgz"
integrity sha512-gu26tVt5lQoybhorLTPsH2j2LnX3AOP2x/34+DUSTNaUTzu2fBXw+isVjQJpUBFWu6aeQRZw5bJol5X9Gxjblw==
"@serialport/parser-inter-byte-timeout@12.0.0":
version "12.0.0"
resolved "https://registry.npmjs.org/@serialport/parser-inter-byte-timeout/-/parser-inter-byte-timeout-12.0.0.tgz"
integrity sha512-GnCh8K0NAESfhCuXAt+FfBRz1Cf9CzIgXfp7SdMgXwrtuUnCC/yuRTUFWRvuzhYKoAo1TL0hhUo77SFHUH1T/w==
"@serialport/parser-packet-length@12.0.0":
version "12.0.0"
resolved "https://registry.npmjs.org/@serialport/parser-packet-length/-/parser-packet-length-12.0.0.tgz"
integrity sha512-p1hiCRqvGHHLCN/8ZiPUY/G0zrxd7gtZs251n+cfNTn+87rwcdUeu9Dps3Aadx30/sOGGFL6brIRGK4l/t7MuQ==
"@serialport/parser-readline@11.0.0":
version "11.0.0"
resolved "https://registry.npmjs.org/@serialport/parser-readline/-/parser-readline-11.0.0.tgz"
integrity sha512-rRAivhRkT3YO28WjmmG4FQX6L+KMb5/ikhyylRfzWPw0nSXy97+u07peS9CbHqaNvJkMhH1locp2H36aGMOEIA==
dependencies:
"@serialport/parser-delimiter" "11.0.0"
"@serialport/parser-readline@12.0.0":
version "12.0.0"
resolved "https://registry.npmjs.org/@serialport/parser-readline/-/parser-readline-12.0.0.tgz"
integrity sha512-O7cywCWC8PiOMvo/gglEBfAkLjp/SENEML46BXDykfKP5mTPM46XMaX1L0waWU6DXJpBgjaL7+yX6VriVPbN4w==
dependencies:
"@serialport/parser-delimiter" "12.0.0"
"@serialport/parser-ready@12.0.0":
version "12.0.0"
resolved "https://registry.npmjs.org/@serialport/parser-ready/-/parser-ready-12.0.0.tgz"
integrity sha512-ygDwj3O4SDpZlbrRUraoXIoIqb8sM7aMKryGjYTIF0JRnKeB1ys8+wIp0RFMdFbO62YriUDextHB5Um5cKFSWg==
"@serialport/parser-regex@12.0.0":
version "12.0.0"
resolved "https://registry.npmjs.org/@serialport/parser-regex/-/parser-regex-12.0.0.tgz"
integrity sha512-dCAVh4P/pZrLcPv9NJ2mvPRBg64L5jXuiRxIlyxxdZGH4WubwXVXY/kBTihQmiAMPxbT3yshSX8f2+feqWsxqA==
"@serialport/parser-slip-encoder@12.0.0":
version "12.0.0"
resolved "https://registry.npmjs.org/@serialport/parser-slip-encoder/-/parser-slip-encoder-12.0.0.tgz"
integrity sha512-0APxDGR9YvJXTRfY+uRGhzOhTpU5akSH183RUcwzN7QXh8/1jwFsFLCu0grmAUfi+fItCkR+Xr1TcNJLR13VNA==
"@serialport/parser-spacepacket@12.0.0":
version "12.0.0"
resolved "https://registry.npmjs.org/@serialport/parser-spacepacket/-/parser-spacepacket-12.0.0.tgz"
integrity sha512-dozONxhPC/78pntuxpz/NOtVps8qIc/UZzdc/LuPvVsqCoJXiRxOg6ZtCP/W58iibJDKPZPAWPGYeZt9DJxI+Q==
"@serialport/stream@12.0.0":
version "12.0.0"
resolved "https://registry.npmjs.org/@serialport/stream/-/stream-12.0.0.tgz"
integrity sha512-9On64rhzuqKdOQyiYLYv2lQOh3TZU/D3+IWCR5gk0alPel2nwpp4YwDEGiUBfrQZEdQ6xww0PWkzqth4wqwX3Q==
dependencies:
"@serialport/bindings-interface" "1.2.2"
debug "4.3.4"
"@types/node@^25.0.10":
version "25.0.10"
resolved "https://registry.npmjs.org/@types/node/-/node-25.0.10.tgz"
integrity sha512-zWW5KPngR/yvakJgGOmZ5vTBemDoSqF3AcV/LrO5u5wTWyEAVVh+IT39G4gtyAkh3CtTZs8aX/yRM82OfzHJRg==
dependencies:
undici-types "~7.16.0"
ansi-regex@^5.0.1:
version "5.0.1"
resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz"
integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==
ansi-styles@^4.0.0:
version "4.3.0"
resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz"
integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==
dependencies:
color-convert "^2.0.1"
binpack@~0:
version "0.1.0"
resolved "https://registry.npmjs.org/binpack/-/binpack-0.1.0.tgz"
integrity sha512-KcSrsGiIKgklTWweVb9XnZPWO1/rGSsK3fwR7VnbDPbLKPlkvSKd/ZrJ1W712r6HzH5u0fa/AZCftATO09x8Aw==
cliui@^8.0.1:
version "8.0.1"
resolved "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz"
integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==
dependencies:
string-width "^4.2.0"
strip-ansi "^6.0.1"
wrap-ansi "^7.0.0"
color-convert@^2.0.1:
version "2.0.1"
resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz"
integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==
dependencies:
color-name "~1.1.4"
color-name@~1.1.4:
version "1.1.4"
resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz"
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
cross-spawn@^7.0.6:
version "7.0.6"
resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz"
integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==
dependencies:
path-key "^3.1.0"
shebang-command "^2.0.0"
which "^2.0.1"
debug@^4.3.3, debug@4.3.4:
version "4.3.4"
resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz"
integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
dependencies:
ms "2.1.2"
duplexer@~0.1.1:
version "0.1.2"
resolved "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz"
integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==
easymidi@^3.1.0:
version "3.1.0"
resolved "https://registry.npmjs.org/easymidi/-/easymidi-3.1.0.tgz"
integrity sha512-bxEwfPysM1L+SO/qwHaYu9dvTxw2QHFjGV9EMzqGQJbhEP2MupKpg6eJMkj+uoXN0Ep1JhVPLbNLPmt3UkZRTw==
dependencies:
"@julusian/midi" "^3.0.0-3"
emoji-regex@^8.0.0:
version "8.0.0"
resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz"
integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==
escalade@^3.1.1:
version "3.2.0"
resolved "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz"
integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==
event-stream@=3.3.4:
version "3.3.4"
resolved "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz"
integrity sha512-QHpkERcGsR0T7Qm3HNJSyXKEEj8AHNxkY3PK8TS2KJvQ7NiSHe3DDpwVKKtoYprL/AreyzFBeIkBIWChAqn60g==
dependencies:
duplexer "~0.1.1"
from "~0"
map-stream "~0.1.0"
pause-stream "0.0.11"
split "0.3"
stream-combiner "~0.0.4"
through "~2.3.1"
from@~0:
version "0.1.7"
resolved "https://registry.npmjs.org/from/-/from-0.1.7.tgz"
integrity sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==
get-caller-file@^2.0.5:
version "2.0.5"
resolved "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz"
integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
is-fullwidth-code-point@^3.0.0:
version "3.0.0"
resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz"
integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==
isexe@^2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz"
integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==
long@4.0.0:
version "4.0.0"
resolved "https://registry.npmjs.org/long/-/long-4.0.0.tgz"
integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==
map-stream@~0.1.0:
version "0.1.0"
resolved "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz"
integrity sha512-CkYQrPYZfWnu/DAmVCpTSX/xHpKZ80eKh2lAkyA6AJTef6bW+6JpbQZN5rofum7da+SyN1bi5ctTm+lTfcCW3g==
ms@2.1.2:
version "2.1.2"
resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz"
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
node-addon-api@^6.1.0:
version "6.1.0"
resolved "https://registry.npmjs.org/node-addon-api/-/node-addon-api-6.1.0.tgz"
integrity sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==
node-addon-api@7.0.0:
version "7.0.0"
resolved "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.0.0.tgz"
integrity sha512-vgbBJTS4m5/KkE16t5Ly0WW9hz46swAstv0hYYwMtbG7AznRhNyfLRe8HZAiWIpcHzoO7HxhLuBQj9rJ/Ho0ZA==
node-cleanup@^2.1.2:
version "2.1.2"
resolved "https://registry.npmjs.org/node-cleanup/-/node-cleanup-2.1.2.tgz"
integrity sha512-qN8v/s2PAJwGUtr1/hYTpNKlD6Y9rc4p8KSmJXyGdYGZsDGKXrGThikLFP9OCHFeLeEpQzPwiAtdIvBLqm//Hw==
node-gyp-build@4.6.0:
version "4.6.0"
resolved "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.6.0.tgz"
integrity sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==
osc-js@^2.4.1:
version "2.4.1"
resolved "https://registry.npmjs.org/osc-js/-/osc-js-2.4.1.tgz"
integrity sha512-QlSeRKJclL47FNvO1MUCAAp9frmCF9zcYbnf6R9HpcklAst8ZyX3ISsk1v/Vghr/5GmXn0bhVjFXF9h+hfnl4Q==
dependencies:
ws "^8.16.0"
osc-min@^1.1.2:
version "1.1.2"
resolved "https://registry.npmjs.org/osc-min/-/osc-min-1.1.2.tgz"
integrity sha512-8DbiO8ME85R75stgNVCZtHxB9MNBBNcyy+isNBXrsFeinXGjwNAauvKVmGlfRas5VJWC/mhzIx7spR2gFvWxvg==
dependencies:
binpack "~0"
osc@^2.4.5:
version "2.4.5"
resolved "https://registry.npmjs.org/osc/-/osc-2.4.5.tgz"
integrity sha512-Nc4/qcl+vA/CMxiKS1xrYgzjfnyB3W94gZnrkn3eTzihlndbEml6+wj1YQNKBI4r+qrw3obCcEoU7SVH/OxpxA==
dependencies:
long "4.0.0"
slip "1.0.2"
wolfy87-eventemitter "5.2.9"
ws "8.18.0"
optionalDependencies:
serialport "12.0.0"
path-key@^3.1.0:
version "3.1.1"
resolved "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz"
integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==
pause-stream@0.0.11:
version "0.0.11"
resolved "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz"
integrity sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==
dependencies:
through "~2.3"
pkg-prebuilds@^1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/pkg-prebuilds/-/pkg-prebuilds-1.0.0.tgz"
integrity sha512-D9wlkXZCmjxj2kBHTw3fGSyjoahr33breGBoJcoezpi7ouYS59DJVOHMZ+dgqacSrZiJo4qtkXxLQTE+BqXJmQ==
dependencies:
yargs "^17.7.2"
ps-tree@^1.2.0:
version "1.2.0"
resolved "https://registry.npmjs.org/ps-tree/-/ps-tree-1.2.0.tgz"
integrity sha512-0VnamPPYHl4uaU/nSFeZZpR21QAWRz+sRv4iW9+v/GS/J5U5iZB5BNN6J0RMoOvdx2gWM2+ZFMIm58q24e4UYA==
dependencies:
event-stream "=3.3.4"
require-directory@^2.1.1:
version "2.1.1"
resolved "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz"
integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==
serialport@12.0.0:
version "12.0.0"
resolved "https://registry.npmjs.org/serialport/-/serialport-12.0.0.tgz"
integrity sha512-AmH3D9hHPFmnF/oq/rvigfiAouAKyK/TjnrkwZRYSFZxNggJxwvbAbfYrLeuvq7ktUdhuHdVdSjj852Z55R+uA==
dependencies:
"@serialport/binding-mock" "10.2.2"
"@serialport/bindings-cpp" "12.0.1"
"@serialport/parser-byte-length" "12.0.0"
"@serialport/parser-cctalk" "12.0.0"
"@serialport/parser-delimiter" "12.0.0"
"@serialport/parser-inter-byte-timeout" "12.0.0"
"@serialport/parser-packet-length" "12.0.0"
"@serialport/parser-readline" "12.0.0"
"@serialport/parser-ready" "12.0.0"
"@serialport/parser-regex" "12.0.0"
"@serialport/parser-slip-encoder" "12.0.0"
"@serialport/parser-spacepacket" "12.0.0"
"@serialport/stream" "12.0.0"
debug "4.3.4"
shebang-command@^2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz"
integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==
dependencies:
shebang-regex "^3.0.0"
shebang-regex@^3.0.0:
version "3.0.0"
resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz"
integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
slip@1.0.2:
version "1.0.2"
resolved "https://registry.npmjs.org/slip/-/slip-1.0.2.tgz"
integrity sha512-XrcHe3NAcyD3wO+O4I13RcS4/3AF+S9RvGNj9JhJeS02HyImwD2E3QWLrmn9hBfL+fB6yapagwxRkeyYzhk98g==
split@0.3:
version "0.3.3"
resolved "https://registry.npmjs.org/split/-/split-0.3.3.tgz"
integrity sha512-wD2AeVmxXRBoX44wAycgjVpMhvbwdI2aZjCkvfNcH1YqHQvJVa1duWc73OyVGJUc05fhFaTZeQ/PYsrmyH0JVA==
dependencies:
through "2"
stream-combiner@~0.0.4:
version "0.0.4"
resolved "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz"
integrity sha512-rT00SPnTVyRsaSz5zgSPma/aHSOic5U1prhYdRy5HS2kTZviFpmDgzilbtsJsxiroqACmayynDN/9VzIbX5DOw==
dependencies:
duplexer "~0.1.1"
string-argv@^0.3.2:
version "0.3.2"
resolved "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz"
integrity sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==
string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
version "4.2.3"
resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
dependencies:
emoji-regex "^8.0.0"
is-fullwidth-code-point "^3.0.0"
strip-ansi "^6.0.1"
strip-ansi@^6.0.0, strip-ansi@^6.0.1:
version "6.0.1"
resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz"
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
dependencies:
ansi-regex "^5.0.1"
through@~2.3, through@~2.3.1, through@2:
version "2.3.8"
resolved "https://registry.npmjs.org/through/-/through-2.3.8.tgz"
integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==
ts-osc@^0.3.2:
version "0.3.2"
resolved "https://registry.npmjs.org/ts-osc/-/ts-osc-0.3.2.tgz"
integrity sha512-ph+RVCILqDd28g8S/njCFaHvTWVOWU9VYJ1Z1+q/1ZobK5iE3sJPoXfvuy3Ft7nrE2leqfgRLe2cjm0qSQUhsQ==
dependencies:
osc-min "^1.1.2"
tsc-watch@^7.2.0:
version "7.2.0"
resolved "https://registry.npmjs.org/tsc-watch/-/tsc-watch-7.2.0.tgz"
integrity sha512-4gRFawQD1cVSaILvG7wl2x6NtteKbS2dGBMbL7Q6n1ldLIOKXCJUoEwUXdGuee4dp+zcnA6tukBBLz1lZrNI9w==
dependencies:
cross-spawn "^7.0.6"
node-cleanup "^2.1.2"
ps-tree "^1.2.0"
string-argv "^0.3.2"
typescript@*, typescript@^5.9.3:
version "5.9.3"
resolved "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz"
integrity sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==
undici-types@~7.16.0:
version "7.16.0"
resolved "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz"
integrity sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==
which@^2.0.1:
version "2.0.2"
resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz"
integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==
dependencies:
isexe "^2.0.0"
wolfy87-eventemitter@5.2.9:
version "5.2.9"
resolved "https://registry.npmjs.org/wolfy87-eventemitter/-/wolfy87-eventemitter-5.2.9.tgz"
integrity sha512-P+6vtWyuDw+MB01X7UeF8TaHBvbCovf4HPEMF/SV7BdDc1SMTiBy13SRD71lQh4ExFTG1d/WNzDGDCyOKSMblw==
wrap-ansi@^7.0.0:
version "7.0.0"
resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz"
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
dependencies:
ansi-styles "^4.0.0"
string-width "^4.1.0"
strip-ansi "^6.0.0"
ws@^8.16.0:
version "8.19.0"
resolved "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz"
integrity sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==
ws@8.18.0:
version "8.18.0"
resolved "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz"
integrity sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==
y18n@^5.0.5:
version "5.0.8"
resolved "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz"
integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==
yargs-parser@^21.1.1:
version "21.1.1"
resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz"
integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==
yargs@^17.7.2:
version "17.7.2"
resolved "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz"
integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==
dependencies:
cliui "^8.0.1"
escalade "^3.1.1"
get-caller-file "^2.0.5"
require-directory "^2.1.1"
string-width "^4.2.3"
y18n "^5.0.5"
yargs-parser "^21.1.1"