This commit is contained in:
SanC 2026-07-19 18:02:21 +07:00 committed by GitHub
commit e64d8b27ab
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 1039 additions and 25 deletions

View File

@ -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",

View File

@ -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: {}

1
src/config.d.ts vendored
View File

@ -5,6 +5,7 @@ declare type DesktopConfig = {
spellchecker: boolean;
hardwareAcceleration: boolean;
discordRpc: boolean;
desktopPresence: boolean;
windowState: {
x: number;
y: number;

View File

@ -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
@ -52,6 +53,7 @@ if (acquiredLock) {
initTray();
initDiscordRpc();
startActivityDetection();
// Windows specific fix for notifications
if (process.platform === "win32") {

View File

@ -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"] }

View File

@ -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<string, unknown> | null = null;
let detectedActivity: Record<string, unknown> | null = null;
let isReady = false;
function buildRpcActivity(activity: Record<string, unknown> | null | undefined) {
return {
...(activity ?? {}),
largeImageKey: "qr",
largeImageText: "Join Stoat!",
buttons: [
{
label: "Join Stoat",
url: "https://stoat.chat/",
},
],
};
}
function applyCurrentActivity(activity: Record<string, unknown> | 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<string, unknown>) {
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<string, unknown>) {
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;
}

View File

@ -0,0 +1,439 @@
import { powerMonitor } from "electron";
import { clearDetectedActivity, setDetectedActivity } from "./discordRpc";
const { activeWindowSync } = require("active-win");
// Configuration options with defaults
export interface PresenceDetectorOptions {
/** Polling interval in milliseconds (default: 5000) */
pollIntervalMs?: number;
/** Debounce interval in milliseconds to prevent excessive updates (default: 1000) */
debounceMs?: number;
/** Maximum number of retries for failed window lookups (default: 3) */
maxFetchRetries?: number;
/** Delay between retries in milliseconds (default: 100) */
fetchRetryDelayMs?: number;
}
/** Normalizes an application name/path for comparison */
function normalizeAppName(value: string): string {
return value
.replace(/\\/g, "/")
.replace(/\.(exe|app)$/i, "")
.replace(/\.root$/i, "")
.replace(/[-_.]+/g, " ")
.trim();
}
/** Extracts the executable name without extension from a path */
function extractExecutableName(value: string): string {
const match = value.match(/([^\\/]+)\.(?:exe|app)$/i);
return match?.[1] ?? "";
}
/** Attempts to extract a Steam game name from the owner path or window title */
function getSteamGameName(processName: string, title: string, ownerPath = ""): string {
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 "";
}
/** Builds a PresenceActivity from window info, or null if no meaningful activity */
function buildActivity(processName: string, title: string, ownerPath = ""): { state: string; details: string; timestamps?: { start: number } } | null {
const normalizedProcessName = processName.toLowerCase();
const normalizedTitle = title.toLowerCase();
// ---- Stoat detection (avoid overly broad matches) ----
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() },
};
}
// ---- Steam game detection ----
const steamGameName = getSteamGameName(processName, title, ownerPath);
if (steamGameName) {
return {
state: "Playing",
details: steamGameName,
timestamps: { start: Date.now() },
};
}
// ---- Generic Steam detection ----
if (
normalizedProcessName.includes("steam") ||
normalizedProcessName.includes("steamwebhelper") ||
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() },
};
}
// ---- Other specific app detections ----
if (normalizedProcessName.includes("valorant")) {
return {
state: "Playing",
details: "Valorant",
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")
) {
const details = title
? `Browsing ${title}`
: "Browsing the web";
return {
state: "Browsing",
details: details.length > 128 ? details.slice(0, 128) : details,
timestamps: { start: Date.now() },
};
}
if (normalizedTitle.includes("valorant")) {
return {
state: "In-game",
details: "Playing Valorant",
timestamps: { start: Date.now() },
};
}
// ---- Windows system features (ignore) ----
const windowsSystemProcesses = [
"searchui",
"startmenuexperiencehost",
"shellexperiencehost",
"settings",
"systemsettings",
"taskmgr",
"actioncenter",
"yourphone",
"search",
"cortana",
"windowsshell",
"dwm",
"explorer",
];
const windowsSystemTitleIndicators = [
"search",
"settings",
"task manager",
"action center",
"control panel",
"windows security",
"windows defender",
"feedback hub",
"microsoft store",
];
if (
windowsSystemProcesses.some(proc => normalizedProcessName.includes(proc)) ||
windowsSystemTitleIndicators.some(indicator => normalizedTitle.includes(indicator))
) {
return null;
}
// ---- Desktop/Explorer (ignore) ----
if (
normalizedProcessName.includes("explorer") ||
normalizedProcessName.includes("shell") ||
normalizedProcessName.includes("desktop") ||
normalizedTitle.includes("desktop") ||
normalizedTitle.includes("program manager")
) {
return null;
}
// ---- Fallback generic activity ----
const appName = normalizeAppName(processName || title || "Unknown app");
return {
state: "Active",
details: `Using ${appName || "an app"}`,
timestamps: { start: Date.now() },
};
}
/**
* Fetches foreground window info using a provided lookup function.
* By default uses activeWindowSync, but can be overridden for testing.
*/
function getForegroundInfo(
lookup: (options: { screen: boolean }) => ReturnType<typeof activeWindowSync> | undefined
) {
try {
const activeWindow = lookup({ 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,
ownerPath,
};
} catch (error) {
console.warn("Foreground window lookup failed", error);
return {
processName: "",
title: "",
ownerPath: "",
};
}
}
/** Activity detection state */
let detectionTimer: NodeJS.Timeout | undefined;
let lastKey = "";
let activityDetectionEnabled = true;
let lastUpdateTime = 0;
/**
* Detects activity with retry logic and debouncing.
* @param lookup Function to get foreground info (injectable for testing)
* @param options Configuration options
*/
async function detectActivity(
lookup: (options: { screen: boolean }) => ReturnType<typeof activeWindowSync> | undefined,
options: PresenceDetectorOptions = {}
) {
if (!activityDetectionEnabled) {
clearDetectedActivity();
return;
}
const {
debounceMs = 1000,
maxFetchRetries = 3,
fetchRetryDelayMs = 100,
} = options;
// Throttle updates: if we updated too recently, skip unless forced by a major change
const now = Date.now();
if (now - lastUpdateTime < debounceMs) {
// Still within debounce window; we can still update if the activity is completely cleared
// but we'll rely on the key change detection below.
}
let info;
let attempts = 0;
while (attempts <= maxFetchRetries) {
try {
info = getForegroundInfo(lookup);
break; // success
} catch (err) {
attempts++;
if (attempts > maxFetchRetries) {
console.error("Failed to detect active application after retries", err);
clearDetectedActivity();
lastKey = "";
return;
}
// wait before retry
await new Promise((resolve) =>
setTimeout(resolve, fetchRetryDelayMs * attempts)
);
}
}
if (!info?.processName) {
clearDetectedActivity();
lastKey = "";
return;
}
const activity = buildActivity(
info.processName,
info.title,
info.ownerPath
);
const key = `${activity?.details ?? ""}:${activity?.state ?? ""}`;
if (!activity) {
clearDetectedActivity();
if (lastKey) {
lastKey = "";
}
return;
}
// Only update if the activity changed
if (key !== lastKey) {
setDetectedActivity(activity as Record<string, unknown>);
lastKey = key;
lastUpdateTime = now;
}
}
/** Starts activity detection with configurable options */
export function startActivityDetection(
options: PresenceDetectorOptions = {},
// For testing: inject a lookup function that mimics activeWindowSync
lookup?: (options: { screen: boolean }) => ReturnType<typeof activeWindowSync> | undefined
) {
activityDetectionEnabled = true;
const actualLookup = lookup ?? activeWindowSync;
if (detectionTimer) {
clearInterval(detectionTimer);
}
const {
pollIntervalMs = 5000,
} = options;
detectionTimer = setInterval(() => {
void detectActivity(actualLookup, options);
}, pollIntervalMs);
// Initial detection
void detectActivity(actualLookup, options);
// React to system resume events
powerMonitor.on("resume", () => {
void detectActivity(actualLookup, options);
});
}
/** Stops activity detection and clears state */
export function stopActivityDetection() {
activityDetectionEnabled = false;
if (detectionTimer) {
clearInterval(detectionTimer);
detectionTimer = undefined;
}
lastKey = "";
lastUpdateTime = 0;
clearDetectedActivity();
}