diff --git a/package.json b/package.json index d0f7837..0ef424e 100644 --- a/package.json +++ b/package.json @@ -47,6 +47,7 @@ "dependencies": { "@electron-forge/maker-appx": "^7.9.0", "@homebridge/dbus-native": "^0.7.2", + "active-win": "^9.0.0", "auto-launch": "^5.0.6", "bufferutil": "^4.0.9", "discord-rpc": "^4.0.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9c7ff44..8f5c0f3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -14,6 +14,9 @@ importers: '@homebridge/dbus-native': specifier: ^0.7.2 version: 0.7.2 + active-win: + specifier: ^9.0.0 + version: 9.0.0(encoding@0.1.13) auto-launch: specifier: ^5.0.6 version: 5.0.6 @@ -523,6 +526,10 @@ packages: resolution: {integrity: sha512-XvJRx+2KR3YXyYtPUUy+qd9i7p+GO9Ko6VIIpWlBrpWwXDv8WLFeHTxz35CfQFUiBMLXlGHhGzys7lqit9gWag==} engines: {node: '>=18'} + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + '@jridgewell/gen-mapping@0.3.13': resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} @@ -560,6 +567,10 @@ packages: resolution: {integrity: sha512-9QOtNffcOF/c1seMCDnjckb3R9WHcG34tky+FHpNKKCW0wc/scYLwMtO+ptyGUfMW0/b/n4qRiALlaFHc9Oj7Q==} engines: {node: '>= 10.0.0'} + '@mapbox/node-pre-gyp@1.0.11': + resolution: {integrity: sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==} + hasBin: true + '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -572,10 +583,18 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} + '@npmcli/agent@2.2.2': + resolution: {integrity: sha512-OrcNPXdpSl9UX7qPVRWbmWMCSXrcDa2M9DvrbOTj7ao1S4PlqVFYv9/yLKMkrJKZ/V5A/kDBC690or307i26Og==} + engines: {node: ^16.14.0 || >=18.0.0} + '@npmcli/fs@2.1.2': resolution: {integrity: sha512-yOJKRvohFOaLqipNtwYB9WugyZKhC/DZC4VYPmpaCzDBrA8YpK3qHZ8/HGscMnE4GqbkLNuVcCnxkeQEdGt6LQ==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + '@npmcli/fs@3.1.1': + resolution: {integrity: sha512-q9CRWjpHCMIh5sVyefoD1cA7PkvILqCZsnSOEUUivORLjxCO/Irmue2DprETiNgEqktDBZaM1Bi+jrarx1XdCg==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + '@npmcli/move-file@2.0.1': resolution: {integrity: sha512-mJd2Z5TjYWq/ttPLLGqArdtnC74J6bOzg4rMDnN+p1xTacZ2yPRCk2y0oSWQtygLR9YVQXgOcONrwtnk3JupxQ==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} @@ -645,6 +664,10 @@ packages: '@octokit/types@6.41.0': resolution: {integrity: sha512-eJ2jbzjdijiL3B4PrSQaSjuF2sPEQPVCPzBvTHJD9Nz+9dw2SGH4K4xeQJ77YfTq5bRQ+bD8wT11JbeDPmxmGg==} + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + '@rollup/rollup-android-arm-eabi@4.52.2': resolution: {integrity: sha512-o3pcKzJgSGt4d74lSZ+OCnHwkKBeAbFDmbEm5gg70eA8VkyCuC/zV9TwBnmw6VjDlRdF4Pshfb+WE9E6XY1PoQ==} cpu: [arm] @@ -903,6 +926,7 @@ packages: '@ungap/structured-clone@1.3.0': resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} + deprecated: Potential CWE-502 - Update to 1.3.1 or higher '@vscode/sudo-prompt@9.3.1': resolution: {integrity: sha512-9ORTwwS74VaTn38tNbQhsA5U44zkJfcb0BdTSyyG6frP4e8KMtHuTXYmwefe5dpL8XB1aGSIVTaLjD3BbWb5iA==} @@ -915,6 +939,10 @@ packages: abbrev@1.1.1: resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} + abbrev@2.0.0: + resolution: {integrity: sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + acorn-jsx@5.3.2: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: @@ -925,10 +953,19 @@ packages: engines: {node: '>=0.4.0'} hasBin: true + active-win@9.0.0: + resolution: {integrity: sha512-aiDwWcottgi/DO1/XWnXPHpuTh9qtMxzLUzD9nZj66Fub8SPNGvBLnEdaQsx44O9p8TEZG9d5NNAXGxzbes8CA==} + engines: {node: '>=18.18'} + deprecated: 'Renamed to get-windows: https://www.npmjs.com/package/get-windows' + agent-base@6.0.2: resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} engines: {node: '>= 6.0.0'} + agent-base@7.1.4: + resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} + engines: {node: '>= 14'} + agentkeepalive@4.6.0: resolution: {integrity: sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==} engines: {node: '>= 8.0.0'} @@ -994,6 +1031,14 @@ packages: applescript@1.0.0: resolution: {integrity: sha512-yvtNHdWvtbYEiIazXAdp/NY+BBb65/DAseqlNiJQjOx9DynuzOYDbVLBJvuc0ve0VL9x6B3OHF6eH52y9hCBtQ==} + aproba@2.1.0: + resolution: {integrity: sha512-tLIEcj5GuR2RSTnxNKdkK0dJ/GrC7P38sUkiDmDuHfsHmbagTFAxDVIBltoklXEVIQ/f14IL8IMJ5pn9Hez1Ew==} + + are-we-there-yet@2.0.0: + resolution: {integrity: sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==} + engines: {node: '>=10'} + deprecated: This package is no longer supported. + argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} @@ -1076,9 +1121,6 @@ packages: brace-expansion@1.1.12: resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} - brace-expansion@2.0.2: - resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==} - brace-expansion@2.1.0: resolution: {integrity: sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==} @@ -1103,6 +1145,10 @@ packages: resolution: {integrity: sha512-/+Emcj9DAXxX4cwlLmRI9c166RuL3w30zp4R7Joiv2cQTtTtA+jeuCAjH3ZlGnYS3tKENSrKhAzVVP9GVyzeYQ==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + cacache@18.0.4: + resolution: {integrity: sha512-B+L5iIa9mgcjLbliir2th36yEwPftrzteHYujzsx3dFP/31GCHcIeS8f5MGd80odLOjaOvSpU3EEAmRQptkxLQ==} + engines: {node: ^16.14.0 || >=18.0.0} + cacheable-lookup@5.0.4: resolution: {integrity: sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==} engines: {node: '>=10.6.0'} @@ -1204,6 +1250,10 @@ packages: color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + color-support@1.1.3: + resolution: {integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==} + hasBin: true + colorette@2.0.20: resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} @@ -1233,6 +1283,9 @@ packages: resolution: {integrity: sha512-L6BuueHTRuJHQvQVc6YXYZRtN5vJUtOdCTLn0tRYYV5azfbAFcPghB5zEE40mVrV6w7slMTqUfkDomutIK14fw==} engines: {node: '>=20'} + console-control-strings@1.1.0: + resolution: {integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==} + cross-dirname@0.1.0: resolution: {integrity: sha512-+R08/oI0nl3vfPcqftZRpytksBXDzOUveBq/NBVx0sUp1axwzPQrKinNx5yd5sxPu8j1wIy8AfnVQ+5eFdha6Q==} @@ -1311,6 +1364,9 @@ packages: resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} engines: {node: '>= 0.4'} + delegates@1.0.0: + resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==} + deprecation@2.3.1: resolution: {integrity: sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==} @@ -1624,6 +1680,10 @@ packages: resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} engines: {node: '>= 0.4'} + foreground-child@3.3.1: + resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} + engines: {node: '>=14'} + from@0.1.7: resolution: {integrity: sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==} @@ -1651,6 +1711,10 @@ packages: resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} engines: {node: '>= 8'} + fs-minipass@3.0.3: + resolution: {integrity: sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + fs.realpath@1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} @@ -1677,6 +1741,11 @@ packages: resolution: {integrity: sha512-w4n9cPWyP7aHxKxYHFQMegj7WIAsL/YX/C4Bs5Rr8s1H9M1rNtRWRsw+ovYMkXDQ5S4ZbYHsHAPmevPjPgw44w==} deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. + gauge@3.0.2: + resolution: {integrity: sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==} + engines: {node: '>=10'} + deprecated: This package is no longer supported. + get-caller-file@2.0.5: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} @@ -1720,6 +1789,11 @@ packages: resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} engines: {node: '>=10.13.0'} + glob@10.5.0: + resolution: {integrity: sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==} + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me + hasBin: true + glob@7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me @@ -1790,6 +1864,9 @@ packages: resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} engines: {node: '>= 0.4'} + has-unicode@2.0.1: + resolution: {integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==} + hasown@2.0.2: resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} @@ -1809,6 +1886,10 @@ packages: resolution: {integrity: sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==} engines: {node: '>= 6'} + http-proxy-agent@7.0.2: + resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} + engines: {node: '>= 14'} + http2-wrapper@1.0.3: resolution: {integrity: sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==} engines: {node: '>=10.19.0'} @@ -1817,6 +1898,10 @@ packages: resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} engines: {node: '>= 6'} + https-proxy-agent@7.0.6: + resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} + engines: {node: '>= 14'} + humanize-ms@1.2.1: resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==} @@ -2024,6 +2109,13 @@ packages: isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + isexe@3.1.5: + resolution: {integrity: sha512-6B3tLtFqtQS4ekarvLVMZ+X+VlvQekbe4taUkf/rhVO3d/h0M2rfARm/pXLcPEsjjMsFgrFgSrhQIxcSVrBz8w==} + engines: {node: '>=18'} + + jackspeak@3.4.3: + resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + javascript-natural-sort@0.7.1: resolution: {integrity: sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw==} @@ -2126,14 +2218,25 @@ packages: resolution: {integrity: sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==} engines: {node: '>=8'} + lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + lru-cache@7.18.3: resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==} engines: {node: '>=12'} + make-dir@3.1.0: + resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} + engines: {node: '>=8'} + make-fetch-happen@10.2.1: resolution: {integrity: sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + make-fetch-happen@13.0.1: + resolution: {integrity: sha512-cKTUFc/rbKUd/9meOvgrpJ2WrNzymt6jfRDdwg5UCnVzv9dTpEj9JS5m3wtziXVCjluIXyL8pcaukYqezIzZQA==} + engines: {node: ^16.14.0 || >=18.0.0} + map-age-cleaner@0.1.3: resolution: {integrity: sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==} engines: {node: '>=6'} @@ -2207,10 +2310,18 @@ packages: resolution: {integrity: sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==} engines: {node: '>= 8'} + minipass-collect@2.0.1: + resolution: {integrity: sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==} + engines: {node: '>=16 || 14 >=14.17'} + minipass-fetch@2.1.2: resolution: {integrity: sha512-LT49Zi2/WMROHYoqGgdlQIZh8mLPZmOrN2NdJjMXxYe4nkN6FUyuPuOAOedNJDrx0IRGg9+4guZewtp8hE6TxA==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + minipass-fetch@3.0.5: + resolution: {integrity: sha512-2N8elDQAtSnFV0Dk7gt15KHsS0Fyz6CbYZ360h0WTYV1Ty46li3rAXVOQj1THMNLdmrD9Vt5pBPtWtVkpwGBqg==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + minipass-flush@1.0.7: resolution: {integrity: sha512-TbqTz9cUwWyHS2Dy89P3ocAGUGxKjjLuR9z8w4WUTGAVgEj17/4nhgo2Du56i0Fm3Pm30g4iA8Lcqctc76jCzA==} engines: {node: '>= 8'} @@ -2231,6 +2342,10 @@ packages: resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==} engines: {node: '>=8'} + minipass@7.1.3: + resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==} + engines: {node: '>=16 || 14 >=14.17'} + minizlib@2.1.2: resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} engines: {node: '>= 8'} @@ -2287,6 +2402,10 @@ packages: node-addon-api@1.7.2: resolution: {integrity: sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==} + node-addon-api@8.9.0: + resolution: {integrity: sha512-ekZMeaaIzSQTSpr7X2X3iJM7lTzgnx8ahAG9pJfT/7+14mlEM8ZYQ9cgCDvSSRbReFK0oHli3WrZdCiRsgAT9Q==} + engines: {node: ^18 || ^20 || >= 21} + node-api-version@0.2.1: resolution: {integrity: sha512-2xP/IGGMmmSQpI1+O/k72jF/ykvZ89JeuKX3TLJAYPDVLUalrshrLHkeVcCCZqG/eEa635cr8IBYzgnDvM2O8Q==} @@ -2303,11 +2422,26 @@ packages: resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} hasBin: true + node-gyp@10.3.1: + resolution: {integrity: sha512-Pp3nFHBThHzVtNY7U6JfPjvT/DTE8+o/4xKsLQtBoU+j2HLsGlhcfzflAoUreaJbNmYnX+LlLi0qjV8kpyO6xQ==} + engines: {node: ^16.14.0 || >=18.0.0} + hasBin: true + + nopt@5.0.0: + resolution: {integrity: sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==} + engines: {node: '>=6'} + hasBin: true + nopt@6.0.0: resolution: {integrity: sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} hasBin: true + nopt@7.2.1: + resolution: {integrity: sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + hasBin: true + normalize-package-data@2.5.0: resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} @@ -2319,6 +2453,14 @@ packages: resolution: {integrity: sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==} engines: {node: '>=4'} + npmlog@5.0.1: + resolution: {integrity: sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==} + deprecated: This package is no longer supported. + + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + object-inspect@1.13.4: resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} engines: {node: '>= 0.4'} @@ -2410,6 +2552,9 @@ packages: resolution: {integrity: sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==} engines: {node: '>=4'} + package-json-from-dist@1.0.1: + resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + parent-module@1.0.1: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} @@ -2445,6 +2590,10 @@ packages: path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} + path-type@2.0.0: resolution: {integrity: sha512-dUnb5dXUf+kzhC/W/F4e5/SkluXIFf5VUHolW1Eg1irn1hGWjPGdsRcvYJ1nD6lhk8Ir7VM0bHJKsYTx8Jx9OQ==} engines: {node: '>=4'} @@ -2504,6 +2653,10 @@ packages: resolution: {integrity: sha512-Kcmo2FhfDTXdcbfDH76N7uBYHINxc/8GW7UAVuVP9I+Va3uHSerrnKV6dLooga/gh7GlgzuCCr/eoldnL1muGw==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + proc-log@4.2.0: + resolution: {integrity: sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + progress@2.0.3: resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} engines: {node: '>=0.4.0'} @@ -2687,6 +2840,9 @@ packages: resolution: {integrity: sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==} engines: {node: '>=10'} + set-blocking@2.0.0: + resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} + set-function-length@1.2.2: resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} engines: {node: '>= 0.4'} @@ -2754,6 +2910,10 @@ packages: resolution: {integrity: sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==} engines: {node: '>= 10'} + socks-proxy-agent@8.0.5: + resolution: {integrity: sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==} + engines: {node: '>= 14'} + socks@2.8.7: resolution: {integrity: sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==} engines: {node: '>= 10.0.0', npm: '>= 3.0.0'} @@ -2787,6 +2947,10 @@ packages: sprintf-js@1.1.3: resolution: {integrity: sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==} + ssri@10.0.6: + resolution: {integrity: sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + ssri@9.0.1: resolution: {integrity: sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} @@ -2998,10 +3162,18 @@ packages: resolution: {integrity: sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + unique-filename@3.0.0: + resolution: {integrity: sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + unique-slug@3.0.0: resolution: {integrity: sha512-8EyMynh679x/0gqE9fT9oilG+qEt+ibFyqjuVTsZn1+CMxH+XLlpvr2UZx4nVcCwTpx81nICr2JQFkM+HPLq4w==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + unique-slug@4.0.0: + resolution: {integrity: sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + universal-user-agent@6.0.1: resolution: {integrity: sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==} @@ -3105,6 +3277,14 @@ packages: engines: {node: '>= 8'} hasBin: true + which@4.0.0: + resolution: {integrity: sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==} + engines: {node: ^16.13.0 || >=18.0.0} + hasBin: true + + wide-align@1.1.5: + resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==} + winreg@1.2.4: resolution: {integrity: sha512-IHpzORub7kYlb8A43Iig3reOvlcBJGX9gZ0WycHhghHtA65X0LYnMRuJs+aH1abVnMJztQkvQNlltnbPi5aGIA==} @@ -3857,6 +4037,16 @@ snapshots: dependencies: mute-stream: 1.0.0 + '@isaacs/cliui@8.0.2': + dependencies: + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.1.2 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 + optional: true + '@jridgewell/gen-mapping@0.3.13': dependencies: '@jridgewell/sourcemap-codec': 1.5.5 @@ -3907,6 +4097,22 @@ snapshots: - supports-color optional: true + '@mapbox/node-pre-gyp@1.0.11(encoding@0.1.13)': + dependencies: + detect-libc: 2.1.1 + https-proxy-agent: 5.0.1 + make-dir: 3.1.0 + node-fetch: 2.7.0(encoding@0.1.13) + nopt: 5.0.0 + npmlog: 5.0.1 + rimraf: 3.0.2 + semver: 7.7.2 + tar: 6.2.1 + transitivePeerDependencies: + - encoding + - supports-color + optional: true + '@nodelib/fs.scandir@2.1.5': dependencies: '@nodelib/fs.stat': 2.0.5 @@ -3919,11 +4125,27 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.19.1 + '@npmcli/agent@2.2.2': + dependencies: + agent-base: 7.1.4 + http-proxy-agent: 7.0.2 + https-proxy-agent: 7.0.6 + lru-cache: 10.4.3 + socks-proxy-agent: 8.0.5 + transitivePeerDependencies: + - supports-color + optional: true + '@npmcli/fs@2.1.2': dependencies: '@gar/promisify': 1.1.3 semver: 7.7.2 + '@npmcli/fs@3.1.1': + dependencies: + semver: 7.7.2 + optional: true + '@npmcli/move-file@2.0.1': dependencies: mkdirp: 1.0.4 @@ -4005,6 +4227,9 @@ snapshots: dependencies: '@octokit/openapi-types': 12.11.0 + '@pkgjs/parseargs@0.11.0': + optional: true + '@rollup/rollup-android-arm-eabi@4.52.2': optional: true @@ -4248,18 +4473,33 @@ snapshots: abbrev@1.1.1: {} + abbrev@2.0.0: + optional: true + acorn-jsx@5.3.2(acorn@8.15.0): dependencies: acorn: 8.15.0 acorn@8.15.0: {} + active-win@9.0.0(encoding@0.1.13): + optionalDependencies: + '@mapbox/node-pre-gyp': 1.0.11(encoding@0.1.13) + node-addon-api: 8.9.0 + node-gyp: 10.3.1 + transitivePeerDependencies: + - encoding + - supports-color + agent-base@6.0.2: dependencies: debug: 4.4.3 transitivePeerDependencies: - supports-color + agent-base@7.1.4: + optional: true + agentkeepalive@4.6.0: dependencies: humanize-ms: 1.2.1 @@ -4321,6 +4561,15 @@ snapshots: applescript@1.0.0: {} + aproba@2.1.0: + optional: true + + are-we-there-yet@2.0.0: + dependencies: + delegates: 1.0.0 + readable-stream: 3.6.2 + optional: true + argparse@2.0.1: {} array-buffer-byte-length@1.0.2: @@ -4427,10 +4676,6 @@ snapshots: balanced-match: 1.0.2 concat-map: 0.0.1 - brace-expansion@2.0.2: - dependencies: - balanced-match: 1.0.2 - brace-expansion@2.1.0: dependencies: balanced-match: 1.0.2 @@ -4475,6 +4720,22 @@ snapshots: transitivePeerDependencies: - bluebird + cacache@18.0.4: + dependencies: + '@npmcli/fs': 3.1.1 + fs-minipass: 3.0.3 + glob: 10.5.0 + lru-cache: 10.4.3 + minipass: 7.1.3 + minipass-collect: 2.0.1 + minipass-flush: 1.0.7 + minipass-pipeline: 1.2.4 + p-map: 4.0.0 + ssri: 10.0.6 + tar: 6.2.1 + unique-filename: 3.0.0 + optional: true + cacheable-lookup@5.0.4: {} cacheable-request@7.0.4: @@ -4584,6 +4845,9 @@ snapshots: color-name@1.1.4: {} + color-support@1.1.3: + optional: true + colorette@2.0.20: {} commander@11.1.0: {} @@ -4611,6 +4875,9 @@ snapshots: semver: 7.7.2 uint8array-extras: 1.5.0 + console-control-strings@1.1.0: + optional: true + cross-dirname@0.1.0: {} cross-spawn@6.0.6: @@ -4687,6 +4954,9 @@ snapshots: has-property-descriptors: 1.0.2 object-keys: 1.1.1 + delegates@1.0.0: + optional: true + deprecation@2.3.1: {} detect-libc@2.1.1: {} @@ -5192,6 +5462,12 @@ snapshots: dependencies: is-callable: 1.2.7 + foreground-child@3.3.1: + dependencies: + cross-spawn: 7.0.6 + signal-exit: 4.1.0 + optional: true + from@0.1.7: {} fs-extra@10.1.0: @@ -5230,6 +5506,11 @@ snapshots: dependencies: minipass: 3.3.6 + fs-minipass@3.0.3: + dependencies: + minipass: 7.1.3 + optional: true + fs.realpath@1.0.0: {} fsevents@2.3.3: @@ -5259,6 +5540,19 @@ snapshots: gar@1.0.4: optional: true + gauge@3.0.2: + dependencies: + aproba: 2.1.0 + color-support: 1.1.3 + console-control-strings: 1.1.0 + has-unicode: 2.0.1 + object-assign: 4.1.1 + signal-exit: 3.0.7 + string-width: 4.2.3 + strip-ansi: 6.0.1 + wide-align: 1.1.5 + optional: true + get-caller-file@2.0.5: {} get-folder-size@2.0.1: @@ -5320,6 +5614,16 @@ snapshots: dependencies: is-glob: 4.0.3 + glob@10.5.0: + dependencies: + foreground-child: 3.3.1 + jackspeak: 3.4.3 + minimatch: 9.0.5 + minipass: 7.1.3 + package-json-from-dist: 1.0.1 + path-scurry: 1.11.1 + optional: true + glob@7.2.3: dependencies: fs.realpath: 1.0.0 @@ -5410,6 +5714,9 @@ snapshots: dependencies: has-symbols: 1.1.0 + has-unicode@2.0.1: + optional: true + hasown@2.0.2: dependencies: function-bind: 1.1.2 @@ -5428,6 +5735,14 @@ snapshots: transitivePeerDependencies: - supports-color + http-proxy-agent@7.0.2: + dependencies: + agent-base: 7.1.4 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + optional: true + http2-wrapper@1.0.3: dependencies: quick-lru: 5.1.1 @@ -5440,6 +5755,14 @@ snapshots: transitivePeerDependencies: - supports-color + https-proxy-agent@7.0.6: + dependencies: + agent-base: 7.1.4 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + optional: true + humanize-ms@1.2.1: dependencies: ms: 2.1.3 @@ -5638,6 +5961,16 @@ snapshots: isexe@2.0.0: {} + isexe@3.1.5: + optional: true + + jackspeak@3.4.3: + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + optional: true + javascript-natural-sort@0.7.1: {} jiti@2.6.0: {} @@ -5739,8 +6072,16 @@ snapshots: lowercase-keys@2.0.0: {} + lru-cache@10.4.3: + optional: true + lru-cache@7.18.3: {} + make-dir@3.1.0: + dependencies: + semver: 6.3.1 + optional: true + make-fetch-happen@10.2.1: dependencies: agentkeepalive: 4.6.0 @@ -5763,6 +6104,24 @@ snapshots: - bluebird - supports-color + make-fetch-happen@13.0.1: + dependencies: + '@npmcli/agent': 2.2.2 + cacache: 18.0.4 + http-cache-semantics: 4.2.0 + is-lambda: 1.0.1 + minipass: 7.1.3 + minipass-fetch: 3.0.5 + minipass-flush: 1.0.7 + minipass-pipeline: 1.2.4 + negotiator: 0.6.4 + proc-log: 4.2.0 + promise-retry: 2.0.1 + ssri: 10.0.6 + transitivePeerDependencies: + - supports-color + optional: true + map-age-cleaner@0.1.3: dependencies: p-defer: 1.0.0 @@ -5816,7 +6175,7 @@ snapshots: minimatch@9.0.5: dependencies: - brace-expansion: 2.0.2 + brace-expansion: 2.1.0 minimist@1.2.8: {} @@ -5824,6 +6183,11 @@ snapshots: dependencies: minipass: 3.3.6 + minipass-collect@2.0.1: + dependencies: + minipass: 7.1.3 + optional: true + minipass-fetch@2.1.2: dependencies: minipass: 3.3.6 @@ -5832,6 +6196,15 @@ snapshots: optionalDependencies: encoding: 0.1.13 + minipass-fetch@3.0.5: + dependencies: + minipass: 7.1.3 + minipass-sized: 1.0.3 + minizlib: 2.1.2 + optionalDependencies: + encoding: 0.1.13 + optional: true + minipass-flush@1.0.7: dependencies: minipass: 3.3.6 @@ -5850,6 +6223,9 @@ snapshots: minipass@5.0.0: {} + minipass@7.1.3: + optional: true + minizlib@2.1.2: dependencies: minipass: 3.3.6 @@ -5892,6 +6268,9 @@ snapshots: node-addon-api@1.7.2: optional: true + node-addon-api@8.9.0: + optional: true + node-api-version@0.2.1: dependencies: semver: 7.7.2 @@ -5904,10 +6283,36 @@ snapshots: node-gyp-build@4.8.4: {} + node-gyp@10.3.1: + dependencies: + env-paths: 2.2.1 + exponential-backoff: 3.1.3 + glob: 10.5.0 + graceful-fs: 4.2.11 + make-fetch-happen: 13.0.1 + nopt: 7.2.1 + proc-log: 4.2.0 + semver: 7.7.2 + tar: 6.2.1 + which: 4.0.0 + transitivePeerDependencies: + - supports-color + optional: true + + nopt@5.0.0: + dependencies: + abbrev: 1.1.1 + optional: true + nopt@6.0.0: dependencies: abbrev: 1.1.1 + nopt@7.2.1: + dependencies: + abbrev: 2.0.0 + optional: true + normalize-package-data@2.5.0: dependencies: hosted-git-info: 2.8.9 @@ -5921,6 +6326,17 @@ snapshots: dependencies: path-key: 2.0.1 + npmlog@5.0.1: + dependencies: + are-we-there-yet: 2.0.0 + console-control-strings: 1.1.0 + gauge: 3.0.2 + set-blocking: 2.0.0 + optional: true + + object-assign@4.1.1: + optional: true + object-inspect@1.13.4: {} object-keys@1.1.1: {} @@ -6026,6 +6442,9 @@ snapshots: p-try@1.0.0: {} + package-json-from-dist@1.0.1: + optional: true + parent-module@1.0.1: dependencies: callsites: 3.1.0 @@ -6050,6 +6469,12 @@ snapshots: path-parse@1.0.7: {} + path-scurry@1.11.1: + dependencies: + lru-cache: 10.4.3 + minipass: 7.1.3 + optional: true + path-type@2.0.0: dependencies: pify: 2.3.0 @@ -6094,6 +6519,9 @@ snapshots: proc-log@2.0.1: {} + proc-log@4.2.0: + optional: true + progress@2.0.3: {} promise-inflight@1.0.1: {} @@ -6309,6 +6737,9 @@ snapshots: type-fest: 0.13.1 optional: true + set-blocking@2.0.0: + optional: true + set-function-length@1.2.2: dependencies: define-data-property: 1.1.4 @@ -6392,6 +6823,15 @@ snapshots: transitivePeerDependencies: - supports-color + socks-proxy-agent@8.0.5: + dependencies: + agent-base: 7.1.4 + debug: 4.4.3 + socks: 2.8.7 + transitivePeerDependencies: + - supports-color + optional: true + socks@2.8.7: dependencies: ip-address: 10.1.0 @@ -6427,6 +6867,11 @@ snapshots: sprintf-js@1.1.3: optional: true + ssri@10.0.6: + dependencies: + minipass: 7.1.3 + optional: true + ssri@9.0.1: dependencies: minipass: 3.3.6 @@ -6663,10 +7108,20 @@ snapshots: dependencies: unique-slug: 3.0.0 + unique-filename@3.0.0: + dependencies: + unique-slug: 4.0.0 + optional: true + unique-slug@3.0.0: dependencies: imurmurhash: 0.1.4 + unique-slug@4.0.0: + dependencies: + imurmurhash: 0.1.4 + optional: true + universal-user-agent@6.0.1: {} universalify@0.1.2: {} @@ -6771,6 +7226,16 @@ snapshots: dependencies: isexe: 2.0.0 + which@4.0.0: + dependencies: + isexe: 3.1.5 + optional: true + + wide-align@1.1.5: + dependencies: + string-width: 4.2.3 + optional: true + winreg@1.2.4: {} word-wrap@1.2.5: {} diff --git a/src/config.d.ts b/src/config.d.ts index d5f0cde..d2b1325 100644 --- a/src/config.d.ts +++ b/src/config.d.ts @@ -5,6 +5,7 @@ declare type DesktopConfig = { spellchecker: boolean; hardwareAcceleration: boolean; discordRpc: boolean; + desktopPresence: boolean; windowState: { x: number; y: number; diff --git a/src/main.ts b/src/main.ts index 911db87..b85796f 100644 --- a/src/main.ts +++ b/src/main.ts @@ -7,6 +7,7 @@ import { autoLaunch } from "./native/autoLaunch"; import { config } from "./native/config"; import { initDiscordRpc } from "./native/discordRpc"; import { initTray } from "./native/tray"; +import { startActivityDetection } from "./native/presenceDetector"; import { BUILD_URL, createMainWindow, mainWindow } from "./native/window"; // Squirrel-specific logic @@ -53,6 +54,7 @@ if (acquiredLock) { initTray(); initDiscordRpc(); + startActivityDetection(); // Windows specific fix for notifications if (process.platform === "win32") { diff --git a/src/native/config.ts b/src/native/config.ts index f7c2d37..9f1403d 100644 --- a/src/native/config.ts +++ b/src/native/config.ts @@ -5,6 +5,7 @@ import Store from "electron-store"; import { destroyDiscordRpc, initDiscordRpc } from "./discordRpc"; import { mainWindow } from "./window"; +import { startActivityDetection, stopActivityDetection } from "./presenceDetector"; const schema = { firstLaunch: { @@ -28,6 +29,9 @@ const schema = { discordRpc: { type: "boolean", } as JSONSchema.Boolean, + desktopPresence: { + type: "boolean", + } as JSONSchema.Boolean, windowState: { type: "object", properties: { @@ -60,6 +64,7 @@ const store = new Store({ spellchecker: true, hardwareAcceleration: true, discordRpc: true, + desktopPresence: true, windowState: { x: 0, y: 0, @@ -83,6 +88,7 @@ class Config { spellchecker: this.spellchecker, hardwareAcceleration: this.hardwareAcceleration, discordRpc: this.discordRpc, + desktopPresence: this.desktopPresence, windowState: this.windowState, }); } @@ -192,6 +198,27 @@ class Config { this.sync(); } + get desktopPresence() { + return (store as never as { get(k: string): boolean }).get( + "desktopPresence", + ); + } + + set desktopPresence(value: boolean) { + if (value) { + startActivityDetection(); + } else { + stopActivityDetection(); + } + + (store as never as { set(k: string, value: boolean): void }).set( + "desktopPresence", + value, + ); + + this.sync(); + } + get windowState() { return ( store as never as { get(k: string): DesktopConfig["windowState"] } diff --git a/src/native/discordRpc.ts b/src/native/discordRpc.ts index 9df475b..92b1eea 100644 --- a/src/native/discordRpc.ts +++ b/src/native/discordRpc.ts @@ -3,7 +3,34 @@ import { Client } from "discord-rpc"; import { config } from "./config"; // internal state -let rpc: Client; +let rpc: Client | undefined; +let currentActivity: Record | null = null; +let detectedActivity: Record | null = null; +let isReady = false; + +function buildRpcActivity(activity: Record | null | undefined) { + return { + ...(activity ?? {}), + largeImageKey: "qr", + largeImageText: "Join Stoat!", + buttons: [ + { + label: "Join Stoat", + url: "https://stoat.chat/", + }, + ], + }; +} + +function applyCurrentActivity(activity: Record | null | undefined = currentActivity) { + if (!rpc || !isReady) { + return; + } + + void rpc.setActivity(buildRpcActivity(activity)).catch((error) => { + console.warn("Discord RPC activity update failed", error); + }); +} export async function initDiscordRpc() { if (!config.discordRpc) return; @@ -14,25 +41,35 @@ export async function initDiscordRpc() { try { rpc = new Client({ transport: "ipc" }); - rpc.on("ready", () => - rpc.setActivity({ - state: "stoat.chat", - details: "Chatting with others", - largeImageKey: "qr", - largeImageText: "Join Stoat!", - buttons: [ - { - label: "Join Stoat", - url: "https://stoat.chat/", - }, - ], - }), - ); + rpc.on("ready", () => { + isReady = true; + if (currentActivity) { + applyCurrentActivity(currentActivity); + } else { + applyCurrentActivity({ + state: "stoat.chat", + details: "Chatting with others", + }); + } + }); - rpc.on("disconnected", reconnect); + rpc.on("disconnected", () => { + isReady = false; + console.warn("Discord RPC disconnected"); + reconnect(); + }); - rpc.login({ clientId: "872068124005007420" }); + rpc.on("error", (error) => { + isReady = false; + console.error("Discord RPC error", error); + }); + + void rpc.login({ clientId: "872068124005007420" }).catch((error) => { + console.error("Discord RPC login failed", error); + reconnect(); + }); } catch (err) { + console.error("Discord RPC setup failed", err); reconnect(); } } @@ -40,5 +77,47 @@ export async function initDiscordRpc() { const reconnect = () => setTimeout(() => initDiscordRpc(), 1e4); export async function destroyDiscordRpc() { + currentActivity = null; + isReady = false; + await rpc?.clearActivity().catch(() => undefined); rpc?.destroy(); + rpc = undefined; +} + +export function setDiscordActivity(activity: Record) { + currentActivity = activity; + console.info("Updating Discord activity", activity); + + if (!rpc || !isReady) { + return; + } + + applyCurrentActivity(activity); +} + +export function clearDiscordActivity() { + currentActivity = null; + console.info("Clearing Discord activity"); + + if (!rpc || !isReady) { + return; + } + + void rpc.clearActivity().catch((error) => { + console.warn("Discord RPC clear failed", error); + }); +} + +export function setDetectedActivity(activity: Record) { + detectedActivity = activity; + console.info("Prepared detected activity for Stoat backend", activity); +} + +export function clearDetectedActivity() { + detectedActivity = null; + console.info("Cleared detected activity"); +} + +export function getDetectedActivity() { + return detectedActivity; } diff --git a/src/native/presenceDetector.ts b/src/native/presenceDetector.ts new file mode 100644 index 0000000..fef85f6 --- /dev/null +++ b/src/native/presenceDetector.ts @@ -0,0 +1,316 @@ +import { powerMonitor } from "electron"; + +import { clearDetectedActivity, setDetectedActivity } from "./discordRpc"; + +const { activeWindowSync } = require("active-win"); + +const POLL_INTERVAL_MS = 5_000; + +let detectionTimer: NodeJS.Timeout | undefined; +let lastKey = ""; +let activityDetectionEnabled = true; +let lastKnownApp = ""; + +type PresenceActivity = { + state: string; + details: string; + timestamps?: { + start: number; + }; +}; + +function normalizeAppName(value: string) { + return value + .replace(/\\/g, "/") + .replace(/\.(exe|app)$/i, "") + .replace(/\.root$/i, "") + .replace(/[-_.]+/g, " ") + .trim(); +} + +function extractExecutableName(value: string) { + const match = value.match(/([^\\/]+)\.(?:exe|app)$/i); + return match?.[1] ?? ""; +} + +function getSteamGameName(processName: string, title: string, ownerPath = "") { + const normalizedOwnerPath = ownerPath.replace(/\\/g, "/").toLowerCase(); + + if (normalizedOwnerPath.includes("/steamapps/common/") || normalizedOwnerPath.includes("/steam/steamapps/common/")) { + const pathParts = ownerPath.replace(/\\/g, "/").split("/").filter(Boolean); + const commonIndex = pathParts.findIndex((part) => part.toLowerCase() === "common"); + + if (commonIndex >= 0 && pathParts[commonIndex + 1]) { + return normalizeAppName(pathParts[commonIndex + 1]); + } + } + + const directName = normalizeAppName(title || processName || ""); + const isSteamClient = ["steam", "steam web helper", "steamwebhelper", "steam client bootstrapper"].includes( + directName.toLowerCase(), + ); + + if (!isSteamClient && /steam/i.test(directName)) { + return directName; + } + + return ""; +} + +function buildActivity(processName: string, title: string, ownerPath = ""): PresenceActivity | null { + const normalizedProcessName = processName.toLowerCase(); + const normalizedTitle = title.toLowerCase(); + const combinedSignal = `${normalizedProcessName} ${normalizedTitle}`; + + const isStoatApp = + normalizedProcessName === "stoat" || + normalizedProcessName === "stoat desktop" || + normalizedProcessName.includes("stoat desktop") || + (normalizedProcessName.includes("stoat") && + (normalizedProcessName.includes("desktop") || normalizedProcessName.includes("app") || normalizedTitle.includes("stoat"))) || + (normalizedProcessName.includes("electron") && normalizedTitle.includes("stoat")); + + if (isStoatApp) { + return { + state: "Chatting", + details: "In Stoat", + timestamps: { start: Date.now() }, + }; + } + + const steamGameName = getSteamGameName(processName, title, ownerPath); + + if (steamGameName) { + return { + state: "Playing", + details: steamGameName, + timestamps: { start: Date.now() }, + }; + } + + if (normalizedProcessName.includes("steam") || normalizedTitle.includes("steam")) { + const steamDisplayName = normalizeAppName(title || processName || ""); + const isSteamClient = ["steam", "steam web helper", "steamwebhelper"].includes( + steamDisplayName.toLowerCase(), + ); + + if (isSteamClient) { + return { + state: "In Steam", + details: "Using Steam", + timestamps: { start: Date.now() }, + }; + } + + return { + state: "Playing", + details: steamDisplayName || "Steam Game", + timestamps: { start: Date.now() }, + }; + } + + if (normalizedProcessName.includes("valorant")) { + return { + state: "Playing", + details: "Valorant", + timestamps: { start: Date.now() }, + }; + } + + if ( + normalizedProcessName.includes("steam") || + normalizedProcessName.includes("steamwebhelper") || + normalizedTitle.includes("steam") + ) { + return { + state: "In Steam", + details: "Using Steam", + timestamps: { start: Date.now() }, + }; + } + + if (normalizedProcessName.includes("league")) { + return { + state: "Playing", + details: "League of Legends", + timestamps: { start: Date.now() }, + }; + } + + if (normalizedProcessName.includes("cs2") || normalizedProcessName.includes("counter-strike")) { + return { + state: "Playing", + details: "Counter-Strike 2", + timestamps: { start: Date.now() }, + }; + } + + if (normalizedProcessName.includes("whatsapp") || normalizedTitle.includes("whatsapp")) { + return { + state: "Chatting", + details: "Using WhatsApp", + timestamps: { start: Date.now() }, + }; + } + + if (normalizedProcessName.includes("discord")) { + return { + state: "Chatting", + details: "Using Discord", + timestamps: { start: Date.now() }, + }; + } + + if (normalizedProcessName.includes("code") || normalizedProcessName.includes("vscode")) { + return { + state: "Developing", + details: "Coding in VS Code", + timestamps: { start: Date.now() }, + }; + } + + if (normalizedProcessName.includes("obs")) { + return { + state: "Streaming", + details: "Broadcasting with OBS", + timestamps: { start: Date.now() }, + }; + } + + if ( + normalizedProcessName.includes("chrome") || + normalizedProcessName.includes("msedge") || + normalizedProcessName.includes("firefox") + ) { + return { + state: "Browsing", + details: title ? `Browsing ${title}` : "Browsing the web", + timestamps: { start: Date.now() }, + }; + } + + if (normalizedTitle.includes("valorant")) { + return { + state: "In-game", + details: "Playing Valorant", + timestamps: { start: Date.now() }, + }; + } + + if ( + normalizedProcessName.includes("explorer") || + normalizedProcessName.includes("shell") || + normalizedProcessName.includes("desktop") || + normalizedTitle.includes("desktop") || + normalizedTitle.includes("program manager") + ) { + return null; + } + + const appName = normalizeAppName(processName || title || "Unknown app"); + return { + state: "Active", + details: `Using ${appName || "an app"}`, + timestamps: { start: Date.now() }, + }; +} + +function getForegroundInfo() { + try { + const activeWindow = activeWindowSync({ screen: true }); + const ownerName = activeWindow?.owner?.name ?? ""; + const ownerPath = activeWindow?.owner?.path ?? ""; + const title = activeWindow?.title ?? ""; + const executableName = extractExecutableName(ownerPath); + const inferredProcessName = normalizeAppName( + executableName || ownerName || title, + ); + const normalizedTitle = title.toLowerCase(); + const titleHint = normalizeAppName(title || ""); + const normalizedTitleHint = titleHint.toLowerCase(); + const normalizedProcessName = inferredProcessName.toLowerCase(); + const shouldUseTitleHint = + Boolean(titleHint) && + (normalizedTitle.includes("stoat") || normalizedTitleHint.includes("stoat")) && + (normalizedProcessName === "electron" || normalizedProcessName === "app" || normalizedProcessName === ""); + + return { + processName: shouldUseTitleHint ? titleHint : inferredProcessName || titleHint || (normalizedTitle.includes("stoat") ? "stoat" : ""), + title, + }; + } catch (error) { + console.warn("Foreground window lookup failed", error); + return { + processName: "", + title: "", + }; + } +} + +async function detectActivity() { + if (!activityDetectionEnabled) { + clearDetectedActivity(); + return; + } + + try { + const { processName, title } = getForegroundInfo(); + const ownerPath = activeWindowSync({ screen: true })?.owner?.path ?? ""; + + if (!processName) { + clearDetectedActivity(); + lastKey = ""; + return; + } + + const activity = buildActivity(processName, title, ownerPath); + const key = `${activity?.details ?? ""}:${activity?.state ?? ""}`; + + if (!activity) { + clearDetectedActivity(); + if (lastKey) { + lastKey = ""; + } + return; + } + + if (key !== lastKey) { + setDetectedActivity(activity); + lastKey = key; + lastKnownApp = processName; + } + } catch (err) { + console.error("Failed to detect active application", err); + } +} + +export function startActivityDetection() { + activityDetectionEnabled = true; + + if (detectionTimer) { + clearInterval(detectionTimer); + } + + detectionTimer = setInterval(() => { + void detectActivity(); + }, POLL_INTERVAL_MS); + + void detectActivity(); + + powerMonitor.on("resume", () => { + void detectActivity(); + }); +} + +export function stopActivityDetection() { + activityDetectionEnabled = false; + + if (detectionTimer) { + clearInterval(detectionTimer); + detectionTimer = undefined; + } + + lastKey = ""; + lastKnownApp = ""; + clearDetectedActivity(); +}