├── .dev.vars.example ├── .editorconfig ├── .gitignore ├── .prettierrc ├── README.md ├── package-lock.json ├── package.json ├── public ├── hand.js ├── index.html ├── script.js └── styles.css ├── src └── index.ts ├── test ├── index.spec.ts └── tsconfig.json ├── tsconfig.json ├── vitest.config.mts ├── worker-configuration.d.ts └── wrangler.toml /.dev.vars.example: -------------------------------------------------------------------------------- 1 | OPENAI_API_KEY="YOUR-API-KEY" 2 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = tab 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [*.yml] 12 | indent_style = space 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | 3 | logs 4 | _.log 5 | npm-debug.log_ 6 | yarn-debug.log* 7 | yarn-error.log* 8 | lerna-debug.log* 9 | .pnpm-debug.log* 10 | 11 | # Diagnostic reports (https://nodejs.org/api/report.html) 12 | 13 | report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json 14 | 15 | # Runtime data 16 | 17 | pids 18 | _.pid 19 | _.seed 20 | \*.pid.lock 21 | 22 | # Directory for instrumented libs generated by jscoverage/JSCover 23 | 24 | lib-cov 25 | 26 | # Coverage directory used by tools like istanbul 27 | 28 | coverage 29 | \*.lcov 30 | 31 | # nyc test coverage 32 | 33 | .nyc_output 34 | 35 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 36 | 37 | .grunt 38 | 39 | # Bower dependency directory (https://bower.io/) 40 | 41 | bower_components 42 | 43 | # node-waf configuration 44 | 45 | .lock-wscript 46 | 47 | # Compiled binary addons (https://nodejs.org/api/addons.html) 48 | 49 | build/Release 50 | 51 | # Dependency directories 52 | 53 | node_modules/ 54 | jspm_packages/ 55 | 56 | # Snowpack dependency directory (https://snowpack.dev/) 57 | 58 | web_modules/ 59 | 60 | # TypeScript cache 61 | 62 | \*.tsbuildinfo 63 | 64 | # Optional npm cache directory 65 | 66 | .npm 67 | 68 | # Optional eslint cache 69 | 70 | .eslintcache 71 | 72 | # Optional stylelint cache 73 | 74 | .stylelintcache 75 | 76 | # Microbundle cache 77 | 78 | .rpt2_cache/ 79 | .rts2_cache_cjs/ 80 | .rts2_cache_es/ 81 | .rts2_cache_umd/ 82 | 83 | # Optional REPL history 84 | 85 | .node_repl_history 86 | 87 | # Output of 'npm pack' 88 | 89 | \*.tgz 90 | 91 | # Yarn Integrity file 92 | 93 | .yarn-integrity 94 | 95 | # dotenv environment variable files 96 | 97 | .env 98 | .env.development.local 99 | .env.test.local 100 | .env.production.local 101 | .env.local 102 | 103 | # parcel-bundler cache (https://parceljs.org/) 104 | 105 | .cache 106 | .parcel-cache 107 | 108 | # Next.js build output 109 | 110 | .next 111 | out 112 | 113 | # Nuxt.js build / generate output 114 | 115 | .nuxt 116 | dist 117 | 118 | # Gatsby files 119 | 120 | .cache/ 121 | 122 | # Comment in the public line in if your project uses Gatsby and not Next.js 123 | 124 | # https://nextjs.org/blog/next-9-1#public-directory-support 125 | 126 | # public 127 | 128 | # vuepress build output 129 | 130 | .vuepress/dist 131 | 132 | # vuepress v2.x temp and cache directory 133 | 134 | .temp 135 | .cache 136 | 137 | # Docusaurus cache and generated files 138 | 139 | .docusaurus 140 | 141 | # Serverless directories 142 | 143 | .serverless/ 144 | 145 | # FuseBox cache 146 | 147 | .fusebox/ 148 | 149 | # DynamoDB Local files 150 | 151 | .dynamodb/ 152 | 153 | # TernJS port file 154 | 155 | .tern-port 156 | 157 | # Stores VSCode versions used for testing VSCode extensions 158 | 159 | .vscode-test 160 | 161 | # yarn v2 162 | 163 | .yarn/cache 164 | .yarn/unplugged 165 | .yarn/build-state.yml 166 | .yarn/install-state.gz 167 | .pnp.\* 168 | 169 | # wrangler project 170 | 171 | .dev.vars 172 | .wrangler/ 173 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 140, 3 | "singleQuote": true, 4 | "semi": true, 5 | "useTabs": true 6 | } 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Client Side Tool Calling with the OpenAI WebRTC Realtime API 2 | 3 | This project is a [Cloudflare Workers](https://developers.cloudflare.com) app using [Hono](https://honojs.dev) to relay the [OpenAI Realtime API](https://platform.openai.com/docs/api-reference/realtime) over WebRTC. The main files are just [static assets](https://developers.cloudflare.com/workers/static-assets/). 4 | 5 | [](https://youtu.be/TcOytsfva0o "Client Side Tool Calling with the OpenAI WebRTC Realtime API") 6 | 7 | 8 | ## Develop 9 | 10 | Copy [.dev.vars.example](./.dev.vars.example) to `.dev.vars` and fill out your OpenAI API Key. 11 | 12 | Install your dependencies 13 | 14 | ```bash 15 | npm install 16 | ``` 17 | 18 | Run local server 19 | 20 | ```bash 21 | npm run dev 22 | ``` 23 | 24 | ## Deploy 25 | 26 | Upload your secret 27 | 28 | ```bash 29 | npx wrangler secret put OPENAI_API_KEY 30 | ``` 31 | 32 | ```bash 33 | npm run deploy 34 | ``` 35 | 36 | The hand is a [HiWonder AI Hand](https://www.hiwonder.com/products/aihand?variant=41022039654487). AI and I reverse-engineered the mobile app to make it work over Bluetooth, see [the code in hand.js](./public/hand.js) 37 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "talk-to-javascript", 3 | "version": "0.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "talk-to-javascript", 9 | "version": "0.0.0", 10 | "dependencies": { 11 | "hono": "^4.6.13" 12 | }, 13 | "devDependencies": { 14 | "@cloudflare/vitest-pool-workers": "^0.5.2", 15 | "@cloudflare/workers-types": "^4.20241205.0", 16 | "typescript": "^5.5.2", 17 | "vitest": "2.1.8", 18 | "wrangler": "^3.107.3" 19 | } 20 | }, 21 | "node_modules/@cloudflare/kv-asset-handler": { 22 | "version": "0.3.4", 23 | "resolved": "https://registry.npmjs.org/@cloudflare/kv-asset-handler/-/kv-asset-handler-0.3.4.tgz", 24 | "integrity": "sha512-YLPHc8yASwjNkmcDMQMY35yiWjoKAKnhUbPRszBRS0YgH+IXtsMp61j+yTcnCE3oO2DgP0U3iejLC8FTtKDC8Q==", 25 | "dev": true, 26 | "dependencies": { 27 | "mime": "^3.0.0" 28 | }, 29 | "engines": { 30 | "node": ">=16.13" 31 | } 32 | }, 33 | "node_modules/@cloudflare/vitest-pool-workers": { 34 | "version": "0.5.36", 35 | "resolved": "https://registry.npmjs.org/@cloudflare/vitest-pool-workers/-/vitest-pool-workers-0.5.36.tgz", 36 | "integrity": "sha512-fp3CiYnSaVePjbeEtJBV4RCs1VWVYOltJST9uTvZRf+zzh2EJP+EJtiibmMpcY3gL9Vd+MT8iYsW07S8nnDbHQ==", 37 | "dev": true, 38 | "dependencies": { 39 | "birpc": "0.2.14", 40 | "cjs-module-lexer": "^1.2.3", 41 | "devalue": "^4.3.0", 42 | "esbuild": "0.17.19", 43 | "miniflare": "3.20241205.0", 44 | "semver": "^7.5.1", 45 | "wrangler": "3.95.0", 46 | "zod": "^3.22.3" 47 | }, 48 | "peerDependencies": { 49 | "@vitest/runner": "2.0.x - 2.1.x", 50 | "@vitest/snapshot": "2.0.x - 2.1.x", 51 | "vitest": "2.0.x - 2.1.x" 52 | } 53 | }, 54 | "node_modules/@cloudflare/vitest-pool-workers/node_modules/unenv": { 55 | "name": "unenv-nightly", 56 | "version": "2.0.0-20241204-140205-a5d5190", 57 | "resolved": "https://registry.npmjs.org/unenv-nightly/-/unenv-nightly-2.0.0-20241204-140205-a5d5190.tgz", 58 | "integrity": "sha512-jpmAytLeiiW01pl5bhVn9wYJ4vtiLdhGe10oXlJBuQEX8mxjxO8BlEXGHU4vr4yEikjFP1wsomTHt/CLU8kUwg==", 59 | "dev": true, 60 | "dependencies": { 61 | "defu": "^6.1.4", 62 | "ohash": "^1.1.4", 63 | "pathe": "^1.1.2", 64 | "ufo": "^1.5.4" 65 | } 66 | }, 67 | "node_modules/@cloudflare/vitest-pool-workers/node_modules/wrangler": { 68 | "version": "3.95.0", 69 | "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-3.95.0.tgz", 70 | "integrity": "sha512-3w5852i3FNyDz421K2Qk4v5L8jjwegO5O8E1+VAQmjnm82HFNxpIRUBq0bmM7CTLvOPI/Jjcmj/eAWjQBL7QYg==", 71 | "dev": true, 72 | "dependencies": { 73 | "@cloudflare/kv-asset-handler": "0.3.4", 74 | "@cloudflare/workers-shared": "0.11.0", 75 | "@esbuild-plugins/node-globals-polyfill": "^0.2.3", 76 | "@esbuild-plugins/node-modules-polyfill": "^0.2.2", 77 | "blake3-wasm": "^2.1.5", 78 | "chokidar": "^4.0.1", 79 | "date-fns": "^4.1.0", 80 | "esbuild": "0.17.19", 81 | "itty-time": "^1.0.6", 82 | "miniflare": "3.20241205.0", 83 | "nanoid": "^3.3.3", 84 | "path-to-regexp": "^6.3.0", 85 | "resolve": "^1.22.8", 86 | "selfsigned": "^2.0.1", 87 | "source-map": "^0.6.1", 88 | "unenv": "npm:unenv-nightly@2.0.0-20241204-140205-a5d5190", 89 | "workerd": "1.20241205.0", 90 | "xxhash-wasm": "^1.0.1" 91 | }, 92 | "bin": { 93 | "wrangler": "bin/wrangler.js", 94 | "wrangler2": "bin/wrangler.js" 95 | }, 96 | "engines": { 97 | "node": ">=16.17.0" 98 | }, 99 | "optionalDependencies": { 100 | "fsevents": "~2.3.2" 101 | }, 102 | "peerDependencies": { 103 | "@cloudflare/workers-types": "^4.20241205.0" 104 | }, 105 | "peerDependenciesMeta": { 106 | "@cloudflare/workers-types": { 107 | "optional": true 108 | } 109 | } 110 | }, 111 | "node_modules/@cloudflare/workerd-darwin-64": { 112 | "version": "1.20241205.0", 113 | "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20241205.0.tgz", 114 | "integrity": "sha512-TArEZkSZkHJyEwnlWWkSpCI99cF6lJ14OVeEoI9Um/+cD9CKZLM9vCmsLeKglKheJ0KcdCnkA+DbeD15t3VaWg==", 115 | "cpu": [ 116 | "x64" 117 | ], 118 | "dev": true, 119 | "optional": true, 120 | "os": [ 121 | "darwin" 122 | ], 123 | "engines": { 124 | "node": ">=16" 125 | } 126 | }, 127 | "node_modules/@cloudflare/workerd-darwin-arm64": { 128 | "version": "1.20241205.0", 129 | "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20241205.0.tgz", 130 | "integrity": "sha512-u5eqKa9QRdA8MugfgCoD+ADDjY6EpKbv3hSYJETmmUh17l7WXjWBzv4pUvOKIX67C0UzMUy4jZYwC53MymhX3w==", 131 | "cpu": [ 132 | "arm64" 133 | ], 134 | "dev": true, 135 | "optional": true, 136 | "os": [ 137 | "darwin" 138 | ], 139 | "engines": { 140 | "node": ">=16" 141 | } 142 | }, 143 | "node_modules/@cloudflare/workerd-linux-64": { 144 | "version": "1.20241205.0", 145 | "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20241205.0.tgz", 146 | "integrity": "sha512-OYA7S5zpumMamWEW+IhhBU6YojIEocyE5X/YFPiTOCrDE3dsfr9t6oqNE7hxGm1VAAu+Irtl+a/5LwmBOU681w==", 147 | "cpu": [ 148 | "x64" 149 | ], 150 | "dev": true, 151 | "optional": true, 152 | "os": [ 153 | "linux" 154 | ], 155 | "engines": { 156 | "node": ">=16" 157 | } 158 | }, 159 | "node_modules/@cloudflare/workerd-linux-arm64": { 160 | "version": "1.20241205.0", 161 | "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20241205.0.tgz", 162 | "integrity": "sha512-qAzecONjFJGIAVJZKExQ5dlbic0f3d4A+GdKa+H6SoUJtPaWiE3K6WuePo4JOT7W3/Zfh25McmX+MmpMUUcM5Q==", 163 | "cpu": [ 164 | "arm64" 165 | ], 166 | "dev": true, 167 | "optional": true, 168 | "os": [ 169 | "linux" 170 | ], 171 | "engines": { 172 | "node": ">=16" 173 | } 174 | }, 175 | "node_modules/@cloudflare/workerd-windows-64": { 176 | "version": "1.20241205.0", 177 | "resolved": "https://registry.npmjs.org/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20241205.0.tgz", 178 | "integrity": "sha512-BEab+HiUgCdl6GXAT7EI2yaRtDPiRJlB94XLvRvXi1ZcmQqsrq6awGo6apctFo4WUL29V7c09LxmN4HQ3X2Tvg==", 179 | "cpu": [ 180 | "x64" 181 | ], 182 | "dev": true, 183 | "optional": true, 184 | "os": [ 185 | "win32" 186 | ], 187 | "engines": { 188 | "node": ">=16" 189 | } 190 | }, 191 | "node_modules/@cloudflare/workers-shared": { 192 | "version": "0.11.0", 193 | "resolved": "https://registry.npmjs.org/@cloudflare/workers-shared/-/workers-shared-0.11.0.tgz", 194 | "integrity": "sha512-A+lQ8xp7992qSeMmuQ0ssL6CPmm+ZmAv6Ddikan0n1jjpMAic+97l7xtVIsswSn9iLMFPYQ9uNN/8Fl0AgARIQ==", 195 | "dev": true, 196 | "dependencies": { 197 | "mime": "^3.0.0", 198 | "zod": "^3.22.3" 199 | }, 200 | "engines": { 201 | "node": ">=16.7.0" 202 | } 203 | }, 204 | "node_modules/@cloudflare/workers-types": { 205 | "version": "4.20250204.0", 206 | "resolved": "https://registry.npmjs.org/@cloudflare/workers-types/-/workers-types-4.20250204.0.tgz", 207 | "integrity": "sha512-mWoQbYaP+nYztx9I7q9sgaiNlT54Cypszz0RfzMxYnT5W3NXDuwGcjGB+5B5H5VB8tEC2dYnBRpa70lX94ueaQ==", 208 | "dev": true 209 | }, 210 | "node_modules/@cspotcode/source-map-support": { 211 | "version": "0.8.1", 212 | "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", 213 | "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", 214 | "dev": true, 215 | "dependencies": { 216 | "@jridgewell/trace-mapping": "0.3.9" 217 | }, 218 | "engines": { 219 | "node": ">=12" 220 | } 221 | }, 222 | "node_modules/@esbuild-plugins/node-globals-polyfill": { 223 | "version": "0.2.3", 224 | "resolved": "https://registry.npmjs.org/@esbuild-plugins/node-globals-polyfill/-/node-globals-polyfill-0.2.3.tgz", 225 | "integrity": "sha512-r3MIryXDeXDOZh7ih1l/yE9ZLORCd5e8vWg02azWRGj5SPTuoh69A2AIyn0Z31V/kHBfZ4HgWJ+OK3GTTwLmnw==", 226 | "dev": true, 227 | "peerDependencies": { 228 | "esbuild": "*" 229 | } 230 | }, 231 | "node_modules/@esbuild-plugins/node-modules-polyfill": { 232 | "version": "0.2.2", 233 | "resolved": "https://registry.npmjs.org/@esbuild-plugins/node-modules-polyfill/-/node-modules-polyfill-0.2.2.tgz", 234 | "integrity": "sha512-LXV7QsWJxRuMYvKbiznh+U1ilIop3g2TeKRzUxOG5X3YITc8JyyTa90BmLwqqv0YnX4v32CSlG+vsziZp9dMvA==", 235 | "dev": true, 236 | "dependencies": { 237 | "escape-string-regexp": "^4.0.0", 238 | "rollup-plugin-node-polyfills": "^0.2.1" 239 | }, 240 | "peerDependencies": { 241 | "esbuild": "*" 242 | } 243 | }, 244 | "node_modules/@esbuild/aix-ppc64": { 245 | "version": "0.21.5", 246 | "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", 247 | "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", 248 | "cpu": [ 249 | "ppc64" 250 | ], 251 | "dev": true, 252 | "optional": true, 253 | "os": [ 254 | "aix" 255 | ], 256 | "engines": { 257 | "node": ">=12" 258 | } 259 | }, 260 | "node_modules/@esbuild/android-arm": { 261 | "version": "0.17.19", 262 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.19.tgz", 263 | "integrity": "sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A==", 264 | "cpu": [ 265 | "arm" 266 | ], 267 | "dev": true, 268 | "optional": true, 269 | "os": [ 270 | "android" 271 | ], 272 | "engines": { 273 | "node": ">=12" 274 | } 275 | }, 276 | "node_modules/@esbuild/android-arm64": { 277 | "version": "0.17.19", 278 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.19.tgz", 279 | "integrity": "sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==", 280 | "cpu": [ 281 | "arm64" 282 | ], 283 | "dev": true, 284 | "optional": true, 285 | "os": [ 286 | "android" 287 | ], 288 | "engines": { 289 | "node": ">=12" 290 | } 291 | }, 292 | "node_modules/@esbuild/android-x64": { 293 | "version": "0.17.19", 294 | "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.19.tgz", 295 | "integrity": "sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww==", 296 | "cpu": [ 297 | "x64" 298 | ], 299 | "dev": true, 300 | "optional": true, 301 | "os": [ 302 | "android" 303 | ], 304 | "engines": { 305 | "node": ">=12" 306 | } 307 | }, 308 | "node_modules/@esbuild/darwin-arm64": { 309 | "version": "0.17.19", 310 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.19.tgz", 311 | "integrity": "sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg==", 312 | "cpu": [ 313 | "arm64" 314 | ], 315 | "dev": true, 316 | "optional": true, 317 | "os": [ 318 | "darwin" 319 | ], 320 | "engines": { 321 | "node": ">=12" 322 | } 323 | }, 324 | "node_modules/@esbuild/darwin-x64": { 325 | "version": "0.17.19", 326 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.19.tgz", 327 | "integrity": "sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==", 328 | "cpu": [ 329 | "x64" 330 | ], 331 | "dev": true, 332 | "optional": true, 333 | "os": [ 334 | "darwin" 335 | ], 336 | "engines": { 337 | "node": ">=12" 338 | } 339 | }, 340 | "node_modules/@esbuild/freebsd-arm64": { 341 | "version": "0.17.19", 342 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.19.tgz", 343 | "integrity": "sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ==", 344 | "cpu": [ 345 | "arm64" 346 | ], 347 | "dev": true, 348 | "optional": true, 349 | "os": [ 350 | "freebsd" 351 | ], 352 | "engines": { 353 | "node": ">=12" 354 | } 355 | }, 356 | "node_modules/@esbuild/freebsd-x64": { 357 | "version": "0.17.19", 358 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.19.tgz", 359 | "integrity": "sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ==", 360 | "cpu": [ 361 | "x64" 362 | ], 363 | "dev": true, 364 | "optional": true, 365 | "os": [ 366 | "freebsd" 367 | ], 368 | "engines": { 369 | "node": ">=12" 370 | } 371 | }, 372 | "node_modules/@esbuild/linux-arm": { 373 | "version": "0.17.19", 374 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.19.tgz", 375 | "integrity": "sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA==", 376 | "cpu": [ 377 | "arm" 378 | ], 379 | "dev": true, 380 | "optional": true, 381 | "os": [ 382 | "linux" 383 | ], 384 | "engines": { 385 | "node": ">=12" 386 | } 387 | }, 388 | "node_modules/@esbuild/linux-arm64": { 389 | "version": "0.17.19", 390 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.19.tgz", 391 | "integrity": "sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg==", 392 | "cpu": [ 393 | "arm64" 394 | ], 395 | "dev": true, 396 | "optional": true, 397 | "os": [ 398 | "linux" 399 | ], 400 | "engines": { 401 | "node": ">=12" 402 | } 403 | }, 404 | "node_modules/@esbuild/linux-ia32": { 405 | "version": "0.17.19", 406 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.19.tgz", 407 | "integrity": "sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ==", 408 | "cpu": [ 409 | "ia32" 410 | ], 411 | "dev": true, 412 | "optional": true, 413 | "os": [ 414 | "linux" 415 | ], 416 | "engines": { 417 | "node": ">=12" 418 | } 419 | }, 420 | "node_modules/@esbuild/linux-loong64": { 421 | "version": "0.17.19", 422 | "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.19.tgz", 423 | "integrity": "sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ==", 424 | "cpu": [ 425 | "loong64" 426 | ], 427 | "dev": true, 428 | "optional": true, 429 | "os": [ 430 | "linux" 431 | ], 432 | "engines": { 433 | "node": ">=12" 434 | } 435 | }, 436 | "node_modules/@esbuild/linux-mips64el": { 437 | "version": "0.17.19", 438 | "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.19.tgz", 439 | "integrity": "sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A==", 440 | "cpu": [ 441 | "mips64el" 442 | ], 443 | "dev": true, 444 | "optional": true, 445 | "os": [ 446 | "linux" 447 | ], 448 | "engines": { 449 | "node": ">=12" 450 | } 451 | }, 452 | "node_modules/@esbuild/linux-ppc64": { 453 | "version": "0.17.19", 454 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.19.tgz", 455 | "integrity": "sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg==", 456 | "cpu": [ 457 | "ppc64" 458 | ], 459 | "dev": true, 460 | "optional": true, 461 | "os": [ 462 | "linux" 463 | ], 464 | "engines": { 465 | "node": ">=12" 466 | } 467 | }, 468 | "node_modules/@esbuild/linux-riscv64": { 469 | "version": "0.17.19", 470 | "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.19.tgz", 471 | "integrity": "sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA==", 472 | "cpu": [ 473 | "riscv64" 474 | ], 475 | "dev": true, 476 | "optional": true, 477 | "os": [ 478 | "linux" 479 | ], 480 | "engines": { 481 | "node": ">=12" 482 | } 483 | }, 484 | "node_modules/@esbuild/linux-s390x": { 485 | "version": "0.17.19", 486 | "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.19.tgz", 487 | "integrity": "sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q==", 488 | "cpu": [ 489 | "s390x" 490 | ], 491 | "dev": true, 492 | "optional": true, 493 | "os": [ 494 | "linux" 495 | ], 496 | "engines": { 497 | "node": ">=12" 498 | } 499 | }, 500 | "node_modules/@esbuild/linux-x64": { 501 | "version": "0.17.19", 502 | "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.19.tgz", 503 | "integrity": "sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw==", 504 | "cpu": [ 505 | "x64" 506 | ], 507 | "dev": true, 508 | "optional": true, 509 | "os": [ 510 | "linux" 511 | ], 512 | "engines": { 513 | "node": ">=12" 514 | } 515 | }, 516 | "node_modules/@esbuild/netbsd-x64": { 517 | "version": "0.17.19", 518 | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.19.tgz", 519 | "integrity": "sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q==", 520 | "cpu": [ 521 | "x64" 522 | ], 523 | "dev": true, 524 | "optional": true, 525 | "os": [ 526 | "netbsd" 527 | ], 528 | "engines": { 529 | "node": ">=12" 530 | } 531 | }, 532 | "node_modules/@esbuild/openbsd-x64": { 533 | "version": "0.17.19", 534 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.19.tgz", 535 | "integrity": "sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g==", 536 | "cpu": [ 537 | "x64" 538 | ], 539 | "dev": true, 540 | "optional": true, 541 | "os": [ 542 | "openbsd" 543 | ], 544 | "engines": { 545 | "node": ">=12" 546 | } 547 | }, 548 | "node_modules/@esbuild/sunos-x64": { 549 | "version": "0.17.19", 550 | "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.19.tgz", 551 | "integrity": "sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg==", 552 | "cpu": [ 553 | "x64" 554 | ], 555 | "dev": true, 556 | "optional": true, 557 | "os": [ 558 | "sunos" 559 | ], 560 | "engines": { 561 | "node": ">=12" 562 | } 563 | }, 564 | "node_modules/@esbuild/win32-arm64": { 565 | "version": "0.17.19", 566 | "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.19.tgz", 567 | "integrity": "sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag==", 568 | "cpu": [ 569 | "arm64" 570 | ], 571 | "dev": true, 572 | "optional": true, 573 | "os": [ 574 | "win32" 575 | ], 576 | "engines": { 577 | "node": ">=12" 578 | } 579 | }, 580 | "node_modules/@esbuild/win32-ia32": { 581 | "version": "0.17.19", 582 | "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.19.tgz", 583 | "integrity": "sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw==", 584 | "cpu": [ 585 | "ia32" 586 | ], 587 | "dev": true, 588 | "optional": true, 589 | "os": [ 590 | "win32" 591 | ], 592 | "engines": { 593 | "node": ">=12" 594 | } 595 | }, 596 | "node_modules/@esbuild/win32-x64": { 597 | "version": "0.17.19", 598 | "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.19.tgz", 599 | "integrity": "sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==", 600 | "cpu": [ 601 | "x64" 602 | ], 603 | "dev": true, 604 | "optional": true, 605 | "os": [ 606 | "win32" 607 | ], 608 | "engines": { 609 | "node": ">=12" 610 | } 611 | }, 612 | "node_modules/@fastify/busboy": { 613 | "version": "2.1.1", 614 | "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz", 615 | "integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==", 616 | "dev": true, 617 | "engines": { 618 | "node": ">=14" 619 | } 620 | }, 621 | "node_modules/@jridgewell/resolve-uri": { 622 | "version": "3.1.2", 623 | "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", 624 | "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", 625 | "dev": true, 626 | "engines": { 627 | "node": ">=6.0.0" 628 | } 629 | }, 630 | "node_modules/@jridgewell/sourcemap-codec": { 631 | "version": "1.5.0", 632 | "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", 633 | "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", 634 | "dev": true 635 | }, 636 | "node_modules/@jridgewell/trace-mapping": { 637 | "version": "0.3.9", 638 | "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", 639 | "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", 640 | "dev": true, 641 | "dependencies": { 642 | "@jridgewell/resolve-uri": "^3.0.3", 643 | "@jridgewell/sourcemap-codec": "^1.4.10" 644 | } 645 | }, 646 | "node_modules/@rollup/rollup-android-arm-eabi": { 647 | "version": "4.28.1", 648 | "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.28.1.tgz", 649 | "integrity": "sha512-2aZp8AES04KI2dy3Ss6/MDjXbwBzj+i0GqKtWXgw2/Ma6E4jJvujryO6gJAghIRVz7Vwr9Gtl/8na3nDUKpraQ==", 650 | "cpu": [ 651 | "arm" 652 | ], 653 | "dev": true, 654 | "optional": true, 655 | "os": [ 656 | "android" 657 | ] 658 | }, 659 | "node_modules/@rollup/rollup-android-arm64": { 660 | "version": "4.28.1", 661 | "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.28.1.tgz", 662 | "integrity": "sha512-EbkK285O+1YMrg57xVA+Dp0tDBRB93/BZKph9XhMjezf6F4TpYjaUSuPt5J0fZXlSag0LmZAsTmdGGqPp4pQFA==", 663 | "cpu": [ 664 | "arm64" 665 | ], 666 | "dev": true, 667 | "optional": true, 668 | "os": [ 669 | "android" 670 | ] 671 | }, 672 | "node_modules/@rollup/rollup-darwin-arm64": { 673 | "version": "4.28.1", 674 | "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.28.1.tgz", 675 | "integrity": "sha512-prduvrMKU6NzMq6nxzQw445zXgaDBbMQvmKSJaxpaZ5R1QDM8w+eGxo6Y/jhT/cLoCvnZI42oEqf9KQNYz1fqQ==", 676 | "cpu": [ 677 | "arm64" 678 | ], 679 | "dev": true, 680 | "optional": true, 681 | "os": [ 682 | "darwin" 683 | ] 684 | }, 685 | "node_modules/@rollup/rollup-darwin-x64": { 686 | "version": "4.28.1", 687 | "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.28.1.tgz", 688 | "integrity": "sha512-WsvbOunsUk0wccO/TV4o7IKgloJ942hVFK1CLatwv6TJspcCZb9umQkPdvB7FihmdxgaKR5JyxDjWpCOp4uZlQ==", 689 | "cpu": [ 690 | "x64" 691 | ], 692 | "dev": true, 693 | "optional": true, 694 | "os": [ 695 | "darwin" 696 | ] 697 | }, 698 | "node_modules/@rollup/rollup-freebsd-arm64": { 699 | "version": "4.28.1", 700 | "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.28.1.tgz", 701 | "integrity": "sha512-HTDPdY1caUcU4qK23FeeGxCdJF64cKkqajU0iBnTVxS8F7H/7BewvYoG+va1KPSL63kQ1PGNyiwKOfReavzvNA==", 702 | "cpu": [ 703 | "arm64" 704 | ], 705 | "dev": true, 706 | "optional": true, 707 | "os": [ 708 | "freebsd" 709 | ] 710 | }, 711 | "node_modules/@rollup/rollup-freebsd-x64": { 712 | "version": "4.28.1", 713 | "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.28.1.tgz", 714 | "integrity": "sha512-m/uYasxkUevcFTeRSM9TeLyPe2QDuqtjkeoTpP9SW0XxUWfcYrGDMkO/m2tTw+4NMAF9P2fU3Mw4ahNvo7QmsQ==", 715 | "cpu": [ 716 | "x64" 717 | ], 718 | "dev": true, 719 | "optional": true, 720 | "os": [ 721 | "freebsd" 722 | ] 723 | }, 724 | "node_modules/@rollup/rollup-linux-arm-gnueabihf": { 725 | "version": "4.28.1", 726 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.28.1.tgz", 727 | "integrity": "sha512-QAg11ZIt6mcmzpNE6JZBpKfJaKkqTm1A9+y9O+frdZJEuhQxiugM05gnCWiANHj4RmbgeVJpTdmKRmH/a+0QbA==", 728 | "cpu": [ 729 | "arm" 730 | ], 731 | "dev": true, 732 | "optional": true, 733 | "os": [ 734 | "linux" 735 | ] 736 | }, 737 | "node_modules/@rollup/rollup-linux-arm-musleabihf": { 738 | "version": "4.28.1", 739 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.28.1.tgz", 740 | "integrity": "sha512-dRP9PEBfolq1dmMcFqbEPSd9VlRuVWEGSmbxVEfiq2cs2jlZAl0YNxFzAQS2OrQmsLBLAATDMb3Z6MFv5vOcXg==", 741 | "cpu": [ 742 | "arm" 743 | ], 744 | "dev": true, 745 | "optional": true, 746 | "os": [ 747 | "linux" 748 | ] 749 | }, 750 | "node_modules/@rollup/rollup-linux-arm64-gnu": { 751 | "version": "4.28.1", 752 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.28.1.tgz", 753 | "integrity": "sha512-uGr8khxO+CKT4XU8ZUH1TTEUtlktK6Kgtv0+6bIFSeiSlnGJHG1tSFSjm41uQ9sAO/5ULx9mWOz70jYLyv1QkA==", 754 | "cpu": [ 755 | "arm64" 756 | ], 757 | "dev": true, 758 | "optional": true, 759 | "os": [ 760 | "linux" 761 | ] 762 | }, 763 | "node_modules/@rollup/rollup-linux-arm64-musl": { 764 | "version": "4.28.1", 765 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.28.1.tgz", 766 | "integrity": "sha512-QF54q8MYGAqMLrX2t7tNpi01nvq5RI59UBNx+3+37zoKX5KViPo/gk2QLhsuqok05sSCRluj0D00LzCwBikb0A==", 767 | "cpu": [ 768 | "arm64" 769 | ], 770 | "dev": true, 771 | "optional": true, 772 | "os": [ 773 | "linux" 774 | ] 775 | }, 776 | "node_modules/@rollup/rollup-linux-loongarch64-gnu": { 777 | "version": "4.28.1", 778 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.28.1.tgz", 779 | "integrity": "sha512-vPul4uodvWvLhRco2w0GcyZcdyBfpfDRgNKU+p35AWEbJ/HPs1tOUrkSueVbBS0RQHAf/A+nNtDpvw95PeVKOA==", 780 | "cpu": [ 781 | "loong64" 782 | ], 783 | "dev": true, 784 | "optional": true, 785 | "os": [ 786 | "linux" 787 | ] 788 | }, 789 | "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { 790 | "version": "4.28.1", 791 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.28.1.tgz", 792 | "integrity": "sha512-pTnTdBuC2+pt1Rmm2SV7JWRqzhYpEILML4PKODqLz+C7Ou2apEV52h19CR7es+u04KlqplggmN9sqZlekg3R1A==", 793 | "cpu": [ 794 | "ppc64" 795 | ], 796 | "dev": true, 797 | "optional": true, 798 | "os": [ 799 | "linux" 800 | ] 801 | }, 802 | "node_modules/@rollup/rollup-linux-riscv64-gnu": { 803 | "version": "4.28.1", 804 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.28.1.tgz", 805 | "integrity": "sha512-vWXy1Nfg7TPBSuAncfInmAI/WZDd5vOklyLJDdIRKABcZWojNDY0NJwruY2AcnCLnRJKSaBgf/GiJfauu8cQZA==", 806 | "cpu": [ 807 | "riscv64" 808 | ], 809 | "dev": true, 810 | "optional": true, 811 | "os": [ 812 | "linux" 813 | ] 814 | }, 815 | "node_modules/@rollup/rollup-linux-s390x-gnu": { 816 | "version": "4.28.1", 817 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.28.1.tgz", 818 | "integrity": "sha512-/yqC2Y53oZjb0yz8PVuGOQQNOTwxcizudunl/tFs1aLvObTclTwZ0JhXF2XcPT/zuaymemCDSuuUPXJJyqeDOg==", 819 | "cpu": [ 820 | "s390x" 821 | ], 822 | "dev": true, 823 | "optional": true, 824 | "os": [ 825 | "linux" 826 | ] 827 | }, 828 | "node_modules/@rollup/rollup-linux-x64-gnu": { 829 | "version": "4.28.1", 830 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.28.1.tgz", 831 | "integrity": "sha512-fzgeABz7rrAlKYB0y2kSEiURrI0691CSL0+KXwKwhxvj92VULEDQLpBYLHpF49MSiPG4sq5CK3qHMnb9tlCjBw==", 832 | "cpu": [ 833 | "x64" 834 | ], 835 | "dev": true, 836 | "optional": true, 837 | "os": [ 838 | "linux" 839 | ] 840 | }, 841 | "node_modules/@rollup/rollup-linux-x64-musl": { 842 | "version": "4.28.1", 843 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.28.1.tgz", 844 | "integrity": "sha512-xQTDVzSGiMlSshpJCtudbWyRfLaNiVPXt1WgdWTwWz9n0U12cI2ZVtWe/Jgwyv/6wjL7b66uu61Vg0POWVfz4g==", 845 | "cpu": [ 846 | "x64" 847 | ], 848 | "dev": true, 849 | "optional": true, 850 | "os": [ 851 | "linux" 852 | ] 853 | }, 854 | "node_modules/@rollup/rollup-win32-arm64-msvc": { 855 | "version": "4.28.1", 856 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.28.1.tgz", 857 | "integrity": "sha512-wSXmDRVupJstFP7elGMgv+2HqXelQhuNf+IS4V+nUpNVi/GUiBgDmfwD0UGN3pcAnWsgKG3I52wMOBnk1VHr/A==", 858 | "cpu": [ 859 | "arm64" 860 | ], 861 | "dev": true, 862 | "optional": true, 863 | "os": [ 864 | "win32" 865 | ] 866 | }, 867 | "node_modules/@rollup/rollup-win32-ia32-msvc": { 868 | "version": "4.28.1", 869 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.28.1.tgz", 870 | "integrity": "sha512-ZkyTJ/9vkgrE/Rk9vhMXhf8l9D+eAhbAVbsGsXKy2ohmJaWg0LPQLnIxRdRp/bKyr8tXuPlXhIoGlEB5XpJnGA==", 871 | "cpu": [ 872 | "ia32" 873 | ], 874 | "dev": true, 875 | "optional": true, 876 | "os": [ 877 | "win32" 878 | ] 879 | }, 880 | "node_modules/@rollup/rollup-win32-x64-msvc": { 881 | "version": "4.28.1", 882 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.28.1.tgz", 883 | "integrity": "sha512-ZvK2jBafvttJjoIdKm/Q/Bh7IJ1Ose9IBOwpOXcOvW3ikGTQGmKDgxTC6oCAzW6PynbkKP8+um1du81XJHZ0JA==", 884 | "cpu": [ 885 | "x64" 886 | ], 887 | "dev": true, 888 | "optional": true, 889 | "os": [ 890 | "win32" 891 | ] 892 | }, 893 | "node_modules/@types/estree": { 894 | "version": "1.0.6", 895 | "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", 896 | "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", 897 | "dev": true 898 | }, 899 | "node_modules/@types/node": { 900 | "version": "22.10.1", 901 | "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.1.tgz", 902 | "integrity": "sha512-qKgsUwfHZV2WCWLAnVP1JqnpE6Im6h3Y0+fYgMTasNQ7V++CBX5OT1as0g0f+OyubbFqhf6XVNIsmN4IIhEgGQ==", 903 | "dev": true, 904 | "dependencies": { 905 | "undici-types": "~6.20.0" 906 | } 907 | }, 908 | "node_modules/@types/node-forge": { 909 | "version": "1.3.11", 910 | "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.11.tgz", 911 | "integrity": "sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==", 912 | "dev": true, 913 | "dependencies": { 914 | "@types/node": "*" 915 | } 916 | }, 917 | "node_modules/@vitest/expect": { 918 | "version": "2.1.8", 919 | "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.1.8.tgz", 920 | "integrity": "sha512-8ytZ/fFHq2g4PJVAtDX57mayemKgDR6X3Oa2Foro+EygiOJHUXhCqBAAKQYYajZpFoIfvBCF1j6R6IYRSIUFuw==", 921 | "dev": true, 922 | "dependencies": { 923 | "@vitest/spy": "2.1.8", 924 | "@vitest/utils": "2.1.8", 925 | "chai": "^5.1.2", 926 | "tinyrainbow": "^1.2.0" 927 | }, 928 | "funding": { 929 | "url": "https://opencollective.com/vitest" 930 | } 931 | }, 932 | "node_modules/@vitest/mocker": { 933 | "version": "2.1.8", 934 | "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-2.1.8.tgz", 935 | "integrity": "sha512-7guJ/47I6uqfttp33mgo6ga5Gr1VnL58rcqYKyShoRK9ebu8T5Rs6HN3s1NABiBeVTdWNrwUMcHH54uXZBN4zA==", 936 | "dev": true, 937 | "dependencies": { 938 | "@vitest/spy": "2.1.8", 939 | "estree-walker": "^3.0.3", 940 | "magic-string": "^0.30.12" 941 | }, 942 | "funding": { 943 | "url": "https://opencollective.com/vitest" 944 | }, 945 | "peerDependencies": { 946 | "msw": "^2.4.9", 947 | "vite": "^5.0.0" 948 | }, 949 | "peerDependenciesMeta": { 950 | "msw": { 951 | "optional": true 952 | }, 953 | "vite": { 954 | "optional": true 955 | } 956 | } 957 | }, 958 | "node_modules/@vitest/pretty-format": { 959 | "version": "2.1.8", 960 | "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.1.8.tgz", 961 | "integrity": "sha512-9HiSZ9zpqNLKlbIDRWOnAWqgcA7xu+8YxXSekhr0Ykab7PAYFkhkwoqVArPOtJhPmYeE2YHgKZlj3CP36z2AJQ==", 962 | "dev": true, 963 | "dependencies": { 964 | "tinyrainbow": "^1.2.0" 965 | }, 966 | "funding": { 967 | "url": "https://opencollective.com/vitest" 968 | } 969 | }, 970 | "node_modules/@vitest/runner": { 971 | "version": "2.1.8", 972 | "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-2.1.8.tgz", 973 | "integrity": "sha512-17ub8vQstRnRlIU5k50bG+QOMLHRhYPAna5tw8tYbj+jzjcspnwnwtPtiOlkuKC4+ixDPTuLZiqiWWQ2PSXHVg==", 974 | "dev": true, 975 | "dependencies": { 976 | "@vitest/utils": "2.1.8", 977 | "pathe": "^1.1.2" 978 | }, 979 | "funding": { 980 | "url": "https://opencollective.com/vitest" 981 | } 982 | }, 983 | "node_modules/@vitest/snapshot": { 984 | "version": "2.1.8", 985 | "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.1.8.tgz", 986 | "integrity": "sha512-20T7xRFbmnkfcmgVEz+z3AU/3b0cEzZOt/zmnvZEctg64/QZbSDJEVm9fLnnlSi74KibmRsO9/Qabi+t0vCRPg==", 987 | "dev": true, 988 | "dependencies": { 989 | "@vitest/pretty-format": "2.1.8", 990 | "magic-string": "^0.30.12", 991 | "pathe": "^1.1.2" 992 | }, 993 | "funding": { 994 | "url": "https://opencollective.com/vitest" 995 | } 996 | }, 997 | "node_modules/@vitest/spy": { 998 | "version": "2.1.8", 999 | "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.1.8.tgz", 1000 | "integrity": "sha512-5swjf2q95gXeYPevtW0BLk6H8+bPlMb4Vw/9Em4hFxDcaOxS+e0LOX4yqNxoHzMR2akEB2xfpnWUzkZokmgWDg==", 1001 | "dev": true, 1002 | "dependencies": { 1003 | "tinyspy": "^3.0.2" 1004 | }, 1005 | "funding": { 1006 | "url": "https://opencollective.com/vitest" 1007 | } 1008 | }, 1009 | "node_modules/@vitest/utils": { 1010 | "version": "2.1.8", 1011 | "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.1.8.tgz", 1012 | "integrity": "sha512-dwSoui6djdwbfFmIgbIjX2ZhIoG7Ex/+xpxyiEgIGzjliY8xGkcpITKTlp6B4MgtGkF2ilvm97cPM96XZaAgcA==", 1013 | "dev": true, 1014 | "dependencies": { 1015 | "@vitest/pretty-format": "2.1.8", 1016 | "loupe": "^3.1.2", 1017 | "tinyrainbow": "^1.2.0" 1018 | }, 1019 | "funding": { 1020 | "url": "https://opencollective.com/vitest" 1021 | } 1022 | }, 1023 | "node_modules/acorn": { 1024 | "version": "8.14.0", 1025 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", 1026 | "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", 1027 | "dev": true, 1028 | "bin": { 1029 | "acorn": "bin/acorn" 1030 | }, 1031 | "engines": { 1032 | "node": ">=0.4.0" 1033 | } 1034 | }, 1035 | "node_modules/acorn-walk": { 1036 | "version": "8.3.4", 1037 | "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", 1038 | "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", 1039 | "dev": true, 1040 | "dependencies": { 1041 | "acorn": "^8.11.0" 1042 | }, 1043 | "engines": { 1044 | "node": ">=0.4.0" 1045 | } 1046 | }, 1047 | "node_modules/as-table": { 1048 | "version": "1.0.55", 1049 | "resolved": "https://registry.npmjs.org/as-table/-/as-table-1.0.55.tgz", 1050 | "integrity": "sha512-xvsWESUJn0JN421Xb9MQw6AsMHRCUknCe0Wjlxvjud80mU4E6hQf1A6NzQKcYNmYw62MfzEtXc+badstZP3JpQ==", 1051 | "dev": true, 1052 | "dependencies": { 1053 | "printable-characters": "^1.0.42" 1054 | } 1055 | }, 1056 | "node_modules/assertion-error": { 1057 | "version": "2.0.1", 1058 | "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", 1059 | "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", 1060 | "dev": true, 1061 | "engines": { 1062 | "node": ">=12" 1063 | } 1064 | }, 1065 | "node_modules/birpc": { 1066 | "version": "0.2.14", 1067 | "resolved": "https://registry.npmjs.org/birpc/-/birpc-0.2.14.tgz", 1068 | "integrity": "sha512-37FHE8rqsYM5JEKCnXFyHpBCzvgHEExwVVTq+nUmloInU7l8ezD1TpOhKpS8oe1DTYFqEK27rFZVKG43oTqXRA==", 1069 | "dev": true, 1070 | "funding": { 1071 | "url": "https://github.com/sponsors/antfu" 1072 | } 1073 | }, 1074 | "node_modules/blake3-wasm": { 1075 | "version": "2.1.5", 1076 | "resolved": "https://registry.npmjs.org/blake3-wasm/-/blake3-wasm-2.1.5.tgz", 1077 | "integrity": "sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==", 1078 | "dev": true 1079 | }, 1080 | "node_modules/cac": { 1081 | "version": "6.7.14", 1082 | "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", 1083 | "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", 1084 | "dev": true, 1085 | "engines": { 1086 | "node": ">=8" 1087 | } 1088 | }, 1089 | "node_modules/capnp-ts": { 1090 | "version": "0.7.0", 1091 | "resolved": "https://registry.npmjs.org/capnp-ts/-/capnp-ts-0.7.0.tgz", 1092 | "integrity": "sha512-XKxXAC3HVPv7r674zP0VC3RTXz+/JKhfyw94ljvF80yynK6VkTnqE3jMuN8b3dUVmmc43TjyxjW4KTsmB3c86g==", 1093 | "dev": true, 1094 | "dependencies": { 1095 | "debug": "^4.3.1", 1096 | "tslib": "^2.2.0" 1097 | } 1098 | }, 1099 | "node_modules/chai": { 1100 | "version": "5.1.2", 1101 | "resolved": "https://registry.npmjs.org/chai/-/chai-5.1.2.tgz", 1102 | "integrity": "sha512-aGtmf24DW6MLHHG5gCx4zaI3uBq3KRtxeVs0DjFH6Z0rDNbsvTxFASFvdj79pxjxZ8/5u3PIiN3IwEIQkiiuPw==", 1103 | "dev": true, 1104 | "dependencies": { 1105 | "assertion-error": "^2.0.1", 1106 | "check-error": "^2.1.1", 1107 | "deep-eql": "^5.0.1", 1108 | "loupe": "^3.1.0", 1109 | "pathval": "^2.0.0" 1110 | }, 1111 | "engines": { 1112 | "node": ">=12" 1113 | } 1114 | }, 1115 | "node_modules/check-error": { 1116 | "version": "2.1.1", 1117 | "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", 1118 | "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==", 1119 | "dev": true, 1120 | "engines": { 1121 | "node": ">= 16" 1122 | } 1123 | }, 1124 | "node_modules/chokidar": { 1125 | "version": "4.0.3", 1126 | "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", 1127 | "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", 1128 | "dev": true, 1129 | "dependencies": { 1130 | "readdirp": "^4.0.1" 1131 | }, 1132 | "engines": { 1133 | "node": ">= 14.16.0" 1134 | }, 1135 | "funding": { 1136 | "url": "https://paulmillr.com/funding/" 1137 | } 1138 | }, 1139 | "node_modules/cjs-module-lexer": { 1140 | "version": "1.4.1", 1141 | "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.1.tgz", 1142 | "integrity": "sha512-cuSVIHi9/9E/+821Qjdvngor+xpnlwnuwIyZOaLmHBVdXL+gP+I6QQB9VkO7RI77YIcTV+S1W9AreJ5eN63JBA==", 1143 | "dev": true 1144 | }, 1145 | "node_modules/confbox": { 1146 | "version": "0.1.8", 1147 | "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz", 1148 | "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==", 1149 | "dev": true 1150 | }, 1151 | "node_modules/cookie": { 1152 | "version": "0.7.2", 1153 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", 1154 | "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", 1155 | "dev": true, 1156 | "engines": { 1157 | "node": ">= 0.6" 1158 | } 1159 | }, 1160 | "node_modules/data-uri-to-buffer": { 1161 | "version": "2.0.2", 1162 | "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-2.0.2.tgz", 1163 | "integrity": "sha512-ND9qDTLc6diwj+Xe5cdAgVTbLVdXbtxTJRXRhli8Mowuaan+0EJOtdqJ0QCHNSSPyoXGx9HX2/VMnKeC34AChA==", 1164 | "dev": true 1165 | }, 1166 | "node_modules/date-fns": { 1167 | "version": "4.1.0", 1168 | "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-4.1.0.tgz", 1169 | "integrity": "sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==", 1170 | "dev": true, 1171 | "funding": { 1172 | "type": "github", 1173 | "url": "https://github.com/sponsors/kossnocorp" 1174 | } 1175 | }, 1176 | "node_modules/debug": { 1177 | "version": "4.4.0", 1178 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", 1179 | "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", 1180 | "dev": true, 1181 | "dependencies": { 1182 | "ms": "^2.1.3" 1183 | }, 1184 | "engines": { 1185 | "node": ">=6.0" 1186 | }, 1187 | "peerDependenciesMeta": { 1188 | "supports-color": { 1189 | "optional": true 1190 | } 1191 | } 1192 | }, 1193 | "node_modules/deep-eql": { 1194 | "version": "5.0.2", 1195 | "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", 1196 | "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", 1197 | "dev": true, 1198 | "engines": { 1199 | "node": ">=6" 1200 | } 1201 | }, 1202 | "node_modules/defu": { 1203 | "version": "6.1.4", 1204 | "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.4.tgz", 1205 | "integrity": "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==", 1206 | "dev": true 1207 | }, 1208 | "node_modules/devalue": { 1209 | "version": "4.3.3", 1210 | "resolved": "https://registry.npmjs.org/devalue/-/devalue-4.3.3.tgz", 1211 | "integrity": "sha512-UH8EL6H2ifcY8TbD2QsxwCC/pr5xSwPvv85LrLXVihmHVC3T3YqTCIwnR5ak0yO1KYqlxrPVOA/JVZJYPy2ATg==", 1212 | "dev": true 1213 | }, 1214 | "node_modules/es-module-lexer": { 1215 | "version": "1.5.4", 1216 | "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz", 1217 | "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==", 1218 | "dev": true 1219 | }, 1220 | "node_modules/esbuild": { 1221 | "version": "0.17.19", 1222 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.19.tgz", 1223 | "integrity": "sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==", 1224 | "dev": true, 1225 | "hasInstallScript": true, 1226 | "bin": { 1227 | "esbuild": "bin/esbuild" 1228 | }, 1229 | "engines": { 1230 | "node": ">=12" 1231 | }, 1232 | "optionalDependencies": { 1233 | "@esbuild/android-arm": "0.17.19", 1234 | "@esbuild/android-arm64": "0.17.19", 1235 | "@esbuild/android-x64": "0.17.19", 1236 | "@esbuild/darwin-arm64": "0.17.19", 1237 | "@esbuild/darwin-x64": "0.17.19", 1238 | "@esbuild/freebsd-arm64": "0.17.19", 1239 | "@esbuild/freebsd-x64": "0.17.19", 1240 | "@esbuild/linux-arm": "0.17.19", 1241 | "@esbuild/linux-arm64": "0.17.19", 1242 | "@esbuild/linux-ia32": "0.17.19", 1243 | "@esbuild/linux-loong64": "0.17.19", 1244 | "@esbuild/linux-mips64el": "0.17.19", 1245 | "@esbuild/linux-ppc64": "0.17.19", 1246 | "@esbuild/linux-riscv64": "0.17.19", 1247 | "@esbuild/linux-s390x": "0.17.19", 1248 | "@esbuild/linux-x64": "0.17.19", 1249 | "@esbuild/netbsd-x64": "0.17.19", 1250 | "@esbuild/openbsd-x64": "0.17.19", 1251 | "@esbuild/sunos-x64": "0.17.19", 1252 | "@esbuild/win32-arm64": "0.17.19", 1253 | "@esbuild/win32-ia32": "0.17.19", 1254 | "@esbuild/win32-x64": "0.17.19" 1255 | } 1256 | }, 1257 | "node_modules/escape-string-regexp": { 1258 | "version": "4.0.0", 1259 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", 1260 | "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", 1261 | "dev": true, 1262 | "engines": { 1263 | "node": ">=10" 1264 | }, 1265 | "funding": { 1266 | "url": "https://github.com/sponsors/sindresorhus" 1267 | } 1268 | }, 1269 | "node_modules/estree-walker": { 1270 | "version": "3.0.3", 1271 | "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", 1272 | "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", 1273 | "dev": true, 1274 | "dependencies": { 1275 | "@types/estree": "^1.0.0" 1276 | } 1277 | }, 1278 | "node_modules/exit-hook": { 1279 | "version": "2.2.1", 1280 | "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-2.2.1.tgz", 1281 | "integrity": "sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw==", 1282 | "dev": true, 1283 | "engines": { 1284 | "node": ">=6" 1285 | }, 1286 | "funding": { 1287 | "url": "https://github.com/sponsors/sindresorhus" 1288 | } 1289 | }, 1290 | "node_modules/expect-type": { 1291 | "version": "1.1.0", 1292 | "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.1.0.tgz", 1293 | "integrity": "sha512-bFi65yM+xZgk+u/KRIpekdSYkTB5W1pEf0Lt8Q8Msh7b+eQ7LXVtIB1Bkm4fvclDEL1b2CZkMhv2mOeF8tMdkA==", 1294 | "dev": true, 1295 | "engines": { 1296 | "node": ">=12.0.0" 1297 | } 1298 | }, 1299 | "node_modules/fsevents": { 1300 | "version": "2.3.3", 1301 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", 1302 | "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", 1303 | "dev": true, 1304 | "hasInstallScript": true, 1305 | "optional": true, 1306 | "os": [ 1307 | "darwin" 1308 | ], 1309 | "engines": { 1310 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0" 1311 | } 1312 | }, 1313 | "node_modules/function-bind": { 1314 | "version": "1.1.2", 1315 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", 1316 | "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", 1317 | "dev": true, 1318 | "funding": { 1319 | "url": "https://github.com/sponsors/ljharb" 1320 | } 1321 | }, 1322 | "node_modules/get-source": { 1323 | "version": "2.0.12", 1324 | "resolved": "https://registry.npmjs.org/get-source/-/get-source-2.0.12.tgz", 1325 | "integrity": "sha512-X5+4+iD+HoSeEED+uwrQ07BOQr0kEDFMVqqpBuI+RaZBpBpHCuXxo70bjar6f0b0u/DQJsJ7ssurpP0V60Az+w==", 1326 | "dev": true, 1327 | "dependencies": { 1328 | "data-uri-to-buffer": "^2.0.0", 1329 | "source-map": "^0.6.1" 1330 | } 1331 | }, 1332 | "node_modules/glob-to-regexp": { 1333 | "version": "0.4.1", 1334 | "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", 1335 | "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", 1336 | "dev": true 1337 | }, 1338 | "node_modules/hasown": { 1339 | "version": "2.0.2", 1340 | "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", 1341 | "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", 1342 | "dev": true, 1343 | "dependencies": { 1344 | "function-bind": "^1.1.2" 1345 | }, 1346 | "engines": { 1347 | "node": ">= 0.4" 1348 | } 1349 | }, 1350 | "node_modules/hono": { 1351 | "version": "4.6.13", 1352 | "resolved": "https://registry.npmjs.org/hono/-/hono-4.6.13.tgz", 1353 | "integrity": "sha512-haV0gaMdSjy9URCRN9hxBPlqHa7fMm/T72kAImIxvw4eQLbNz1rgjN4hHElLJSieDiNuiIAXC//cC6YGz2KCbg==", 1354 | "engines": { 1355 | "node": ">=16.9.0" 1356 | } 1357 | }, 1358 | "node_modules/is-core-module": { 1359 | "version": "2.16.1", 1360 | "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", 1361 | "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", 1362 | "dev": true, 1363 | "dependencies": { 1364 | "hasown": "^2.0.2" 1365 | }, 1366 | "engines": { 1367 | "node": ">= 0.4" 1368 | }, 1369 | "funding": { 1370 | "url": "https://github.com/sponsors/ljharb" 1371 | } 1372 | }, 1373 | "node_modules/itty-time": { 1374 | "version": "1.0.6", 1375 | "resolved": "https://registry.npmjs.org/itty-time/-/itty-time-1.0.6.tgz", 1376 | "integrity": "sha512-+P8IZaLLBtFv8hCkIjcymZOp4UJ+xW6bSlQsXGqrkmJh7vSiMFSlNne0mCYagEE0N7HDNR5jJBRxwN0oYv61Rw==", 1377 | "dev": true 1378 | }, 1379 | "node_modules/loupe": { 1380 | "version": "3.1.2", 1381 | "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.2.tgz", 1382 | "integrity": "sha512-23I4pFZHmAemUnz8WZXbYRSKYj801VDaNv9ETuMh7IrMc7VuVVSo+Z9iLE3ni30+U48iDWfi30d3twAXBYmnCg==", 1383 | "dev": true 1384 | }, 1385 | "node_modules/magic-string": { 1386 | "version": "0.30.15", 1387 | "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.15.tgz", 1388 | "integrity": "sha512-zXeaYRgZ6ldS1RJJUrMrYgNJ4fdwnyI6tVqoiIhyCyv5IVTK9BU8Ic2l253GGETQHxI4HNUwhJ3fjDhKqEoaAw==", 1389 | "dev": true, 1390 | "dependencies": { 1391 | "@jridgewell/sourcemap-codec": "^1.5.0" 1392 | } 1393 | }, 1394 | "node_modules/mime": { 1395 | "version": "3.0.0", 1396 | "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", 1397 | "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", 1398 | "dev": true, 1399 | "bin": { 1400 | "mime": "cli.js" 1401 | }, 1402 | "engines": { 1403 | "node": ">=10.0.0" 1404 | } 1405 | }, 1406 | "node_modules/miniflare": { 1407 | "version": "3.20241205.0", 1408 | "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20241205.0.tgz", 1409 | "integrity": "sha512-Z0cTtIf6ZrcAJ3SrOI9EUM3s4dkGhNeU6Ubl8sroYhsPVD+rtz3m5+p6McHFWCkcMff1o60X5XEKVTmkz0gbpA==", 1410 | "dev": true, 1411 | "dependencies": { 1412 | "@cspotcode/source-map-support": "0.8.1", 1413 | "acorn": "^8.8.0", 1414 | "acorn-walk": "^8.2.0", 1415 | "capnp-ts": "^0.7.0", 1416 | "exit-hook": "^2.2.1", 1417 | "glob-to-regexp": "^0.4.1", 1418 | "stoppable": "^1.1.0", 1419 | "undici": "^5.28.4", 1420 | "workerd": "1.20241205.0", 1421 | "ws": "^8.18.0", 1422 | "youch": "^3.2.2", 1423 | "zod": "^3.22.3" 1424 | }, 1425 | "bin": { 1426 | "miniflare": "bootstrap.js" 1427 | }, 1428 | "engines": { 1429 | "node": ">=16.13" 1430 | } 1431 | }, 1432 | "node_modules/mlly": { 1433 | "version": "1.7.4", 1434 | "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.4.tgz", 1435 | "integrity": "sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==", 1436 | "dev": true, 1437 | "dependencies": { 1438 | "acorn": "^8.14.0", 1439 | "pathe": "^2.0.1", 1440 | "pkg-types": "^1.3.0", 1441 | "ufo": "^1.5.4" 1442 | } 1443 | }, 1444 | "node_modules/mlly/node_modules/pathe": { 1445 | "version": "2.0.2", 1446 | "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.2.tgz", 1447 | "integrity": "sha512-15Ztpk+nov8DR524R4BF7uEuzESgzUEAV4Ah7CUMNGXdE5ELuvxElxGXndBl32vMSsWa1jpNf22Z+Er3sKwq+w==", 1448 | "dev": true 1449 | }, 1450 | "node_modules/ms": { 1451 | "version": "2.1.3", 1452 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 1453 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", 1454 | "dev": true 1455 | }, 1456 | "node_modules/mustache": { 1457 | "version": "4.2.0", 1458 | "resolved": "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz", 1459 | "integrity": "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==", 1460 | "dev": true, 1461 | "bin": { 1462 | "mustache": "bin/mustache" 1463 | } 1464 | }, 1465 | "node_modules/nanoid": { 1466 | "version": "3.3.8", 1467 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", 1468 | "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==", 1469 | "dev": true, 1470 | "funding": [ 1471 | { 1472 | "type": "github", 1473 | "url": "https://github.com/sponsors/ai" 1474 | } 1475 | ], 1476 | "bin": { 1477 | "nanoid": "bin/nanoid.cjs" 1478 | }, 1479 | "engines": { 1480 | "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" 1481 | } 1482 | }, 1483 | "node_modules/node-forge": { 1484 | "version": "1.3.1", 1485 | "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", 1486 | "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", 1487 | "dev": true, 1488 | "engines": { 1489 | "node": ">= 6.13.0" 1490 | } 1491 | }, 1492 | "node_modules/ohash": { 1493 | "version": "1.1.4", 1494 | "resolved": "https://registry.npmjs.org/ohash/-/ohash-1.1.4.tgz", 1495 | "integrity": "sha512-FlDryZAahJmEF3VR3w1KogSEdWX3WhA5GPakFx4J81kEAiHyLMpdLLElS8n8dfNadMgAne/MywcvmogzscVt4g==", 1496 | "dev": true 1497 | }, 1498 | "node_modules/path-parse": { 1499 | "version": "1.0.7", 1500 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", 1501 | "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", 1502 | "dev": true 1503 | }, 1504 | "node_modules/path-to-regexp": { 1505 | "version": "6.3.0", 1506 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz", 1507 | "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==", 1508 | "dev": true 1509 | }, 1510 | "node_modules/pathe": { 1511 | "version": "1.1.2", 1512 | "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", 1513 | "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", 1514 | "dev": true 1515 | }, 1516 | "node_modules/pathval": { 1517 | "version": "2.0.0", 1518 | "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.0.tgz", 1519 | "integrity": "sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==", 1520 | "dev": true, 1521 | "engines": { 1522 | "node": ">= 14.16" 1523 | } 1524 | }, 1525 | "node_modules/picocolors": { 1526 | "version": "1.1.1", 1527 | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", 1528 | "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", 1529 | "dev": true 1530 | }, 1531 | "node_modules/pkg-types": { 1532 | "version": "1.3.1", 1533 | "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz", 1534 | "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==", 1535 | "dev": true, 1536 | "dependencies": { 1537 | "confbox": "^0.1.8", 1538 | "mlly": "^1.7.4", 1539 | "pathe": "^2.0.1" 1540 | } 1541 | }, 1542 | "node_modules/pkg-types/node_modules/pathe": { 1543 | "version": "2.0.2", 1544 | "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.2.tgz", 1545 | "integrity": "sha512-15Ztpk+nov8DR524R4BF7uEuzESgzUEAV4Ah7CUMNGXdE5ELuvxElxGXndBl32vMSsWa1jpNf22Z+Er3sKwq+w==", 1546 | "dev": true 1547 | }, 1548 | "node_modules/postcss": { 1549 | "version": "8.4.49", 1550 | "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz", 1551 | "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==", 1552 | "dev": true, 1553 | "funding": [ 1554 | { 1555 | "type": "opencollective", 1556 | "url": "https://opencollective.com/postcss/" 1557 | }, 1558 | { 1559 | "type": "tidelift", 1560 | "url": "https://tidelift.com/funding/github/npm/postcss" 1561 | }, 1562 | { 1563 | "type": "github", 1564 | "url": "https://github.com/sponsors/ai" 1565 | } 1566 | ], 1567 | "dependencies": { 1568 | "nanoid": "^3.3.7", 1569 | "picocolors": "^1.1.1", 1570 | "source-map-js": "^1.2.1" 1571 | }, 1572 | "engines": { 1573 | "node": "^10 || ^12 || >=14" 1574 | } 1575 | }, 1576 | "node_modules/printable-characters": { 1577 | "version": "1.0.42", 1578 | "resolved": "https://registry.npmjs.org/printable-characters/-/printable-characters-1.0.42.tgz", 1579 | "integrity": "sha512-dKp+C4iXWK4vVYZmYSd0KBH5F/h1HoZRsbJ82AVKRO3PEo8L4lBS/vLwhVtpwwuYcoIsVY+1JYKR268yn480uQ==", 1580 | "dev": true 1581 | }, 1582 | "node_modules/readdirp": { 1583 | "version": "4.1.1", 1584 | "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.1.tgz", 1585 | "integrity": "sha512-h80JrZu/MHUZCyHu5ciuoI0+WxsCxzxJTILn6Fs8rxSnFPh+UVHYfeIxK1nVGugMqkfC4vJcBOYbkfkwYK0+gw==", 1586 | "dev": true, 1587 | "engines": { 1588 | "node": ">= 14.18.0" 1589 | }, 1590 | "funding": { 1591 | "type": "individual", 1592 | "url": "https://paulmillr.com/funding/" 1593 | } 1594 | }, 1595 | "node_modules/resolve": { 1596 | "version": "1.22.10", 1597 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", 1598 | "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", 1599 | "dev": true, 1600 | "dependencies": { 1601 | "is-core-module": "^2.16.0", 1602 | "path-parse": "^1.0.7", 1603 | "supports-preserve-symlinks-flag": "^1.0.0" 1604 | }, 1605 | "bin": { 1606 | "resolve": "bin/resolve" 1607 | }, 1608 | "engines": { 1609 | "node": ">= 0.4" 1610 | }, 1611 | "funding": { 1612 | "url": "https://github.com/sponsors/ljharb" 1613 | } 1614 | }, 1615 | "node_modules/rollup": { 1616 | "version": "4.28.1", 1617 | "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.28.1.tgz", 1618 | "integrity": "sha512-61fXYl/qNVinKmGSTHAZ6Yy8I3YIJC/r2m9feHo6SwVAVcLT5MPwOUFe7EuURA/4m0NR8lXG4BBXuo/IZEsjMg==", 1619 | "dev": true, 1620 | "dependencies": { 1621 | "@types/estree": "1.0.6" 1622 | }, 1623 | "bin": { 1624 | "rollup": "dist/bin/rollup" 1625 | }, 1626 | "engines": { 1627 | "node": ">=18.0.0", 1628 | "npm": ">=8.0.0" 1629 | }, 1630 | "optionalDependencies": { 1631 | "@rollup/rollup-android-arm-eabi": "4.28.1", 1632 | "@rollup/rollup-android-arm64": "4.28.1", 1633 | "@rollup/rollup-darwin-arm64": "4.28.1", 1634 | "@rollup/rollup-darwin-x64": "4.28.1", 1635 | "@rollup/rollup-freebsd-arm64": "4.28.1", 1636 | "@rollup/rollup-freebsd-x64": "4.28.1", 1637 | "@rollup/rollup-linux-arm-gnueabihf": "4.28.1", 1638 | "@rollup/rollup-linux-arm-musleabihf": "4.28.1", 1639 | "@rollup/rollup-linux-arm64-gnu": "4.28.1", 1640 | "@rollup/rollup-linux-arm64-musl": "4.28.1", 1641 | "@rollup/rollup-linux-loongarch64-gnu": "4.28.1", 1642 | "@rollup/rollup-linux-powerpc64le-gnu": "4.28.1", 1643 | "@rollup/rollup-linux-riscv64-gnu": "4.28.1", 1644 | "@rollup/rollup-linux-s390x-gnu": "4.28.1", 1645 | "@rollup/rollup-linux-x64-gnu": "4.28.1", 1646 | "@rollup/rollup-linux-x64-musl": "4.28.1", 1647 | "@rollup/rollup-win32-arm64-msvc": "4.28.1", 1648 | "@rollup/rollup-win32-ia32-msvc": "4.28.1", 1649 | "@rollup/rollup-win32-x64-msvc": "4.28.1", 1650 | "fsevents": "~2.3.2" 1651 | } 1652 | }, 1653 | "node_modules/rollup-plugin-inject": { 1654 | "version": "3.0.2", 1655 | "resolved": "https://registry.npmjs.org/rollup-plugin-inject/-/rollup-plugin-inject-3.0.2.tgz", 1656 | "integrity": "sha512-ptg9PQwzs3orn4jkgXJ74bfs5vYz1NCZlSQMBUA0wKcGp5i5pA1AO3fOUEte8enhGUC+iapTCzEWw2jEFFUO/w==", 1657 | "deprecated": "This package has been deprecated and is no longer maintained. Please use @rollup/plugin-inject.", 1658 | "dev": true, 1659 | "dependencies": { 1660 | "estree-walker": "^0.6.1", 1661 | "magic-string": "^0.25.3", 1662 | "rollup-pluginutils": "^2.8.1" 1663 | } 1664 | }, 1665 | "node_modules/rollup-plugin-inject/node_modules/estree-walker": { 1666 | "version": "0.6.1", 1667 | "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz", 1668 | "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==", 1669 | "dev": true 1670 | }, 1671 | "node_modules/rollup-plugin-inject/node_modules/magic-string": { 1672 | "version": "0.25.9", 1673 | "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", 1674 | "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", 1675 | "dev": true, 1676 | "dependencies": { 1677 | "sourcemap-codec": "^1.4.8" 1678 | } 1679 | }, 1680 | "node_modules/rollup-plugin-node-polyfills": { 1681 | "version": "0.2.1", 1682 | "resolved": "https://registry.npmjs.org/rollup-plugin-node-polyfills/-/rollup-plugin-node-polyfills-0.2.1.tgz", 1683 | "integrity": "sha512-4kCrKPTJ6sK4/gLL/U5QzVT8cxJcofO0OU74tnB19F40cmuAKSzH5/siithxlofFEjwvw1YAhPmbvGNA6jEroA==", 1684 | "dev": true, 1685 | "dependencies": { 1686 | "rollup-plugin-inject": "^3.0.0" 1687 | } 1688 | }, 1689 | "node_modules/rollup-pluginutils": { 1690 | "version": "2.8.2", 1691 | "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz", 1692 | "integrity": "sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==", 1693 | "dev": true, 1694 | "dependencies": { 1695 | "estree-walker": "^0.6.1" 1696 | } 1697 | }, 1698 | "node_modules/rollup-pluginutils/node_modules/estree-walker": { 1699 | "version": "0.6.1", 1700 | "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz", 1701 | "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==", 1702 | "dev": true 1703 | }, 1704 | "node_modules/selfsigned": { 1705 | "version": "2.4.1", 1706 | "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz", 1707 | "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", 1708 | "dev": true, 1709 | "dependencies": { 1710 | "@types/node-forge": "^1.3.0", 1711 | "node-forge": "^1" 1712 | }, 1713 | "engines": { 1714 | "node": ">=10" 1715 | } 1716 | }, 1717 | "node_modules/semver": { 1718 | "version": "7.6.3", 1719 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", 1720 | "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", 1721 | "dev": true, 1722 | "bin": { 1723 | "semver": "bin/semver.js" 1724 | }, 1725 | "engines": { 1726 | "node": ">=10" 1727 | } 1728 | }, 1729 | "node_modules/siginfo": { 1730 | "version": "2.0.0", 1731 | "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", 1732 | "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", 1733 | "dev": true 1734 | }, 1735 | "node_modules/source-map": { 1736 | "version": "0.6.1", 1737 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", 1738 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", 1739 | "dev": true, 1740 | "engines": { 1741 | "node": ">=0.10.0" 1742 | } 1743 | }, 1744 | "node_modules/source-map-js": { 1745 | "version": "1.2.1", 1746 | "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", 1747 | "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", 1748 | "dev": true, 1749 | "engines": { 1750 | "node": ">=0.10.0" 1751 | } 1752 | }, 1753 | "node_modules/sourcemap-codec": { 1754 | "version": "1.4.8", 1755 | "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", 1756 | "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", 1757 | "deprecated": "Please use @jridgewell/sourcemap-codec instead", 1758 | "dev": true 1759 | }, 1760 | "node_modules/stackback": { 1761 | "version": "0.0.2", 1762 | "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", 1763 | "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", 1764 | "dev": true 1765 | }, 1766 | "node_modules/stacktracey": { 1767 | "version": "2.1.8", 1768 | "resolved": "https://registry.npmjs.org/stacktracey/-/stacktracey-2.1.8.tgz", 1769 | "integrity": "sha512-Kpij9riA+UNg7TnphqjH7/CzctQ/owJGNbFkfEeve4Z4uxT5+JapVLFXcsurIfN34gnTWZNJ/f7NMG0E8JDzTw==", 1770 | "dev": true, 1771 | "dependencies": { 1772 | "as-table": "^1.0.36", 1773 | "get-source": "^2.0.12" 1774 | } 1775 | }, 1776 | "node_modules/std-env": { 1777 | "version": "3.8.0", 1778 | "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.8.0.tgz", 1779 | "integrity": "sha512-Bc3YwwCB+OzldMxOXJIIvC6cPRWr/LxOp48CdQTOkPyk/t4JWWJbrilwBd7RJzKV8QW7tJkcgAmeuLLJugl5/w==", 1780 | "dev": true 1781 | }, 1782 | "node_modules/stoppable": { 1783 | "version": "1.1.0", 1784 | "resolved": "https://registry.npmjs.org/stoppable/-/stoppable-1.1.0.tgz", 1785 | "integrity": "sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==", 1786 | "dev": true, 1787 | "engines": { 1788 | "node": ">=4", 1789 | "npm": ">=6" 1790 | } 1791 | }, 1792 | "node_modules/supports-preserve-symlinks-flag": { 1793 | "version": "1.0.0", 1794 | "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", 1795 | "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", 1796 | "dev": true, 1797 | "engines": { 1798 | "node": ">= 0.4" 1799 | }, 1800 | "funding": { 1801 | "url": "https://github.com/sponsors/ljharb" 1802 | } 1803 | }, 1804 | "node_modules/tinybench": { 1805 | "version": "2.9.0", 1806 | "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", 1807 | "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", 1808 | "dev": true 1809 | }, 1810 | "node_modules/tinyexec": { 1811 | "version": "0.3.1", 1812 | "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.1.tgz", 1813 | "integrity": "sha512-WiCJLEECkO18gwqIp6+hJg0//p23HXp4S+gGtAKu3mI2F2/sXC4FvHvXvB0zJVVaTPhx1/tOwdbRsa1sOBIKqQ==", 1814 | "dev": true 1815 | }, 1816 | "node_modules/tinypool": { 1817 | "version": "1.0.2", 1818 | "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.0.2.tgz", 1819 | "integrity": "sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA==", 1820 | "dev": true, 1821 | "engines": { 1822 | "node": "^18.0.0 || >=20.0.0" 1823 | } 1824 | }, 1825 | "node_modules/tinyrainbow": { 1826 | "version": "1.2.0", 1827 | "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-1.2.0.tgz", 1828 | "integrity": "sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==", 1829 | "dev": true, 1830 | "engines": { 1831 | "node": ">=14.0.0" 1832 | } 1833 | }, 1834 | "node_modules/tinyspy": { 1835 | "version": "3.0.2", 1836 | "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-3.0.2.tgz", 1837 | "integrity": "sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==", 1838 | "dev": true, 1839 | "engines": { 1840 | "node": ">=14.0.0" 1841 | } 1842 | }, 1843 | "node_modules/tslib": { 1844 | "version": "2.8.1", 1845 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", 1846 | "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", 1847 | "dev": true 1848 | }, 1849 | "node_modules/typescript": { 1850 | "version": "5.7.2", 1851 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz", 1852 | "integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==", 1853 | "dev": true, 1854 | "bin": { 1855 | "tsc": "bin/tsc", 1856 | "tsserver": "bin/tsserver" 1857 | }, 1858 | "engines": { 1859 | "node": ">=14.17" 1860 | } 1861 | }, 1862 | "node_modules/ufo": { 1863 | "version": "1.5.4", 1864 | "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.4.tgz", 1865 | "integrity": "sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==", 1866 | "dev": true 1867 | }, 1868 | "node_modules/undici": { 1869 | "version": "5.28.4", 1870 | "resolved": "https://registry.npmjs.org/undici/-/undici-5.28.4.tgz", 1871 | "integrity": "sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==", 1872 | "dev": true, 1873 | "dependencies": { 1874 | "@fastify/busboy": "^2.0.0" 1875 | }, 1876 | "engines": { 1877 | "node": ">=14.0" 1878 | } 1879 | }, 1880 | "node_modules/undici-types": { 1881 | "version": "6.20.0", 1882 | "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", 1883 | "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", 1884 | "dev": true 1885 | }, 1886 | "node_modules/unenv": { 1887 | "version": "2.0.0-rc.1", 1888 | "resolved": "https://registry.npmjs.org/unenv/-/unenv-2.0.0-rc.1.tgz", 1889 | "integrity": "sha512-PU5fb40H8X149s117aB4ytbORcCvlASdtF97tfls4BPIyj4PeVxvpSuy1jAptqYHqB0vb2w2sHvzM0XWcp2OKg==", 1890 | "dev": true, 1891 | "dependencies": { 1892 | "defu": "^6.1.4", 1893 | "mlly": "^1.7.4", 1894 | "ohash": "^1.1.4", 1895 | "pathe": "^1.1.2", 1896 | "ufo": "^1.5.4" 1897 | } 1898 | }, 1899 | "node_modules/vite": { 1900 | "version": "5.4.11", 1901 | "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.11.tgz", 1902 | "integrity": "sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q==", 1903 | "dev": true, 1904 | "dependencies": { 1905 | "esbuild": "^0.21.3", 1906 | "postcss": "^8.4.43", 1907 | "rollup": "^4.20.0" 1908 | }, 1909 | "bin": { 1910 | "vite": "bin/vite.js" 1911 | }, 1912 | "engines": { 1913 | "node": "^18.0.0 || >=20.0.0" 1914 | }, 1915 | "funding": { 1916 | "url": "https://github.com/vitejs/vite?sponsor=1" 1917 | }, 1918 | "optionalDependencies": { 1919 | "fsevents": "~2.3.3" 1920 | }, 1921 | "peerDependencies": { 1922 | "@types/node": "^18.0.0 || >=20.0.0", 1923 | "less": "*", 1924 | "lightningcss": "^1.21.0", 1925 | "sass": "*", 1926 | "sass-embedded": "*", 1927 | "stylus": "*", 1928 | "sugarss": "*", 1929 | "terser": "^5.4.0" 1930 | }, 1931 | "peerDependenciesMeta": { 1932 | "@types/node": { 1933 | "optional": true 1934 | }, 1935 | "less": { 1936 | "optional": true 1937 | }, 1938 | "lightningcss": { 1939 | "optional": true 1940 | }, 1941 | "sass": { 1942 | "optional": true 1943 | }, 1944 | "sass-embedded": { 1945 | "optional": true 1946 | }, 1947 | "stylus": { 1948 | "optional": true 1949 | }, 1950 | "sugarss": { 1951 | "optional": true 1952 | }, 1953 | "terser": { 1954 | "optional": true 1955 | } 1956 | } 1957 | }, 1958 | "node_modules/vite-node": { 1959 | "version": "2.1.8", 1960 | "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-2.1.8.tgz", 1961 | "integrity": "sha512-uPAwSr57kYjAUux+8E2j0q0Fxpn8M9VoyfGiRI8Kfktz9NcYMCenwY5RnZxnF1WTu3TGiYipirIzacLL3VVGFg==", 1962 | "dev": true, 1963 | "dependencies": { 1964 | "cac": "^6.7.14", 1965 | "debug": "^4.3.7", 1966 | "es-module-lexer": "^1.5.4", 1967 | "pathe": "^1.1.2", 1968 | "vite": "^5.0.0" 1969 | }, 1970 | "bin": { 1971 | "vite-node": "vite-node.mjs" 1972 | }, 1973 | "engines": { 1974 | "node": "^18.0.0 || >=20.0.0" 1975 | }, 1976 | "funding": { 1977 | "url": "https://opencollective.com/vitest" 1978 | } 1979 | }, 1980 | "node_modules/vite/node_modules/@esbuild/android-arm": { 1981 | "version": "0.21.5", 1982 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", 1983 | "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", 1984 | "cpu": [ 1985 | "arm" 1986 | ], 1987 | "dev": true, 1988 | "optional": true, 1989 | "os": [ 1990 | "android" 1991 | ], 1992 | "engines": { 1993 | "node": ">=12" 1994 | } 1995 | }, 1996 | "node_modules/vite/node_modules/@esbuild/android-arm64": { 1997 | "version": "0.21.5", 1998 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", 1999 | "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", 2000 | "cpu": [ 2001 | "arm64" 2002 | ], 2003 | "dev": true, 2004 | "optional": true, 2005 | "os": [ 2006 | "android" 2007 | ], 2008 | "engines": { 2009 | "node": ">=12" 2010 | } 2011 | }, 2012 | "node_modules/vite/node_modules/@esbuild/android-x64": { 2013 | "version": "0.21.5", 2014 | "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", 2015 | "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", 2016 | "cpu": [ 2017 | "x64" 2018 | ], 2019 | "dev": true, 2020 | "optional": true, 2021 | "os": [ 2022 | "android" 2023 | ], 2024 | "engines": { 2025 | "node": ">=12" 2026 | } 2027 | }, 2028 | "node_modules/vite/node_modules/@esbuild/darwin-arm64": { 2029 | "version": "0.21.5", 2030 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", 2031 | "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", 2032 | "cpu": [ 2033 | "arm64" 2034 | ], 2035 | "dev": true, 2036 | "optional": true, 2037 | "os": [ 2038 | "darwin" 2039 | ], 2040 | "engines": { 2041 | "node": ">=12" 2042 | } 2043 | }, 2044 | "node_modules/vite/node_modules/@esbuild/darwin-x64": { 2045 | "version": "0.21.5", 2046 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", 2047 | "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", 2048 | "cpu": [ 2049 | "x64" 2050 | ], 2051 | "dev": true, 2052 | "optional": true, 2053 | "os": [ 2054 | "darwin" 2055 | ], 2056 | "engines": { 2057 | "node": ">=12" 2058 | } 2059 | }, 2060 | "node_modules/vite/node_modules/@esbuild/freebsd-arm64": { 2061 | "version": "0.21.5", 2062 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", 2063 | "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", 2064 | "cpu": [ 2065 | "arm64" 2066 | ], 2067 | "dev": true, 2068 | "optional": true, 2069 | "os": [ 2070 | "freebsd" 2071 | ], 2072 | "engines": { 2073 | "node": ">=12" 2074 | } 2075 | }, 2076 | "node_modules/vite/node_modules/@esbuild/freebsd-x64": { 2077 | "version": "0.21.5", 2078 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", 2079 | "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", 2080 | "cpu": [ 2081 | "x64" 2082 | ], 2083 | "dev": true, 2084 | "optional": true, 2085 | "os": [ 2086 | "freebsd" 2087 | ], 2088 | "engines": { 2089 | "node": ">=12" 2090 | } 2091 | }, 2092 | "node_modules/vite/node_modules/@esbuild/linux-arm": { 2093 | "version": "0.21.5", 2094 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", 2095 | "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", 2096 | "cpu": [ 2097 | "arm" 2098 | ], 2099 | "dev": true, 2100 | "optional": true, 2101 | "os": [ 2102 | "linux" 2103 | ], 2104 | "engines": { 2105 | "node": ">=12" 2106 | } 2107 | }, 2108 | "node_modules/vite/node_modules/@esbuild/linux-arm64": { 2109 | "version": "0.21.5", 2110 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", 2111 | "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", 2112 | "cpu": [ 2113 | "arm64" 2114 | ], 2115 | "dev": true, 2116 | "optional": true, 2117 | "os": [ 2118 | "linux" 2119 | ], 2120 | "engines": { 2121 | "node": ">=12" 2122 | } 2123 | }, 2124 | "node_modules/vite/node_modules/@esbuild/linux-ia32": { 2125 | "version": "0.21.5", 2126 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", 2127 | "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", 2128 | "cpu": [ 2129 | "ia32" 2130 | ], 2131 | "dev": true, 2132 | "optional": true, 2133 | "os": [ 2134 | "linux" 2135 | ], 2136 | "engines": { 2137 | "node": ">=12" 2138 | } 2139 | }, 2140 | "node_modules/vite/node_modules/@esbuild/linux-loong64": { 2141 | "version": "0.21.5", 2142 | "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", 2143 | "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", 2144 | "cpu": [ 2145 | "loong64" 2146 | ], 2147 | "dev": true, 2148 | "optional": true, 2149 | "os": [ 2150 | "linux" 2151 | ], 2152 | "engines": { 2153 | "node": ">=12" 2154 | } 2155 | }, 2156 | "node_modules/vite/node_modules/@esbuild/linux-mips64el": { 2157 | "version": "0.21.5", 2158 | "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", 2159 | "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", 2160 | "cpu": [ 2161 | "mips64el" 2162 | ], 2163 | "dev": true, 2164 | "optional": true, 2165 | "os": [ 2166 | "linux" 2167 | ], 2168 | "engines": { 2169 | "node": ">=12" 2170 | } 2171 | }, 2172 | "node_modules/vite/node_modules/@esbuild/linux-ppc64": { 2173 | "version": "0.21.5", 2174 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", 2175 | "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", 2176 | "cpu": [ 2177 | "ppc64" 2178 | ], 2179 | "dev": true, 2180 | "optional": true, 2181 | "os": [ 2182 | "linux" 2183 | ], 2184 | "engines": { 2185 | "node": ">=12" 2186 | } 2187 | }, 2188 | "node_modules/vite/node_modules/@esbuild/linux-riscv64": { 2189 | "version": "0.21.5", 2190 | "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", 2191 | "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", 2192 | "cpu": [ 2193 | "riscv64" 2194 | ], 2195 | "dev": true, 2196 | "optional": true, 2197 | "os": [ 2198 | "linux" 2199 | ], 2200 | "engines": { 2201 | "node": ">=12" 2202 | } 2203 | }, 2204 | "node_modules/vite/node_modules/@esbuild/linux-s390x": { 2205 | "version": "0.21.5", 2206 | "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", 2207 | "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", 2208 | "cpu": [ 2209 | "s390x" 2210 | ], 2211 | "dev": true, 2212 | "optional": true, 2213 | "os": [ 2214 | "linux" 2215 | ], 2216 | "engines": { 2217 | "node": ">=12" 2218 | } 2219 | }, 2220 | "node_modules/vite/node_modules/@esbuild/linux-x64": { 2221 | "version": "0.21.5", 2222 | "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", 2223 | "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", 2224 | "cpu": [ 2225 | "x64" 2226 | ], 2227 | "dev": true, 2228 | "optional": true, 2229 | "os": [ 2230 | "linux" 2231 | ], 2232 | "engines": { 2233 | "node": ">=12" 2234 | } 2235 | }, 2236 | "node_modules/vite/node_modules/@esbuild/netbsd-x64": { 2237 | "version": "0.21.5", 2238 | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", 2239 | "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", 2240 | "cpu": [ 2241 | "x64" 2242 | ], 2243 | "dev": true, 2244 | "optional": true, 2245 | "os": [ 2246 | "netbsd" 2247 | ], 2248 | "engines": { 2249 | "node": ">=12" 2250 | } 2251 | }, 2252 | "node_modules/vite/node_modules/@esbuild/openbsd-x64": { 2253 | "version": "0.21.5", 2254 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", 2255 | "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", 2256 | "cpu": [ 2257 | "x64" 2258 | ], 2259 | "dev": true, 2260 | "optional": true, 2261 | "os": [ 2262 | "openbsd" 2263 | ], 2264 | "engines": { 2265 | "node": ">=12" 2266 | } 2267 | }, 2268 | "node_modules/vite/node_modules/@esbuild/sunos-x64": { 2269 | "version": "0.21.5", 2270 | "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", 2271 | "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", 2272 | "cpu": [ 2273 | "x64" 2274 | ], 2275 | "dev": true, 2276 | "optional": true, 2277 | "os": [ 2278 | "sunos" 2279 | ], 2280 | "engines": { 2281 | "node": ">=12" 2282 | } 2283 | }, 2284 | "node_modules/vite/node_modules/@esbuild/win32-arm64": { 2285 | "version": "0.21.5", 2286 | "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", 2287 | "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", 2288 | "cpu": [ 2289 | "arm64" 2290 | ], 2291 | "dev": true, 2292 | "optional": true, 2293 | "os": [ 2294 | "win32" 2295 | ], 2296 | "engines": { 2297 | "node": ">=12" 2298 | } 2299 | }, 2300 | "node_modules/vite/node_modules/@esbuild/win32-ia32": { 2301 | "version": "0.21.5", 2302 | "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", 2303 | "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", 2304 | "cpu": [ 2305 | "ia32" 2306 | ], 2307 | "dev": true, 2308 | "optional": true, 2309 | "os": [ 2310 | "win32" 2311 | ], 2312 | "engines": { 2313 | "node": ">=12" 2314 | } 2315 | }, 2316 | "node_modules/vite/node_modules/@esbuild/win32-x64": { 2317 | "version": "0.21.5", 2318 | "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", 2319 | "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", 2320 | "cpu": [ 2321 | "x64" 2322 | ], 2323 | "dev": true, 2324 | "optional": true, 2325 | "os": [ 2326 | "win32" 2327 | ], 2328 | "engines": { 2329 | "node": ">=12" 2330 | } 2331 | }, 2332 | "node_modules/vite/node_modules/esbuild": { 2333 | "version": "0.21.5", 2334 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", 2335 | "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", 2336 | "dev": true, 2337 | "hasInstallScript": true, 2338 | "bin": { 2339 | "esbuild": "bin/esbuild" 2340 | }, 2341 | "engines": { 2342 | "node": ">=12" 2343 | }, 2344 | "optionalDependencies": { 2345 | "@esbuild/aix-ppc64": "0.21.5", 2346 | "@esbuild/android-arm": "0.21.5", 2347 | "@esbuild/android-arm64": "0.21.5", 2348 | "@esbuild/android-x64": "0.21.5", 2349 | "@esbuild/darwin-arm64": "0.21.5", 2350 | "@esbuild/darwin-x64": "0.21.5", 2351 | "@esbuild/freebsd-arm64": "0.21.5", 2352 | "@esbuild/freebsd-x64": "0.21.5", 2353 | "@esbuild/linux-arm": "0.21.5", 2354 | "@esbuild/linux-arm64": "0.21.5", 2355 | "@esbuild/linux-ia32": "0.21.5", 2356 | "@esbuild/linux-loong64": "0.21.5", 2357 | "@esbuild/linux-mips64el": "0.21.5", 2358 | "@esbuild/linux-ppc64": "0.21.5", 2359 | "@esbuild/linux-riscv64": "0.21.5", 2360 | "@esbuild/linux-s390x": "0.21.5", 2361 | "@esbuild/linux-x64": "0.21.5", 2362 | "@esbuild/netbsd-x64": "0.21.5", 2363 | "@esbuild/openbsd-x64": "0.21.5", 2364 | "@esbuild/sunos-x64": "0.21.5", 2365 | "@esbuild/win32-arm64": "0.21.5", 2366 | "@esbuild/win32-ia32": "0.21.5", 2367 | "@esbuild/win32-x64": "0.21.5" 2368 | } 2369 | }, 2370 | "node_modules/vitest": { 2371 | "version": "2.1.8", 2372 | "resolved": "https://registry.npmjs.org/vitest/-/vitest-2.1.8.tgz", 2373 | "integrity": "sha512-1vBKTZskHw/aosXqQUlVWWlGUxSJR8YtiyZDJAFeW2kPAeX6S3Sool0mjspO+kXLuxVWlEDDowBAeqeAQefqLQ==", 2374 | "dev": true, 2375 | "dependencies": { 2376 | "@vitest/expect": "2.1.8", 2377 | "@vitest/mocker": "2.1.8", 2378 | "@vitest/pretty-format": "^2.1.8", 2379 | "@vitest/runner": "2.1.8", 2380 | "@vitest/snapshot": "2.1.8", 2381 | "@vitest/spy": "2.1.8", 2382 | "@vitest/utils": "2.1.8", 2383 | "chai": "^5.1.2", 2384 | "debug": "^4.3.7", 2385 | "expect-type": "^1.1.0", 2386 | "magic-string": "^0.30.12", 2387 | "pathe": "^1.1.2", 2388 | "std-env": "^3.8.0", 2389 | "tinybench": "^2.9.0", 2390 | "tinyexec": "^0.3.1", 2391 | "tinypool": "^1.0.1", 2392 | "tinyrainbow": "^1.2.0", 2393 | "vite": "^5.0.0", 2394 | "vite-node": "2.1.8", 2395 | "why-is-node-running": "^2.3.0" 2396 | }, 2397 | "bin": { 2398 | "vitest": "vitest.mjs" 2399 | }, 2400 | "engines": { 2401 | "node": "^18.0.0 || >=20.0.0" 2402 | }, 2403 | "funding": { 2404 | "url": "https://opencollective.com/vitest" 2405 | }, 2406 | "peerDependencies": { 2407 | "@edge-runtime/vm": "*", 2408 | "@types/node": "^18.0.0 || >=20.0.0", 2409 | "@vitest/browser": "2.1.8", 2410 | "@vitest/ui": "2.1.8", 2411 | "happy-dom": "*", 2412 | "jsdom": "*" 2413 | }, 2414 | "peerDependenciesMeta": { 2415 | "@edge-runtime/vm": { 2416 | "optional": true 2417 | }, 2418 | "@types/node": { 2419 | "optional": true 2420 | }, 2421 | "@vitest/browser": { 2422 | "optional": true 2423 | }, 2424 | "@vitest/ui": { 2425 | "optional": true 2426 | }, 2427 | "happy-dom": { 2428 | "optional": true 2429 | }, 2430 | "jsdom": { 2431 | "optional": true 2432 | } 2433 | } 2434 | }, 2435 | "node_modules/why-is-node-running": { 2436 | "version": "2.3.0", 2437 | "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", 2438 | "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", 2439 | "dev": true, 2440 | "dependencies": { 2441 | "siginfo": "^2.0.0", 2442 | "stackback": "0.0.2" 2443 | }, 2444 | "bin": { 2445 | "why-is-node-running": "cli.js" 2446 | }, 2447 | "engines": { 2448 | "node": ">=8" 2449 | } 2450 | }, 2451 | "node_modules/workerd": { 2452 | "version": "1.20241205.0", 2453 | "resolved": "https://registry.npmjs.org/workerd/-/workerd-1.20241205.0.tgz", 2454 | "integrity": "sha512-vso/2n0c5SdBDWiD+Sx5gM7unA6SiZXRVUHDqH1euoP/9mFVHZF8icoYsNLB87b/TX8zNgpae+I5N/xFpd9v0g==", 2455 | "dev": true, 2456 | "hasInstallScript": true, 2457 | "bin": { 2458 | "workerd": "bin/workerd" 2459 | }, 2460 | "engines": { 2461 | "node": ">=16" 2462 | }, 2463 | "optionalDependencies": { 2464 | "@cloudflare/workerd-darwin-64": "1.20241205.0", 2465 | "@cloudflare/workerd-darwin-arm64": "1.20241205.0", 2466 | "@cloudflare/workerd-linux-64": "1.20241205.0", 2467 | "@cloudflare/workerd-linux-arm64": "1.20241205.0", 2468 | "@cloudflare/workerd-windows-64": "1.20241205.0" 2469 | } 2470 | }, 2471 | "node_modules/wrangler": { 2472 | "version": "3.107.3", 2473 | "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-3.107.3.tgz", 2474 | "integrity": "sha512-N9ZMDHZ+DI5/B0yclr3bG57U/Zw7wSzGdpO2l7j6+3q8yUf+4Fk0Rvneo2t8rjLewKlvqgt9D9siFuo8MXJ55Q==", 2475 | "dev": true, 2476 | "dependencies": { 2477 | "@cloudflare/kv-asset-handler": "0.3.4", 2478 | "@esbuild-plugins/node-globals-polyfill": "0.2.3", 2479 | "@esbuild-plugins/node-modules-polyfill": "0.2.2", 2480 | "blake3-wasm": "2.1.5", 2481 | "esbuild": "0.17.19", 2482 | "miniflare": "3.20250129.0", 2483 | "path-to-regexp": "6.3.0", 2484 | "unenv": "2.0.0-rc.1", 2485 | "workerd": "1.20250129.0" 2486 | }, 2487 | "bin": { 2488 | "wrangler": "bin/wrangler.js", 2489 | "wrangler2": "bin/wrangler.js" 2490 | }, 2491 | "engines": { 2492 | "node": ">=16.17.0" 2493 | }, 2494 | "optionalDependencies": { 2495 | "fsevents": "~2.3.2" 2496 | }, 2497 | "peerDependencies": { 2498 | "@cloudflare/workers-types": "^4.20250129.0" 2499 | }, 2500 | "peerDependenciesMeta": { 2501 | "@cloudflare/workers-types": { 2502 | "optional": true 2503 | } 2504 | } 2505 | }, 2506 | "node_modules/wrangler/node_modules/@cloudflare/workerd-darwin-64": { 2507 | "version": "1.20250129.0", 2508 | "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20250129.0.tgz", 2509 | "integrity": "sha512-M+xETVnl+xy2dfDDWmp0XXr2rttl70a6bljQygl0EmYmNswFTcYbQWCaBuNBo9kabU59rLKr4a/b3QZ07NoL/g==", 2510 | "cpu": [ 2511 | "x64" 2512 | ], 2513 | "dev": true, 2514 | "optional": true, 2515 | "os": [ 2516 | "darwin" 2517 | ], 2518 | "engines": { 2519 | "node": ">=16" 2520 | } 2521 | }, 2522 | "node_modules/wrangler/node_modules/@cloudflare/workerd-darwin-arm64": { 2523 | "version": "1.20250129.0", 2524 | "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20250129.0.tgz", 2525 | "integrity": "sha512-c4PQUyIMp+bCMxZkAMBzXgTHjRZxeYCujDbb3staestqgRbenzcfauXsMd6np35ng+EE1uBgHNPV4+7fC0ZBfg==", 2526 | "cpu": [ 2527 | "arm64" 2528 | ], 2529 | "dev": true, 2530 | "optional": true, 2531 | "os": [ 2532 | "darwin" 2533 | ], 2534 | "engines": { 2535 | "node": ">=16" 2536 | } 2537 | }, 2538 | "node_modules/wrangler/node_modules/@cloudflare/workerd-linux-64": { 2539 | "version": "1.20250129.0", 2540 | "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20250129.0.tgz", 2541 | "integrity": "sha512-xJx8LwWFxsm5U3DETJwRuOmT5RWBqm4FmA4itYXvcEICca9pWJDB641kT4PnpypwDNmYOebhU7A+JUrCRucG0w==", 2542 | "cpu": [ 2543 | "x64" 2544 | ], 2545 | "dev": true, 2546 | "optional": true, 2547 | "os": [ 2548 | "linux" 2549 | ], 2550 | "engines": { 2551 | "node": ">=16" 2552 | } 2553 | }, 2554 | "node_modules/wrangler/node_modules/@cloudflare/workerd-linux-arm64": { 2555 | "version": "1.20250129.0", 2556 | "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20250129.0.tgz", 2557 | "integrity": "sha512-dR//npbaX5p323huBVNIy5gaWubQx6CC3aiXeK0yX4aD5ar8AjxQFb2U/Sgjeo65Rkt53hJWqC7IwRpK/eOxrA==", 2558 | "cpu": [ 2559 | "arm64" 2560 | ], 2561 | "dev": true, 2562 | "optional": true, 2563 | "os": [ 2564 | "linux" 2565 | ], 2566 | "engines": { 2567 | "node": ">=16" 2568 | } 2569 | }, 2570 | "node_modules/wrangler/node_modules/@cloudflare/workerd-windows-64": { 2571 | "version": "1.20250129.0", 2572 | "resolved": "https://registry.npmjs.org/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20250129.0.tgz", 2573 | "integrity": "sha512-OeO+1nPj/ocAE3adFar/tRFGRkbCrBnrOYXq0FUBSpyNHpDdA9/U3PAw5CN4zvjfTnqXZfTxTFeqoruqzRzbtg==", 2574 | "cpu": [ 2575 | "x64" 2576 | ], 2577 | "dev": true, 2578 | "optional": true, 2579 | "os": [ 2580 | "win32" 2581 | ], 2582 | "engines": { 2583 | "node": ">=16" 2584 | } 2585 | }, 2586 | "node_modules/wrangler/node_modules/miniflare": { 2587 | "version": "3.20250129.0", 2588 | "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-3.20250129.0.tgz", 2589 | "integrity": "sha512-qYlGEjMl/2kJdgNaztj4hpA64d6Dl79Lx/NL61p/v5XZRiWanBOTgkQqdPxCKZOj6KQnioqhC7lfd6jDXKSs2A==", 2590 | "dev": true, 2591 | "dependencies": { 2592 | "@cspotcode/source-map-support": "0.8.1", 2593 | "acorn": "^8.8.0", 2594 | "acorn-walk": "^8.2.0", 2595 | "exit-hook": "^2.2.1", 2596 | "glob-to-regexp": "^0.4.1", 2597 | "stoppable": "^1.1.0", 2598 | "undici": "^5.28.4", 2599 | "workerd": "1.20250129.0", 2600 | "ws": "^8.18.0", 2601 | "youch": "^3.2.2", 2602 | "zod": "^3.22.3" 2603 | }, 2604 | "bin": { 2605 | "miniflare": "bootstrap.js" 2606 | }, 2607 | "engines": { 2608 | "node": ">=16.13" 2609 | } 2610 | }, 2611 | "node_modules/wrangler/node_modules/workerd": { 2612 | "version": "1.20250129.0", 2613 | "resolved": "https://registry.npmjs.org/workerd/-/workerd-1.20250129.0.tgz", 2614 | "integrity": "sha512-Rprz8rxKTF4l6q/nYYI07lBetJnR19mGipx+u/a27GZOPKMG5SLIzA2NciZlJaB2Qd5YY+4p/eHOeKqo5keVWA==", 2615 | "dev": true, 2616 | "hasInstallScript": true, 2617 | "bin": { 2618 | "workerd": "bin/workerd" 2619 | }, 2620 | "engines": { 2621 | "node": ">=16" 2622 | }, 2623 | "optionalDependencies": { 2624 | "@cloudflare/workerd-darwin-64": "1.20250129.0", 2625 | "@cloudflare/workerd-darwin-arm64": "1.20250129.0", 2626 | "@cloudflare/workerd-linux-64": "1.20250129.0", 2627 | "@cloudflare/workerd-linux-arm64": "1.20250129.0", 2628 | "@cloudflare/workerd-windows-64": "1.20250129.0" 2629 | } 2630 | }, 2631 | "node_modules/ws": { 2632 | "version": "8.18.0", 2633 | "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", 2634 | "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", 2635 | "dev": true, 2636 | "engines": { 2637 | "node": ">=10.0.0" 2638 | }, 2639 | "peerDependencies": { 2640 | "bufferutil": "^4.0.1", 2641 | "utf-8-validate": ">=5.0.2" 2642 | }, 2643 | "peerDependenciesMeta": { 2644 | "bufferutil": { 2645 | "optional": true 2646 | }, 2647 | "utf-8-validate": { 2648 | "optional": true 2649 | } 2650 | } 2651 | }, 2652 | "node_modules/xxhash-wasm": { 2653 | "version": "1.1.0", 2654 | "resolved": "https://registry.npmjs.org/xxhash-wasm/-/xxhash-wasm-1.1.0.tgz", 2655 | "integrity": "sha512-147y/6YNh+tlp6nd/2pWq38i9h6mz/EuQ6njIrmW8D1BS5nCqs0P6DG+m6zTGnNz5I+uhZ0SHxBs9BsPrwcKDA==", 2656 | "dev": true 2657 | }, 2658 | "node_modules/youch": { 2659 | "version": "3.3.4", 2660 | "resolved": "https://registry.npmjs.org/youch/-/youch-3.3.4.tgz", 2661 | "integrity": "sha512-UeVBXie8cA35DS6+nBkls68xaBBXCye0CNznrhszZjTbRVnJKQuNsyLKBTTL4ln1o1rh2PKtv35twV7irj5SEg==", 2662 | "dev": true, 2663 | "dependencies": { 2664 | "cookie": "^0.7.1", 2665 | "mustache": "^4.2.0", 2666 | "stacktracey": "^2.1.8" 2667 | } 2668 | }, 2669 | "node_modules/zod": { 2670 | "version": "3.24.0", 2671 | "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.0.tgz", 2672 | "integrity": "sha512-Hz+wiY8yD0VLA2k/+nsg2Abez674dDGTai33SwNvMPuf9uIrBC9eFgIMQxBBbHFxVXi8W+5nX9DcAh9YNSQm/w==", 2673 | "dev": true, 2674 | "funding": { 2675 | "url": "https://github.com/sponsors/colinhacks" 2676 | } 2677 | } 2678 | } 2679 | } 2680 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "talk-to-javascript", 3 | "version": "0.0.1", 4 | "private": true, 5 | "scripts": { 6 | "deploy": "wrangler deploy", 7 | "dev": "wrangler dev", 8 | "start": "wrangler dev", 9 | "test": "vitest", 10 | "cf-typegen": "wrangler types" 11 | }, 12 | "devDependencies": { 13 | "@cloudflare/vitest-pool-workers": "^0.5.2", 14 | "@cloudflare/workers-types": "^4.20241205.0", 15 | "typescript": "^5.5.2", 16 | "vitest": "2.1.8", 17 | "wrangler": "^3.107.3" 18 | }, 19 | "dependencies": { 20 | "hono": "^4.6.13" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /public/hand.js: -------------------------------------------------------------------------------- 1 | const UART_SERVICE_UUID = "6e400001-b5a3-f393-e0a9-e50e24dcca9e"; 2 | const UART_TX_UUID = "6e400003-b5a3-f393-e0a9-e50e24dcca9e"; // TX characteristic for micro:bit v2 3 | 4 | class Hand { 5 | constructor() { 6 | this.bluetoothDevice = undefined; 7 | this.uartService = undefined; 8 | } 9 | 10 | async connect() { 11 | try { 12 | this.bluetoothDevice = await navigator.bluetooth.requestDevice({ 13 | filters: [{ namePrefix: "BBC" }], // Filter for devices with names starting with "BBC" 14 | optionalServices: [UART_SERVICE_UUID], 15 | }); 16 | 17 | const server = await this.bluetoothDevice.gatt.connect(); 18 | const service = await server.getPrimaryService(UART_SERVICE_UUID); 19 | this.uartService = await service.getCharacteristic(UART_TX_UUID); 20 | 21 | console.log("Connected to hand!"); 22 | } catch (error) { 23 | console.error("Failed to connect to hand:", error); 24 | alert("Failed to connect to hand. Please try again."); 25 | } 26 | } 27 | 28 | async sendCommand(actionNumber) { 29 | if (this.uartService === undefined) { 30 | console.error("Not connected to micro:bit"); 31 | alert("Please connect to Hand first!"); 32 | return; 33 | } 34 | try { 35 | // Convert action number to hex and pad to two characters 36 | const hexAction = actionNumber.toString(16).toUpperCase().padStart(2, "0"); 37 | const command = `CMD|0F|${hexAction}|$`; 38 | const encoder = new TextEncoder(); 39 | await this.uartService.writeValue(encoder.encode(command)); 40 | console.log(`Command sent: ${command}`); 41 | } catch (error) { 42 | console.error("Failed to send command:", error); 43 | alert("Failed to send command to Yorick."); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Just a website 7 | 8 | 9 | 10 | 11 | 12 |
13 |

This is a plain old website

14 |

This is just a plain website that is using plain old JavaScript

15 | 16 |
17 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /public/script.js: -------------------------------------------------------------------------------- 1 | const hand = new Hand(); 2 | 3 | function talkToTheHand() { 4 | hand 5 | .connect() 6 | .then(() => console.log('Hand is ready')) 7 | .catch((err) => console.error(err)); 8 | } 9 | 10 | const fns = { 11 | getPageHTML: () => { 12 | return { success: true, html: document.documentElement.outerHTML }; 13 | }, 14 | changeBackgroundColor: ({ color }) => { 15 | document.body.style.backgroundColor = color; 16 | return { success: true, color }; 17 | }, 18 | changeTextColor: ({ color }) => { 19 | document.body.style.color = color; 20 | return { success: true, color }; 21 | }, 22 | showFingers: async ({ numberOfFingers }) => { 23 | await hand.sendCommand(numberOfFingers); 24 | return { success: true, numberOfFingers }; 25 | }, 26 | }; 27 | 28 | // Create a WebRTC Agent 29 | const peerConnection = new RTCPeerConnection(); 30 | 31 | // On inbound audio add to page 32 | peerConnection.ontrack = (event) => { 33 | const el = document.createElement('audio'); 34 | el.srcObject = event.streams[0]; 35 | el.autoplay = el.controls = true; 36 | document.body.appendChild(el); 37 | }; 38 | 39 | const dataChannel = peerConnection.createDataChannel('oai-events'); 40 | 41 | function configureData() { 42 | console.log('Configuring data channel'); 43 | const event = { 44 | type: 'session.update', 45 | session: { 46 | modalities: ['text', 'audio'], 47 | // Provide the tools. Note they match the keys in the `fns` object above 48 | tools: [ 49 | { 50 | type: 'function', 51 | name: 'changeBackgroundColor', 52 | description: 'Changes the background color of a web page', 53 | parameters: { 54 | type: 'object', 55 | properties: { 56 | color: { type: 'string', description: 'A hex value of the color' }, 57 | }, 58 | }, 59 | }, 60 | { 61 | type: 'function', 62 | name: 'changeTextColor', 63 | description: 'Changes the text color of a web page', 64 | parameters: { 65 | type: 'object', 66 | properties: { 67 | color: { type: 'string', description: 'A hex value of the color' }, 68 | }, 69 | }, 70 | }, 71 | { 72 | type: 'function', 73 | name: 'showFingers', 74 | description: 'Controls a robot hand to show a specific number of fingers', 75 | parameters: { 76 | type: 'object', 77 | properties: { 78 | numberOfFingers: { 79 | enum: [1, 2, 3, 4, 5], 80 | description: 'Values 1 through 5 of the number of fingers to hold up' }, 81 | }, 82 | }, 83 | }, 84 | { 85 | type: 'function', 86 | name: 'getPageHTML', 87 | description: 'Gets the HTML for the current page', 88 | }, 89 | ], 90 | }, 91 | }; 92 | dataChannel.send(JSON.stringify(event)); 93 | } 94 | 95 | dataChannel.addEventListener('open', (ev) => { 96 | console.log('Opening data channel', ev); 97 | configureData(); 98 | }); 99 | 100 | // { 101 | // "type": "response.function_call_arguments.done", 102 | // "event_id": "event_Ad2gt864G595umbCs2aF9", 103 | // "response_id": "resp_Ad2griUWUjsyeLyAVtTtt", 104 | // "item_id": "item_Ad2gsxA84w9GgEvFwW1Ex", 105 | // "output_index": 1, 106 | // "call_id": "call_PG12S5ER7l7HrvZz", 107 | // "name": "get_weather", 108 | // "arguments": "{\"location\":\"Portland, Oregon\"}" 109 | // } 110 | 111 | dataChannel.addEventListener('message', async (ev) => { 112 | const msg = JSON.parse(ev.data); 113 | // Handle function calls 114 | if (msg.type === 'response.function_call_arguments.done') { 115 | const fn = fns[msg.name]; 116 | if (fn !== undefined) { 117 | console.log(`Calling local function ${msg.name} with ${msg.arguments}`); 118 | const args = JSON.parse(msg.arguments); 119 | const result = await fn(args); 120 | console.log('result', result); 121 | // Let OpenAI know that the function has been called and share it's output 122 | const event = { 123 | type: 'conversation.item.create', 124 | item: { 125 | type: 'function_call_output', 126 | call_id: msg.call_id, // call_id from the function_call message 127 | output: JSON.stringify(result), // result of the function 128 | }, 129 | }; 130 | dataChannel.send(JSON.stringify(event)); 131 | // Have assistant respond after getting the results 132 | dataChannel.send(JSON.stringify({type:"response.create"})); 133 | } 134 | } 135 | }); 136 | 137 | // Capture microphone 138 | navigator.mediaDevices.getUserMedia({ audio: true }).then((stream) => { 139 | // Add microphone to PeerConnection 140 | stream.getTracks().forEach((track) => peerConnection.addTransceiver(track, { direction: 'sendrecv' })); 141 | 142 | peerConnection.createOffer().then((offer) => { 143 | peerConnection.setLocalDescription(offer); 144 | fetch('/session') 145 | .then((tokenResponse) => tokenResponse.json()) 146 | .then((data) => { 147 | const EPHEMERAL_KEY = data.result.client_secret.value; 148 | const baseUrl = 'https://api.openai.com/v1/realtime'; 149 | const model = 'gpt-4o-realtime-preview-2024-12-17'; 150 | fetch(`${baseUrl}?model=${model}`, { 151 | method: 'POST', 152 | body: offer.sdp, 153 | headers: { 154 | Authorization: `Bearer ${EPHEMERAL_KEY}`, 155 | 'Content-Type': 'application/sdp', 156 | }, 157 | }) 158 | .then((r) => r.text()) 159 | .then((answer) => { 160 | // Accept answer from Realtime WebRTC API 161 | peerConnection.setRemoteDescription({ 162 | sdp: answer, 163 | type: 'answer', 164 | }); 165 | }); 166 | }); 167 | 168 | // Send WebRTC Offer to Workers Realtime WebRTC API Relay 169 | }); 170 | }); 171 | -------------------------------------------------------------------------------- /public/styles.css: -------------------------------------------------------------------------------- 1 | /* Ensure the body takes up the full height */ 2 | body { 3 | margin: 0; 4 | display: flex; 5 | flex-direction: column; 6 | min-height: 100vh; 7 | } 8 | 9 | /* Main content should expand to fill available space */ 10 | .content { 11 | flex: 1; 12 | } 13 | 14 | /* Sticky footer styling */ 15 | footer { 16 | background-color: #333; 17 | color: #fff; 18 | text-align: center; 19 | padding: 10px; 20 | position: sticky; 21 | bottom: 0; 22 | } 23 | 24 | footer a { 25 | color: #fff; 26 | } 27 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import { Hono } from 'hono'; 2 | import { cors } from 'hono/cors'; 3 | 4 | const app = new Hono<{ Bindings: Env }>(); 5 | app.use(cors()); 6 | 7 | const DEFAULT_INSTRUCTIONS = `You are helpful and have some tools installed. 8 | 9 | In the tools you have the ability to control a robot hand. 10 | `; 11 | 12 | // Learn more: https://platform.openai.com/docs/api-reference/realtime-sessions/create 13 | app.get('/session', async (c) => { 14 | const response = await fetch("https://api.openai.com/v1/realtime/sessions", { 15 | method: "POST", 16 | headers: { 17 | "Authorization": `Bearer ${c.env.OPENAI_API_KEY}`, 18 | "Content-Type": "application/json", 19 | }, 20 | body: JSON.stringify({ 21 | model: "gpt-4o-realtime-preview-2024-12-17", 22 | instructions: DEFAULT_INSTRUCTIONS, 23 | voice: "ash", 24 | }), 25 | }); 26 | const result = await response.json(); 27 | return c.json({result}); 28 | }); 29 | 30 | 31 | export default app; 32 | -------------------------------------------------------------------------------- /test/index.spec.ts: -------------------------------------------------------------------------------- 1 | // test/index.spec.ts 2 | import { env, createExecutionContext, waitOnExecutionContext, SELF } from 'cloudflare:test'; 3 | import { describe, it, expect } from 'vitest'; 4 | import worker from '../src/index'; 5 | 6 | // For now, you'll need to do something like this to get a correctly-typed 7 | // `Request` to pass to `worker.fetch()`. 8 | const IncomingRequest = Request; 9 | 10 | describe('Hello World worker', () => { 11 | it('responds with Hello World! (unit style)', async () => { 12 | const request = new IncomingRequest('http://example.com'); 13 | // Create an empty context to pass to `worker.fetch()`. 14 | const ctx = createExecutionContext(); 15 | const response = await worker.fetch(request, env, ctx); 16 | // Wait for all `Promise`s passed to `ctx.waitUntil()` to settle before running test assertions 17 | await waitOnExecutionContext(ctx); 18 | expect(await response.text()).toMatchInlineSnapshot(`"Hello World!"`); 19 | }); 20 | 21 | it('responds with Hello World! (integration style)', async () => { 22 | const response = await SELF.fetch('https://example.com'); 23 | expect(await response.text()).toMatchInlineSnapshot(`"Hello World!"`); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /test/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "types": ["@cloudflare/workers-types/experimental", "@cloudflare/vitest-pool-workers"] 5 | }, 6 | "include": ["./**/*.ts", "../worker-configuration.d.ts"], 7 | "exclude": [] 8 | } 9 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Visit https://aka.ms/tsconfig.json to read more about this file */ 4 | 5 | /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ 6 | "target": "es2021", 7 | /* Specify a set of bundled library declaration files that describe the target runtime environment. */ 8 | "lib": ["es2021"], 9 | /* Specify what JSX code is generated. */ 10 | "jsx": "react-jsx", 11 | 12 | /* Specify what module code is generated. */ 13 | "module": "es2022", 14 | /* Specify how TypeScript looks up a file from a given module specifier. */ 15 | "moduleResolution": "Bundler", 16 | /* Specify type package names to be included without being referenced in a source file. */ 17 | "types": [ 18 | "@cloudflare/workers-types/2023-07-01" 19 | ], 20 | /* Enable importing .json files */ 21 | "resolveJsonModule": true, 22 | 23 | /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */ 24 | "allowJs": true, 25 | /* Enable error reporting in type-checked JavaScript files. */ 26 | "checkJs": false, 27 | 28 | /* Disable emitting files from a compilation. */ 29 | "noEmit": true, 30 | 31 | /* Ensure that each file can be safely transpiled without relying on other imports. */ 32 | "isolatedModules": true, 33 | /* Allow 'import x from y' when a module doesn't have a default export. */ 34 | "allowSyntheticDefaultImports": true, 35 | /* Ensure that casing is correct in imports. */ 36 | "forceConsistentCasingInFileNames": true, 37 | 38 | /* Enable all strict type-checking options. */ 39 | "strict": true, 40 | 41 | /* Skip type checking all .d.ts files. */ 42 | "skipLibCheck": true 43 | }, 44 | "exclude": ["test"], 45 | "include": ["worker-configuration.d.ts", "src/**/*.ts"] 46 | } 47 | -------------------------------------------------------------------------------- /vitest.config.mts: -------------------------------------------------------------------------------- 1 | import { defineWorkersConfig } from '@cloudflare/vitest-pool-workers/config'; 2 | 3 | export default defineWorkersConfig({ 4 | test: { 5 | poolOptions: { 6 | workers: { 7 | wrangler: { configPath: './wrangler.toml' }, 8 | }, 9 | }, 10 | }, 11 | }); 12 | -------------------------------------------------------------------------------- /worker-configuration.d.ts: -------------------------------------------------------------------------------- 1 | // Generated by Wrangler by running `wrangler types` 2 | 3 | interface Env { 4 | OPENAI_API_KEY: string; 5 | } 6 | -------------------------------------------------------------------------------- /wrangler.toml: -------------------------------------------------------------------------------- 1 | #:schema node_modules/wrangler/config-schema.json 2 | name = "talk-to-javascript" 3 | main = "src/index.ts" 4 | compatibility_date = "2024-01-15" 5 | compatibility_flags = ["nodejs_compat"] 6 | 7 | # Workers Logs 8 | # Docs: https://developers.cloudflare.com/workers/observability/logs/workers-logs/ 9 | # Configuration: https://developers.cloudflare.com/workers/observability/logs/workers-logs/#enable-workers-logs 10 | [observability] 11 | enabled = true 12 | 13 | [assets] 14 | directory = "./public" 15 | 16 | # Automatically place your workloads in an optimal location to minimize latency. 17 | # If you are running back-end logic in a Worker, running it closer to your back-end infrastructure 18 | # rather than the end user may result in better performance. 19 | # Docs: https://developers.cloudflare.com/workers/configuration/smart-placement/#smart-placement 20 | # [placement] 21 | # mode = "smart" 22 | 23 | # Variable bindings. These are arbitrary, plaintext strings (similar to environment variables) 24 | # Docs: 25 | # - https://developers.cloudflare.com/workers/wrangler/configuration/#environment-variables 26 | # Note: Use secrets to store sensitive data. 27 | # - https://developers.cloudflare.com/workers/configuration/secrets/ 28 | # [vars] 29 | # MY_VARIABLE = "production_value" 30 | 31 | # Bind the Workers AI model catalog. Run machine learning models, powered by serverless GPUs, on Cloudflare’s global network 32 | # Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#workers-ai 33 | # [ai] 34 | # binding = "AI" 35 | 36 | # Bind an Analytics Engine dataset. Use Analytics Engine to write analytics within your Pages Function. 37 | # Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#analytics-engine-datasets 38 | # [[analytics_engine_datasets]] 39 | # binding = "MY_DATASET" 40 | 41 | # Bind a headless browser instance running on Cloudflare's global network. 42 | # Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#browser-rendering 43 | # [browser] 44 | # binding = "MY_BROWSER" 45 | 46 | # Bind a D1 database. D1 is Cloudflare’s native serverless SQL database. 47 | # Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#d1-databases 48 | # [[d1_databases]] 49 | # binding = "MY_DB" 50 | # database_name = "my-database" 51 | # database_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" 52 | 53 | # Bind a dispatch namespace. Use Workers for Platforms to deploy serverless functions programmatically on behalf of your customers. 54 | # Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#dispatch-namespace-bindings-workers-for-platforms 55 | # [[dispatch_namespaces]] 56 | # binding = "MY_DISPATCHER" 57 | # namespace = "my-namespace" 58 | 59 | # Bind a Durable Object. Durable objects are a scale-to-zero compute primitive based on the actor model. 60 | # Durable Objects can live for as long as needed. Use these when you need a long-running "server", such as in realtime apps. 61 | # Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#durable-objects 62 | # [[durable_objects.bindings]] 63 | # name = "MY_DURABLE_OBJECT" 64 | # class_name = "MyDurableObject" 65 | 66 | # Durable Object migrations. 67 | # Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#migrations 68 | # [[migrations]] 69 | # tag = "v1" 70 | # new_classes = ["MyDurableObject"] 71 | 72 | # Bind a Hyperdrive configuration. Use to accelerate access to your existing databases from Cloudflare Workers. 73 | # Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#hyperdrive 74 | # [[hyperdrive]] 75 | # binding = "MY_HYPERDRIVE" 76 | # id = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" 77 | 78 | # Bind a KV Namespace. Use KV as persistent storage for small key-value pairs. 79 | # Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#kv-namespaces 80 | # [[kv_namespaces]] 81 | # binding = "MY_KV_NAMESPACE" 82 | # id = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" 83 | 84 | # Bind an mTLS certificate. Use to present a client certificate when communicating with another service. 85 | # Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#mtls-certificates 86 | # [[mtls_certificates]] 87 | # binding = "MY_CERTIFICATE" 88 | # certificate_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" 89 | 90 | # Bind a Queue producer. Use this binding to schedule an arbitrary task that may be processed later by a Queue consumer. 91 | # Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#queues 92 | # [[queues.producers]] 93 | # binding = "MY_QUEUE" 94 | # queue = "my-queue" 95 | 96 | # Bind a Queue consumer. Queue Consumers can retrieve tasks scheduled by Producers to act on them. 97 | # Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#queues 98 | # [[queues.consumers]] 99 | # queue = "my-queue" 100 | 101 | # Bind an R2 Bucket. Use R2 to store arbitrarily large blobs of data, such as files. 102 | # Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#r2-buckets 103 | # [[r2_buckets]] 104 | # binding = "MY_BUCKET" 105 | # bucket_name = "my-bucket" 106 | 107 | # Bind another Worker service. Use this binding to call another Worker without network overhead. 108 | # Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#service-bindings 109 | # [[services]] 110 | # binding = "MY_SERVICE" 111 | # service = "my-service" 112 | 113 | # Bind a Vectorize index. Use to store and query vector embeddings for semantic search, classification and other vector search use-cases. 114 | # Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#vectorize-indexes 115 | # [[vectorize]] 116 | # binding = "MY_INDEX" 117 | # index_name = "my-index" 118 | --------------------------------------------------------------------------------