├── .gitignore ├── model └── group1-shard1of1.bin ├── .prettierrc.json ├── vitest.config.ts ├── .npmignore ├── scripts ├── bin-encode.mjs └── clear-node-fetch.mjs ├── lib ├── worker.ts ├── base64.ts ├── worker-wrapper.ts └── index.ts ├── __test__ ├── test-utils.ts ├── esm.test.ts ├── worker.test.ts └── index.test.ts ├── tsconfig.json ├── vite.config.ts ├── LICENSE.md ├── package.json ├── docs └── index.html ├── README.md └── pnpm-lock.yaml /.gitignore: -------------------------------------------------------------------------------- 1 | dist 2 | node_modules 3 | *.tgz 4 | -------------------------------------------------------------------------------- /model/group1-shard1of1.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Ray-D-Song/guesslang-js/HEAD/model/group1-shard1of1.bin -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 150, 3 | "tabWidth": 2, 4 | "useTabs": false, 5 | "semi": true, 6 | "singleQuote": true, 7 | "trailingComma": "all" 8 | } 9 | -------------------------------------------------------------------------------- /vitest.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vitest/config'; 2 | 3 | export default defineConfig({ 4 | test: { 5 | setupFiles: ['@vitest/web-worker'], 6 | }, 7 | }) -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .github 2 | .prettierrc.json 3 | dist/test 4 | example 5 | lib 6 | model 7 | test 8 | utils 9 | tsconfig.json 10 | webpack.config.js 11 | **/*.map 12 | guesslang-js-*.tgz 13 | -------------------------------------------------------------------------------- /scripts/bin-encode.mjs: -------------------------------------------------------------------------------- 1 | import { readFileSync, writeFileSync } from 'node:fs'; 2 | import { Buffer } from 'node:buffer'; 3 | 4 | async function encode() { 5 | const binContent = readFileSync('./model/group1-shard1of1.bin'); 6 | const base64 = Buffer.from(binContent).toString('base64'); 7 | writeFileSync('./lib/bin.ts', `export default \`${base64}\``); 8 | } 9 | 10 | encode(); -------------------------------------------------------------------------------- /lib/worker.ts: -------------------------------------------------------------------------------- 1 | import { GuessLang } from './index'; 2 | 3 | let guessLang = new GuessLang() 4 | 5 | self.onmessage = async (e: MessageEvent) => { 6 | const { id, content } = e.data; 7 | 8 | try { 9 | const result = await guessLang.runModel(content); 10 | self.postMessage({ id, result }); 11 | } catch (error) { 12 | self.postMessage({ 13 | id, 14 | error: error instanceof Error ? error.message : String(error) 15 | }) 16 | } 17 | }; 18 | -------------------------------------------------------------------------------- /__test__/test-utils.ts: -------------------------------------------------------------------------------- 1 | import path from 'path'; 2 | import { readFileSync } from 'fs'; 3 | 4 | export async function modelJsonLoaderFunc() { 5 | const modelPath = path.join(__dirname, '..', 'model', 'model.json'); 6 | console.log('modelPath', modelPath); 7 | return JSON.parse(readFileSync(modelPath, 'utf-8')); 8 | } 9 | 10 | export async function weightsLoaderFunc() { 11 | const weightsPath = path.join(__dirname, '..', 'model', 'group1-shard1of1.bin'); 12 | return readFileSync(weightsPath).buffer; 13 | } -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "ESNext", 4 | "moduleResolution": "node", 5 | "noEmitOnError": false, 6 | "strict": true, 7 | "esModuleInterop": true, 8 | "forceConsistentCasingInFileNames": true, 9 | "skipLibCheck": true, 10 | "sourceMap": true, 11 | "inlineSources": true, 12 | "noUnusedLocals": true, 13 | "noUnusedParameters": true, 14 | "declaration": true, 15 | "emitDeclarationOnly": true, 16 | "noEmit": false, 17 | "outDir": "./dist/types", 18 | "lib": ["ESNext", "DOM", "DOM.Iterable"], 19 | "types": ["vite/client"], 20 | "resolveJsonModule": true 21 | }, 22 | "include": [ 23 | "lib/**/*.ts" 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /scripts/clear-node-fetch.mjs: -------------------------------------------------------------------------------- 1 | import { readdirSync, readFileSync, writeFileSync, statSync } from 'node:fs'; 2 | import path from 'node:path'; 3 | 4 | function clearNodeFetch() { 5 | const libDir = path.resolve('dist/lib'); 6 | const workerDir = path.resolve('dist/worker'); 7 | const dirs = [libDir, workerDir]; 8 | for (const dir of dirs) { 9 | const files = readdirSync(dir); 10 | for (const fileOrDir of files) { 11 | const stats = statSync(path.resolve(dir, fileOrDir)); 12 | if (stats.isFile()) { 13 | const content = readFileSync(path.resolve(dir, fileOrDir), 'utf8'); 14 | if (content.includes('node-fetch')) { 15 | writeFileSync(path.resolve(dir, fileOrDir), content.replace('() => require("node-fetch")', "'good'")); 16 | } 17 | } 18 | } 19 | } 20 | } 21 | 22 | clearNodeFetch(); -------------------------------------------------------------------------------- /vite.config.ts: -------------------------------------------------------------------------------- 1 | import { LibraryFormats } from 'vite'; 2 | import { defineConfig } from 'vite' 3 | 4 | // build esm 5 | export default defineConfig(() => { 6 | const BUILD_TARGET = process.env.BUILD_TARGET || 'esm&umd' 7 | 8 | if (BUILD_TARGET === 'worker') { 9 | return { 10 | build: { 11 | outDir: 'dist/worker', 12 | target: 'es6', 13 | assetsDir: '', 14 | lib: { 15 | name: 'guesslang-worker', 16 | entry: './lib/worker-wrapper.ts', 17 | formats: ['es'] satisfies LibraryFormats[] 18 | } 19 | }, 20 | worker: { 21 | format: 'es' as const, 22 | }, 23 | } 24 | } 25 | 26 | return { 27 | build: { 28 | outDir: 'dist/lib', 29 | target: 'es6', 30 | lib: { 31 | name: 'guesslang', 32 | entry: './lib/index.ts', 33 | formats: ['es'] satisfies LibraryFormats[] 34 | } 35 | }, 36 | } 37 | }) 38 | -------------------------------------------------------------------------------- /__test__/esm.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect, beforeEach, afterEach } from 'vitest'; 2 | import { GuessLang } from '../lib'; 3 | import { modelJsonLoaderFunc, weightsLoaderFunc } from './test-utils'; 4 | 5 | describe('ESM Format Tests', () => { 6 | let guessLang: GuessLang; 7 | 8 | beforeEach(() => { 9 | guessLang = new GuessLang({ 10 | minContentSize: 0, 11 | modelJsonLoaderFunc, 12 | weightsLoaderFunc 13 | }); 14 | }); 15 | 16 | afterEach(() => { 17 | if (guessLang) { 18 | guessLang.dispose(); 19 | } 20 | }); 21 | 22 | it('should work with ESM imports', async () => { 23 | const code = ` 24 | import { useState, useEffect } from 'react'; 25 | 26 | export function Counter() { 27 | const [count, setCount] = useState(0); 28 | 29 | useEffect(() => { 30 | document.title = \`Count: \${count}\`; 31 | }, [count]); 32 | } 33 | `; 34 | 35 | const result = await guessLang.runModel(code); 36 | expect(result[0].languageId).to.equal('ts'); 37 | }); 38 | 39 | }); -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | ===================== 4 | 5 | Permission is hereby granted, free of charge, to any person 6 | obtaining a copy of this software and associated documentation 7 | files (the “Software”), to deal in the Software without 8 | restriction, including without limitation the rights to use, 9 | copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the 11 | Software is furnished to do so, subject to the following 12 | conditions: 13 | 14 | The above copyright notice and this permission notice shall be 15 | included in all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, 18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 19 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 21 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 22 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 24 | OTHER DEALINGS IN THE SOFTWARE. 25 | -------------------------------------------------------------------------------- /lib/base64.ts: -------------------------------------------------------------------------------- 1 | // Taken from https://github.com/niklasvh/base64-arraybuffer/blob/47fe6a8b415945503594a2adb0d24804b136d851/src/index.ts 2 | 3 | const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; 4 | 5 | const lookup = typeof Uint8Array === 'undefined' ? [] : new Uint8Array(256); 6 | for (let i = 0; i < chars.length; i++) { 7 | lookup[chars.charCodeAt(i)] = i; 8 | } 9 | 10 | export const base64ToArrayBuffer = (base64: string): ArrayBuffer => { 11 | let bufferLength = base64.length * 0.75, 12 | len = base64.length, 13 | i, 14 | p = 0, 15 | encoded1, 16 | encoded2, 17 | encoded3, 18 | encoded4; 19 | 20 | if (base64[base64.length - 1] === '=') { 21 | bufferLength--; 22 | if (base64[base64.length - 2] === '=') { 23 | bufferLength--; 24 | } 25 | } 26 | 27 | const arraybuffer = new ArrayBuffer(bufferLength), 28 | bytes = new Uint8Array(arraybuffer); 29 | 30 | for (i = 0; i < len; i += 4) { 31 | encoded1 = lookup[base64.charCodeAt(i)]; 32 | encoded2 = lookup[base64.charCodeAt(i + 1)]; 33 | encoded3 = lookup[base64.charCodeAt(i + 2)]; 34 | encoded4 = lookup[base64.charCodeAt(i + 3)]; 35 | 36 | bytes[p++] = (encoded1 << 2) | (encoded2 >> 4); 37 | bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2); 38 | bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63); 39 | } 40 | 41 | return arraybuffer; 42 | }; 43 | -------------------------------------------------------------------------------- /lib/worker-wrapper.ts: -------------------------------------------------------------------------------- 1 | import type { ModelResult } from './index'; 2 | import Worker from './worker?worker&inline'; 3 | 4 | interface CommonWorker { 5 | postMessage(message: any): void; 6 | terminate(): void; 7 | } 8 | 9 | interface BrowserWorker extends CommonWorker { 10 | onmessage: (e: MessageEvent) => void; 11 | } 12 | 13 | export class GuessLangWorker { 14 | private worker: BrowserWorker; 15 | private messageId = 0; 16 | private pendingMessages = new Map void; 18 | reject: (error: Error) => void; 19 | }>(); 20 | 21 | constructor() { 22 | const worker = new Worker(); 23 | worker.onmessage = this.handleMessage.bind(this); 24 | this.worker = worker as BrowserWorker; 25 | } 26 | 27 | async runModel(content: string): Promise { 28 | const id = this.messageId++; 29 | 30 | return new Promise((resolve, reject) => { 31 | this.pendingMessages.set(id, { resolve, reject }); 32 | this.worker.postMessage({ id, content }); 33 | }); 34 | } 35 | 36 | private handleMessage(e: MessageEvent | any) { 37 | const data = e.data || e; 38 | const { id, result, error } = data; 39 | 40 | const pending = this.pendingMessages.get(id); 41 | if (pending) { 42 | this.pendingMessages.delete(id); 43 | if (error) { 44 | pending.reject(new Error(error)); 45 | } else { 46 | pending.resolve(result); 47 | } 48 | } 49 | } 50 | 51 | dispose() { 52 | this.worker.terminate(); 53 | this.pendingMessages.clear(); 54 | } 55 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@ray-d-song/guesslang-js", 3 | "version": "0.1.0", 4 | "description": "Use guesslang's ML model to detect source code languages", 5 | "private": false, 6 | "scripts": { 7 | "build:types": "tsc", 8 | "build:lib": "vite build", 9 | "build:worker": "BUILD_TARGET=worker vite build", 10 | "build": "npm run build:types && npm run build:lib && npm run build:worker && node scripts/clear-node-fetch.mjs", 11 | "test": "vitest" 12 | }, 13 | "repository": { 14 | "type": "git", 15 | "url": "git+https://github.com/Ray-D-Song/guesslang-js.git" 16 | }, 17 | "author": "Ray-D-Song", 18 | "license": "MIT", 19 | "bugs": { 20 | "url": "https://github.com/Ray-D-Song/guesslang-js/issues" 21 | }, 22 | "homepage": "https://github.com/Ray-D-Song/guesslang-js#readme", 23 | "devDependencies": { 24 | "@tensorflow/tfjs-backend-cpu": "^3.9.0", 25 | "@tensorflow/tfjs-converter": "^3.9.0", 26 | "@tensorflow/tfjs-core": "^3.9.0", 27 | "@types/node": "^16.10.2", 28 | "@vitest/web-worker": "^2.1.5", 29 | "prettier": "^2.4.1", 30 | "typescript": "^4.4.3", 31 | "vite": "^5.4.11", 32 | "vite-plugin-dts": "^4.3.0", 33 | "vitest": "^2.1.5" 34 | }, 35 | "exports": { 36 | ".": { 37 | "types": "./dist/types/lib/index.d.ts", 38 | "import": "./dist/lib/guesslang-js.mjs", 39 | "default": "./dist/lib/guesslang-js.umd.js" 40 | }, 41 | "./worker": { 42 | "types": "./dist/types/lib/worker-wrapper.d.ts", 43 | "import": "./dist/worker/guesslang-js.mjs" 44 | } 45 | }, 46 | "files": [ 47 | "dist/lib", 48 | "dist/worker", 49 | "dist/types" 50 | ] 51 | } 52 | -------------------------------------------------------------------------------- /__test__/worker.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'vitest'; 2 | import '@vitest/web-worker' 3 | import { ModelResult } from '../lib'; 4 | 5 | declare global { 6 | var modelJsonLoaderFunc: () => Promise; 7 | var weightsLoaderFunc: () => Promise; 8 | } 9 | 10 | describe('GuessLangWorker Tests', () => { 11 | const worker = new Worker(new URL('../lib/worker.ts', import.meta.url)); 12 | 13 | it('should detect TypeScript code', async () => { 14 | const code = ` 15 | interface User { 16 | id: number; 17 | name: string; 18 | } 19 | 20 | function getUser(id: number): Promise { 21 | return fetch(\`/api/users/\${id}\`).then(res => res.json()); 22 | } 23 | `; 24 | 25 | worker.postMessage({ 26 | id: 0, 27 | content: code, 28 | }); 29 | 30 | const result = await new Promise((resolve, reject) => { 31 | worker.onmessage = (e) => resolve(e.data.result); 32 | worker.onerror = (e) => reject(e.error); 33 | }); 34 | 35 | expect(result[0].languageId).to.equal('ts'); 36 | }); 37 | 38 | it('should detect Python code', async () => { 39 | const code = ` 40 | def two_sum(nums, target): 41 | num_map = {} 42 | for i, num in enumerate(nums): 43 | complement = target - num 44 | if complement in num_map: 45 | return [num_map[complement], i] 46 | num_map[num] = i 47 | return [] 48 | `; 49 | 50 | worker.postMessage({ 51 | id: 0, 52 | content: code, 53 | }); 54 | 55 | const result = await new Promise((resolve, reject) => { 56 | worker.onmessage = (e) => resolve(e.data.result); 57 | worker.onerror = (e) => reject(e.error); 58 | }); 59 | 60 | expect(result[0].languageId).to.equal('py'); 61 | }); 62 | }); 63 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | guesslang-js 5 | 6 | 7 | 8 | 17 | 18 | 19 |
20 |
21 |

Code Language Detection

22 | 23 | 35 |
36 | 37 |
38 |
39 | 40 | 44 |
45 | 46 |
47 | 48 | 53 |
54 |
55 | 56 | 62 |
63 | 64 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # guesslang-js 2 | 3 | A JavaScript library that uses machine learning to detect source code languages. Powered by [@yoeo](https://github.com/yoeo)'s [guesslang](https://github.com/yoeo/guesslang) model! 4 | 5 | Inspired by and modified from [vscode-languagedetection](https://github.com/microsoft/vscode-languagedetection) to add browser support. 6 | 7 | This is a fork of https://github.com/hieplpvip/guesslang-js, aimed at: 8 | - esm and web worker support 9 | - fix memory leak issues 10 | - better build process 11 | 12 | ## Usage 13 | 14 | This library is intended to be used only in browser. For Node.JS, please consider using [vscode-languagedetection](https://github.com/microsoft/vscode-languagedetection). 15 | 16 | Install via `npm`: 17 | ```bash 18 | npm install @ray-d-song/guesslang-js 19 | 20 | # or yarn 21 | yarn add @ray-d-song/guesslang-js 22 | 23 | # or pnpm 24 | pnpm add @ray-d-song/guesslang-js 25 | ``` 26 | 27 | Now you can use it in your project: 28 | 29 | ```js 30 | import { GuessLang } from '@ray-d-song/guesslang-js'; 31 | ``` 32 | 33 | Declare sample code: 34 | 35 | ```js 36 | const code = ` 37 | struct Rectangle { 38 | width: u32, 39 | height: u32, 40 | } 41 | 42 | fn main() { 43 | let rect1 = Rectangle { 44 | width: 30, 45 | height: 50, 46 | }; 47 | 48 | println!( 49 | "The area of the rectangle is {} square pixels.", 50 | area(&rect1) 51 | ); 52 | } 53 | 54 | fn area(rectangle: &Rectangle) -> u32 { 55 | rectangle.width * rectangle.height 56 | } 57 | `; 58 | ``` 59 | 60 | ### With Promise 61 | 62 | ```js 63 | // You should only create one guesslang instance 64 | const guessLang = new GuessLang(); 65 | 66 | guessLang.runModel(code).then((result) => { 67 | console.log(result); 68 | }); 69 | ``` 70 | 71 | ### With async/await 72 | 73 | ```js 74 | const guessLang = new GuessLang(); 75 | 76 | const result = await guessLang.runModel(code); 77 | console.log(result); 78 | ``` 79 | 80 | ### With Web Worker 81 | 82 | ```js 83 | import { GuessLangWorker } from '@ray-d-song/guesslang-js/worker'; 84 | 85 | const guessLang = new GuessLangWorker(); 86 | const result = await guessLang.runModel(code); 87 | console.log(result); 88 | ``` 89 | 90 | You should get an output similar to this: 91 | 92 | ```json 93 | [ 94 | { "languageId": "rs", "confidence": 0.7457122802734375 }, 95 | { "languageId": "js", "confidence": 0.03622082620859146 }, 96 | { "languageId": "ts", "confidence": 0.02657853439450264 }, 97 | { "languageId": "html", "confidence": 0.018268872052431107 }, 98 | { "languageId": "dart", "confidence": 0.017024816945195198 }, 99 | { "languageId": "css", "confidence": 0.013620768673717976 }, 100 | { "languageId": "go", "confidence": 0.012718110345304012 }, 101 | { "languageId": "c", "confidence": 0.011547493748366833 }, 102 | { "languageId": "lua", "confidence": 0.011429708451032639 }, 103 | { "languageId": "cpp", "confidence": 0.010202286764979362 }, 104 | { "languageId": "swift", "confidence": 0.010128483176231384 }, 105 | { "languageId": "kt", "confidence": 0.008081216365098953 }, 106 | { "languageId": "pm", "confidence": 0.007753847632557154 }, 107 | { "languageId": "groovy", "confidence": 0.007391981780529022 }, 108 | { "languageId": "scala", "confidence": 0.0069132656790316105 }, 109 | { "languageId": "r", "confidence": 0.006373902782797813 }, 110 | { "languageId": "ps1", "confidence": 0.004702022764831781 }, 111 | { "languageId": "mm", "confidence": 0.004345177672803402 }, 112 | { "languageId": "tex", "confidence": 0.004238464403897524 }, 113 | { "languageId": "asm", "confidence": 0.0035753981210291386 }, 114 | { "languageId": "php", "confidence": 0.0029875021427869797 }, 115 | { "languageId": "cs", "confidence": 0.00282992678694427 }, 116 | { "languageId": "erl", "confidence": 0.0026539231184870005 }, 117 | { "languageId": "hs", "confidence": 0.0022999923676252365 }, 118 | { "languageId": "java", "confidence": 0.0021398833487182856 }, 119 | { "languageId": "json", "confidence": 0.0018522157333791256 }, 120 | { "languageId": "jl", "confidence": 0.0016744869062677026 }, 121 | { "languageId": "coffee", "confidence": 0.0014533938374370337 }, 122 | { "languageId": "ml", "confidence": 0.0014339216286316514 }, 123 | { "languageId": "prolog", "confidence": 0.0013837843434885144 }, 124 | { "languageId": "md", "confidence": 0.0011162260780110955 }, 125 | { "languageId": "rb", "confidence": 0.0010244469158351421 }, 126 | { "languageId": "bat", "confidence": 0.0009783837012946606 }, 127 | { "languageId": "ex", "confidence": 0.0009154175058938563 }, 128 | { "languageId": "pas", "confidence": 0.0009110081009566784 }, 129 | { "languageId": "xml", "confidence": 0.0008580578141845763 }, 130 | { "languageId": "sh", "confidence": 0.0008576430263929069 }, 131 | { "languageId": "py", "confidence": 0.0006855467217974365 }, 132 | { "languageId": "csv", "confidence": 0.0006681767990812659 }, 133 | { "languageId": "yaml", "confidence": 0.0006367963505908847 }, 134 | { "languageId": "sql", "confidence": 0.0006355350487865508 }, 135 | { "languageId": "vba", "confidence": 0.0005863389233127236 }, 136 | { "languageId": "dm", "confidence": 0.0004887901013717055 }, 137 | { "languageId": "matlab", "confidence": 0.0003887197526637465 }, 138 | { "languageId": "v", "confidence": 0.000384387094527483 }, 139 | { "languageId": "clj", "confidence": 0.0003443971218075603 }, 140 | { "languageId": "f90", "confidence": 0.0002740618074312806 }, 141 | { "languageId": "cmake", "confidence": 0.000268166622845456 }, 142 | { "languageId": "ini", "confidence": 0.00018944506882689893 }, 143 | { "languageId": "makefile", "confidence": 0.0001014301014947705 }, 144 | { "languageId": "lisp", "confidence": 0.00006610684067709371 }, 145 | { "languageId": "cbl", "confidence": 0.00004037651524413377 }, 146 | { "languageId": "dockerfile", "confidence": 0.00002403824146313127 }, 147 | { "languageId": "toml", "confidence": 0.000019977496776846237 } 148 | ] 149 | ``` 150 | 151 | ### Advanced Options 152 | 153 | You can pass an optional object to `GuessLang` containing the following options: 154 | 155 | - `minContentSize?: number` - The minimum number of characters in a file to be considered for language detection. Defaults to `20`. 156 | - `maxContentSize?: number` - The maximum number of characters _that will be used_ in a file to be considered for language detection. Defaults to `100000`. 157 | 158 | For example: 159 | 160 | ```js 161 | const guessLang = new GuessLang({ 162 | minContentSize: 0, 163 | maxContentSize: 1000, 164 | }); 165 | ``` 166 | 167 | ## Differences from vscode-languagedetection 168 | 169 | The only notable difference is that this library includes the guesslang model as Base64 encoded string, allowing everything to be loaded from one single file. Meanwhile, `vscode-languagedetection` loads the model from files using `fs`. 170 | 171 | ## Credits 172 | 173 | - [guesslang](https://github.com/yoeo/guesslang) 174 | - [vscode-languagedetection](https://github.com/microsoft/vscode-languagedetection) 175 | - [base64-arraybuffer](https://github.com/niklasvh/base64-arraybuffer) 176 | - [base64-inline-loader](https://github.com/monolithed/base64-inline-loader) 177 | -------------------------------------------------------------------------------- /lib/index.ts: -------------------------------------------------------------------------------- 1 | import { Rank, tensor, Tensor, io, setBackend, env } from '@tensorflow/tfjs-core'; 2 | import { GraphModel, loadGraphModel } from '@tensorflow/tfjs-converter'; 3 | import '@tensorflow/tfjs-backend-cpu'; 4 | import MODEL_JSON from '../model/model.json'; 5 | import MODEL_WEIGHTS from './bin'; 6 | import { base64ToArrayBuffer } from './base64'; 7 | 8 | export interface ModelResult { 9 | languageId: string; 10 | confidence: number; 11 | } 12 | 13 | class InMemoryIOHandler implements io.IOHandler { 14 | constructor(private readonly modelJSON: io.ModelJSON, private readonly weights: ArrayBuffer) {} 15 | 16 | async load(): Promise { 17 | // We do not allow both modelTopology and weightsManifest to be missing. 18 | const modelTopology = this.modelJSON.modelTopology; 19 | const weightsManifest = this.modelJSON.weightsManifest; 20 | if (modelTopology === null && weightsManifest === null) { 21 | throw new Error(`The model contains neither model topology or manifest for weights.`); 22 | } 23 | 24 | return this.getModelArtifactsForJSON(this.modelJSON, (weightsManifest) => this.loadWeights(weightsManifest)); 25 | } 26 | 27 | private async getModelArtifactsForJSON( 28 | modelJSON: io.ModelJSON, 29 | loadWeights: (weightsManifest: io.WeightsManifestConfig) => Promise<[/* weightSpecs */ io.WeightsManifestEntry[], /* weightData */ ArrayBuffer]>, 30 | ): Promise { 31 | const modelArtifacts: io.ModelArtifacts = { 32 | modelTopology: modelJSON.modelTopology, 33 | format: modelJSON.format, 34 | generatedBy: modelJSON.generatedBy, 35 | convertedBy: modelJSON.convertedBy, 36 | }; 37 | 38 | if (modelJSON.trainingConfig !== null) { 39 | modelArtifacts.trainingConfig = modelJSON.trainingConfig; 40 | } 41 | if (modelJSON.weightsManifest !== null) { 42 | const [weightSpecs, weightData] = await loadWeights(modelJSON.weightsManifest); 43 | modelArtifacts.weightSpecs = weightSpecs; 44 | modelArtifacts.weightData = weightData; 45 | } 46 | if (modelJSON.signature !== null) { 47 | modelArtifacts.signature = modelJSON.signature; 48 | } 49 | if (modelJSON.userDefinedMetadata !== null) { 50 | modelArtifacts.userDefinedMetadata = modelJSON.userDefinedMetadata; 51 | } 52 | if (modelJSON.modelInitializer !== null) { 53 | modelArtifacts.modelInitializer = modelJSON.modelInitializer; 54 | } 55 | 56 | return modelArtifacts; 57 | } 58 | 59 | private async loadWeights(weightsManifest: io.WeightsManifestConfig): Promise<[io.WeightsManifestEntry[], ArrayBuffer]> { 60 | const weightSpecs = []; 61 | for (const entry of weightsManifest) { 62 | weightSpecs.push(...entry.weights); 63 | } 64 | 65 | return [weightSpecs, this.weights]; 66 | } 67 | } 68 | 69 | export interface GuessLangOptions { 70 | modelJsonLoaderFunc?: () => Promise<{ [key: string]: any }>; 71 | weightsLoaderFunc?: () => Promise; 72 | minContentSize?: number; 73 | maxContentSize?: number; 74 | normalizeNewline?: boolean; 75 | } 76 | 77 | let isBackendRegistered = false; 78 | 79 | export class GuessLang { 80 | private static DEFAULT_MAX_CONTENT_SIZE = 100000; 81 | private static DEFAULT_MIN_CONTENT_SIZE = 20; 82 | 83 | private static NODE_MODEL_JSON_FUNC: () => Promise<{ [key: string]: any }> = async () => { 84 | return MODEL_JSON; 85 | }; 86 | 87 | private static NODE_WEIGHTS_FUNC: () => Promise = async () => { 88 | return base64ToArrayBuffer(MODEL_WEIGHTS); 89 | }; 90 | 91 | private _model: GraphModel | undefined; 92 | private _modelJson: io.ModelJSON | undefined; 93 | private _weights: ArrayBuffer | undefined; 94 | private readonly _minContentSize: number; 95 | private readonly _maxContentSize: number; 96 | private readonly _modelJsonLoaderFunc: () => Promise<{ [key: string]: any }>; 97 | private readonly _weightsLoaderFunc: () => Promise; 98 | private readonly _normalizeNewline: boolean; 99 | 100 | constructor(options?: GuessLangOptions) { 101 | this._modelJsonLoaderFunc = options?.modelJsonLoaderFunc ?? GuessLang.NODE_MODEL_JSON_FUNC; 102 | this._weightsLoaderFunc = options?.weightsLoaderFunc ?? GuessLang.NODE_WEIGHTS_FUNC; 103 | this._minContentSize = options?.minContentSize ?? GuessLang.DEFAULT_MIN_CONTENT_SIZE; 104 | this._maxContentSize = options?.maxContentSize ?? GuessLang.DEFAULT_MAX_CONTENT_SIZE; 105 | this._normalizeNewline = options?.normalizeNewline ?? true; 106 | } 107 | 108 | private async getModelJSON(): Promise { 109 | if (this._modelJson) { 110 | return this._modelJson; 111 | } 112 | 113 | this._modelJson = (await this._modelJsonLoaderFunc()) as io.ModelJSON; 114 | return this._modelJson; 115 | } 116 | 117 | private async getWeights() { 118 | if (this._weights) { 119 | return this._weights; 120 | } 121 | 122 | this._weights = await this._weightsLoaderFunc(); 123 | return this._weights; 124 | } 125 | 126 | private async loadModel() { 127 | if (this._model) { 128 | return; 129 | } 130 | 131 | if (!isBackendRegistered) { 132 | const tfEnv = env(); 133 | tfEnv.set('IS_NODE', false); 134 | tfEnv.set('PROD', true); 135 | 136 | if (!(await setBackend('cpu'))) { 137 | throw new Error('Unable to set backend to CPU.'); 138 | } 139 | isBackendRegistered = true; 140 | } 141 | 142 | const resolvedModelJSON = await this.getModelJSON(); 143 | const resolvedWeights = await this.getWeights(); 144 | this._model = await loadGraphModel(new InMemoryIOHandler(resolvedModelJSON, resolvedWeights)); 145 | } 146 | 147 | public async runModel(content: string): Promise> { 148 | if (!content || content.length < this._minContentSize) { 149 | return []; 150 | } 151 | 152 | await this.loadModel(); 153 | 154 | // larger files cause a "RangeError: Maximum call stack size exceeded" in tfjs. 155 | // So grab the first X characters as that should be good enough for guessing. 156 | if (content.length >= this._maxContentSize) { 157 | content = content.substring(0, this._maxContentSize); 158 | } 159 | 160 | if (this._normalizeNewline) { 161 | content = content.replace(/\r\n/g, '\n'); 162 | } 163 | 164 | const predicted = await this._model!.executeAsync(tensor([content])); 165 | try { 166 | // call out to the model 167 | const probabilitiesTensor: Tensor = Array.isArray(predicted) ? predicted[0]! : predicted; 168 | const languageTensor: Tensor = Array.isArray(predicted) ? predicted[1]! : predicted; 169 | const probabilities = probabilitiesTensor.dataSync() as Float32Array; 170 | const langs: Array = languageTensor.dataSync() as any; 171 | 172 | const objs: Array = []; 173 | for (let i = 0; i < langs.length; i++) { 174 | objs.push({ 175 | languageId: langs[i], 176 | confidence: probabilities[i], 177 | }); 178 | } 179 | 180 | let maxIndex = 0; 181 | for (let i = 0; i < probabilities.length; i++) { 182 | if (probabilities[i] > probabilities[maxIndex]) { 183 | maxIndex = i; 184 | } 185 | } 186 | 187 | return objs.sort((a, b) => { 188 | return b.confidence - a.confidence; 189 | }); 190 | } finally { 191 | if (Array.isArray(predicted)) { 192 | predicted.forEach((tensor) => { 193 | tensor.dispose(); 194 | }); 195 | } else { 196 | predicted.dispose(); 197 | } 198 | } 199 | } 200 | 201 | public dispose() { 202 | this._model?.dispose(); 203 | this._modelJson = undefined; 204 | this._weights = undefined; 205 | this._model = undefined; 206 | } 207 | } 208 | -------------------------------------------------------------------------------- /__test__/index.test.ts: -------------------------------------------------------------------------------- 1 | import { readFileSync } from 'fs'; 2 | import path from 'path'; 3 | import { describe, it, expect } from 'vitest'; 4 | import { GuessLang, ModelResult } from '../lib'; 5 | 6 | const expectedRelativeConfidence = 0.2; 7 | 8 | async function arrayify(generator: Generator) { 9 | const langs: string[] = []; 10 | for await (const lang of generator) { 11 | langs.push(lang); 12 | } 13 | return langs; 14 | } 15 | 16 | // Similar to the heuristic used in VS Code: 17 | function* runVSCodeHeuristic(modelResults: ModelResult[]) { 18 | if (!modelResults) { 19 | return; 20 | } 21 | 22 | if (modelResults[0].confidence < expectedRelativeConfidence) { 23 | return; 24 | } 25 | 26 | const possibleLanguages: ModelResult[] = [modelResults[0]]; 27 | 28 | for (let current of modelResults) { 29 | if (current === modelResults[0]) { 30 | continue; 31 | } 32 | 33 | const currentHighest = possibleLanguages[possibleLanguages.length - 1]; 34 | 35 | if (currentHighest.confidence - current.confidence >= expectedRelativeConfidence) { 36 | while (possibleLanguages.length) { 37 | yield possibleLanguages.shift()!.languageId; 38 | } 39 | if (current.confidence > expectedRelativeConfidence) { 40 | possibleLanguages.push(current); 41 | continue; 42 | } 43 | return; 44 | } else { 45 | if (current.confidence > expectedRelativeConfidence) { 46 | possibleLanguages.push(current); 47 | continue; 48 | } 49 | 50 | // Handle languages that are close enough to each other 51 | if ( 52 | (currentHighest.languageId === 'ts' && current.languageId === 'js') || 53 | (currentHighest.languageId === 'js' && current.languageId === 'ts') || 54 | (currentHighest.languageId === 'c' && current.languageId === 'cpp') || 55 | (currentHighest.languageId === 'cpp' && current.languageId === 'c') 56 | ) { 57 | continue; 58 | } 59 | 60 | return; 61 | } 62 | } 63 | } 64 | 65 | async function modelJsonLoaderFunc(): Promise<{ [key: string]: any }> { 66 | const fs = await import('fs'); 67 | const path = await import('path'); 68 | 69 | return new Promise((resolve, reject) => { 70 | fs.readFile(path.join(__dirname, '..', 'model', 'model.json'), (err, data) => { 71 | if (err) { 72 | reject(err); 73 | return; 74 | } 75 | resolve(JSON.parse(data.toString())); 76 | }); 77 | }); 78 | } 79 | 80 | async function weightsLoaderFunc(): Promise { 81 | const fs = await import('fs'); 82 | const path = await import('path'); 83 | 84 | return new Promise((resolve, reject) => { 85 | fs.readFile(path.join(__dirname, '..', 'model', 'group1-shard1of1.bin'), (err, data) => { 86 | if (err) { 87 | reject(err); 88 | return; 89 | } 90 | resolve(data.buffer); 91 | }); 92 | }); 93 | } 94 | 95 | describe('describe', () => { 96 | const modelOperations = new GuessLang({ 97 | modelJsonLoaderFunc, 98 | weightsLoaderFunc, 99 | }); 100 | 101 | it('test TypeScript', async () => { 102 | const result = await modelOperations.runModel(` 103 | import { ValidationPipe } from '@nestjs/common'; 104 | import { NestFactory } from '@nestjs/core'; 105 | import { AppModule } from './app.module'; 106 | 107 | async function bootstrap() { 108 | const app = await NestFactory.create(AppModule); 109 | app.useGlobalPipes(new ValidationPipe()); 110 | 111 | await app.listen(3000); 112 | console.log(\`Application is running on: \${await app.getUrl()}\`); 113 | } 114 | bootstrap(); 115 | `); 116 | 117 | expect(result[0].languageId).to.equal('ts'); 118 | expect(result[0].confidence).to.greaterThan(expectedRelativeConfidence); 119 | 120 | const langs: string[] = await arrayify(runVSCodeHeuristic(result)); 121 | expect(langs.length).to.equal(1); 122 | expect(langs[0]).to.equal('ts'); 123 | }); 124 | 125 | it('test Python', async () => { 126 | const result = await modelOperations.runModel(` 127 | # Python program to check if the input number is odd or even. 128 | # A number is even if division by 2 gives a remainder of 0. 129 | # If the remainder is 1, it is an odd number. 130 | 131 | num = int(input("Enter a number: ")) 132 | if (num % 2) == 0: 133 | print("{0} is Even".format(num)) 134 | else: 135 | print("{0} is Odd".format(num)) 136 | `); 137 | expect(result[0].languageId).to.equal('py'); 138 | expect(result[0].confidence).to.greaterThan(expectedRelativeConfidence); 139 | const langs: string[] = await arrayify(runVSCodeHeuristic(result)); 140 | expect(langs.length).to.equal(1); 141 | expect(langs[0]).to.equal('py'); 142 | }); 143 | 144 | it('test Java', async () => { 145 | const result = await modelOperations.runModel(` 146 | public class Main { 147 | 148 | public static void main(String[] args) { 149 | int num = 29; 150 | boolean flag = false; 151 | for (int i = 2; i <= num / 2; ++i) { 152 | // condition for nonprime number 153 | if (num % i == 0) { 154 | flag = true; 155 | break; 156 | } 157 | } 158 | 159 | if (!flag) 160 | System.out.println(num + " is a prime number."); 161 | else 162 | System.out.println(num + " is not a prime number."); 163 | } 164 | } 165 | `); 166 | expect(result[0].languageId).to.equal('java'); 167 | expect(result[0].confidence).to.greaterThan(expectedRelativeConfidence); 168 | const langs: string[] = await arrayify(runVSCodeHeuristic(result)); 169 | expect(langs.length).to.equal(1); 170 | expect(langs[0]).to.equal('java'); 171 | }); 172 | 173 | it('test PowerShell', async () => { 174 | const result = await modelOperations.runModel(` 175 | $msedgedriverPath = 'C:\\Users\\Tyler\\Downloads\\edgedriver_win64\\msedgedriver.exe' 176 | 177 | $Driver = Start-SeNewEdge -BinaryPath $msedgedriverPath -StartURL https://seattle.signetic.com/home 178 | 179 | Start-Sleep -Seconds 5 180 | 181 | while($true) { 182 | $element = Find-SeElement -Driver $Driver -ClassName text-demibold 183 | 184 | if (!$element -or $element.Text -ne 'No appointments available') { 185 | # notify 186 | New-BurntToastNotification -Text 'Check website' 187 | break 188 | } else { 189 | Write-Host 'no appointments available' 190 | } 191 | 192 | Enter-SeUrl https://seattle.signetic.com/home -Driver $Driver 193 | Start-Sleep -Seconds 2 194 | } 195 | `); 196 | expect(result[0].languageId).to.equal('ps1'); 197 | expect(result[0].confidence).to.greaterThan(expectedRelativeConfidence); 198 | const langs: string[] = await arrayify(runVSCodeHeuristic(result)); 199 | expect(langs.length).to.equal(1); 200 | expect(langs[0]).to.equal('ps1'); 201 | }); 202 | 203 | it('test large file', async () => { 204 | const result = await modelOperations.runModel(readFileSync(path.resolve(__dirname, '..', '__test__', 'large.ts.txt')).toString()); 205 | 206 | expect(result[0].languageId).to.equal('ts'); 207 | expect(result[0].confidence).to.greaterThan(expectedRelativeConfidence); 208 | 209 | const langs: string[] = await arrayify(runVSCodeHeuristic(result)); 210 | expect(langs.length).to.equal(1); 211 | expect(langs[0]).to.equal('ts'); 212 | }); 213 | 214 | it('test Visual Basic', async () => { 215 | const result = await modelOperations.runModel(` 216 | Module Module1 217 | 218 | Sub Main() 219 | Dim id As Integer 220 | Dim name As String = "Suresh Dasari" 221 | Dim percentage As Double = 10.23 222 | Dim gender As Char = "M"c 223 | Dim isVerified As Boolean 224 | 225 | id = 10 226 | isVerified = True 227 | Console.WriteLine("Id:{0}", id) 228 | Console.WriteLine("Name:{0}", name) 229 | Console.WriteLine("Percentage:{0}", percentage) 230 | Console.WriteLine("Gender:{0}", gender) 231 | Console.WriteLine("Verfied:{0}", isVerified) 232 | Console.ReadLine() 233 | End Sub 234 | 235 | End Module 236 | `); 237 | 238 | expect(result[0].languageId).to.equal('vba'); 239 | expect(result[0].confidence).to.greaterThan(expectedRelativeConfidence); 240 | 241 | for await (const lang of runVSCodeHeuristic(result)) { 242 | expect(lang).to.equal('vba'); 243 | } 244 | }); 245 | 246 | it('test results with carriage returns', async () => { 247 | const result = await modelOperations.runModel( 248 | `public class Reverse {\r\n\r\n public static void main(String[] args) {\r\n String sentence = "Go work";\r\n String reversed = reverse(sentence);\r\n System.out.println("The reversed sentence is: " + reversed);\r\n }\r\n\r\n public static String reverse(String sentence) {\r\n if (sentence.isEmpty())\r\n return sentence;\r\n\r\n return reverse(sentence.substring(1)) + sentence.charAt(0);\r\n }\r\n}`, 249 | ); 250 | expect(result[0].languageId).to.equal('java'); 251 | expect(result[0].confidence).to.greaterThan(expectedRelativeConfidence); 252 | const langs: string[] = await arrayify(runVSCodeHeuristic(result)); 253 | expect(langs.length).to.equal(1); 254 | expect(langs[0]).to.equal('java'); 255 | }); 256 | }); 257 | -------------------------------------------------------------------------------- /pnpm-lock.yaml: -------------------------------------------------------------------------------- 1 | lockfileVersion: '9.0' 2 | 3 | settings: 4 | autoInstallPeers: true 5 | excludeLinksFromLockfile: false 6 | 7 | importers: 8 | 9 | .: 10 | devDependencies: 11 | '@tensorflow/tfjs-backend-cpu': 12 | specifier: ^3.9.0 13 | version: 3.21.0(@tensorflow/tfjs-core@3.21.0) 14 | '@tensorflow/tfjs-converter': 15 | specifier: ^3.9.0 16 | version: 3.21.0(@tensorflow/tfjs-core@3.21.0) 17 | '@tensorflow/tfjs-core': 18 | specifier: ^3.9.0 19 | version: 3.21.0 20 | '@types/node': 21 | specifier: ^16.10.2 22 | version: 16.18.119 23 | '@vitest/web-worker': 24 | specifier: ^2.1.5 25 | version: 2.1.5(vitest@2.1.5(@types/node@16.18.119)(terser@5.36.0)) 26 | prettier: 27 | specifier: ^2.4.1 28 | version: 2.8.8 29 | typescript: 30 | specifier: ^4.4.3 31 | version: 4.9.5 32 | vite: 33 | specifier: ^5.4.11 34 | version: 5.4.11(@types/node@16.18.119)(terser@5.36.0) 35 | vite-plugin-dts: 36 | specifier: ^4.3.0 37 | version: 4.3.0(@types/node@16.18.119)(rollup@4.27.3)(typescript@4.9.5)(vite@5.4.11(@types/node@16.18.119)(terser@5.36.0)) 38 | vitest: 39 | specifier: ^2.1.5 40 | version: 2.1.5(@types/node@16.18.119)(terser@5.36.0) 41 | 42 | packages: 43 | 44 | '@babel/helper-string-parser@7.25.9': 45 | resolution: {integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==} 46 | engines: {node: '>=6.9.0'} 47 | 48 | '@babel/helper-validator-identifier@7.25.9': 49 | resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==} 50 | engines: {node: '>=6.9.0'} 51 | 52 | '@babel/parser@7.26.2': 53 | resolution: {integrity: sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==} 54 | engines: {node: '>=6.0.0'} 55 | hasBin: true 56 | 57 | '@babel/types@7.26.0': 58 | resolution: {integrity: sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==} 59 | engines: {node: '>=6.9.0'} 60 | 61 | '@esbuild/aix-ppc64@0.21.5': 62 | resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} 63 | engines: {node: '>=12'} 64 | cpu: [ppc64] 65 | os: [aix] 66 | 67 | '@esbuild/android-arm64@0.21.5': 68 | resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} 69 | engines: {node: '>=12'} 70 | cpu: [arm64] 71 | os: [android] 72 | 73 | '@esbuild/android-arm@0.21.5': 74 | resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} 75 | engines: {node: '>=12'} 76 | cpu: [arm] 77 | os: [android] 78 | 79 | '@esbuild/android-x64@0.21.5': 80 | resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} 81 | engines: {node: '>=12'} 82 | cpu: [x64] 83 | os: [android] 84 | 85 | '@esbuild/darwin-arm64@0.21.5': 86 | resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} 87 | engines: {node: '>=12'} 88 | cpu: [arm64] 89 | os: [darwin] 90 | 91 | '@esbuild/darwin-x64@0.21.5': 92 | resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} 93 | engines: {node: '>=12'} 94 | cpu: [x64] 95 | os: [darwin] 96 | 97 | '@esbuild/freebsd-arm64@0.21.5': 98 | resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} 99 | engines: {node: '>=12'} 100 | cpu: [arm64] 101 | os: [freebsd] 102 | 103 | '@esbuild/freebsd-x64@0.21.5': 104 | resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} 105 | engines: {node: '>=12'} 106 | cpu: [x64] 107 | os: [freebsd] 108 | 109 | '@esbuild/linux-arm64@0.21.5': 110 | resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} 111 | engines: {node: '>=12'} 112 | cpu: [arm64] 113 | os: [linux] 114 | 115 | '@esbuild/linux-arm@0.21.5': 116 | resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} 117 | engines: {node: '>=12'} 118 | cpu: [arm] 119 | os: [linux] 120 | 121 | '@esbuild/linux-ia32@0.21.5': 122 | resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} 123 | engines: {node: '>=12'} 124 | cpu: [ia32] 125 | os: [linux] 126 | 127 | '@esbuild/linux-loong64@0.21.5': 128 | resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} 129 | engines: {node: '>=12'} 130 | cpu: [loong64] 131 | os: [linux] 132 | 133 | '@esbuild/linux-mips64el@0.21.5': 134 | resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} 135 | engines: {node: '>=12'} 136 | cpu: [mips64el] 137 | os: [linux] 138 | 139 | '@esbuild/linux-ppc64@0.21.5': 140 | resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} 141 | engines: {node: '>=12'} 142 | cpu: [ppc64] 143 | os: [linux] 144 | 145 | '@esbuild/linux-riscv64@0.21.5': 146 | resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} 147 | engines: {node: '>=12'} 148 | cpu: [riscv64] 149 | os: [linux] 150 | 151 | '@esbuild/linux-s390x@0.21.5': 152 | resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} 153 | engines: {node: '>=12'} 154 | cpu: [s390x] 155 | os: [linux] 156 | 157 | '@esbuild/linux-x64@0.21.5': 158 | resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} 159 | engines: {node: '>=12'} 160 | cpu: [x64] 161 | os: [linux] 162 | 163 | '@esbuild/netbsd-x64@0.21.5': 164 | resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} 165 | engines: {node: '>=12'} 166 | cpu: [x64] 167 | os: [netbsd] 168 | 169 | '@esbuild/openbsd-x64@0.21.5': 170 | resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} 171 | engines: {node: '>=12'} 172 | cpu: [x64] 173 | os: [openbsd] 174 | 175 | '@esbuild/sunos-x64@0.21.5': 176 | resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} 177 | engines: {node: '>=12'} 178 | cpu: [x64] 179 | os: [sunos] 180 | 181 | '@esbuild/win32-arm64@0.21.5': 182 | resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} 183 | engines: {node: '>=12'} 184 | cpu: [arm64] 185 | os: [win32] 186 | 187 | '@esbuild/win32-ia32@0.21.5': 188 | resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} 189 | engines: {node: '>=12'} 190 | cpu: [ia32] 191 | os: [win32] 192 | 193 | '@esbuild/win32-x64@0.21.5': 194 | resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} 195 | engines: {node: '>=12'} 196 | cpu: [x64] 197 | os: [win32] 198 | 199 | '@jridgewell/gen-mapping@0.3.5': 200 | resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} 201 | engines: {node: '>=6.0.0'} 202 | 203 | '@jridgewell/resolve-uri@3.1.2': 204 | resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} 205 | engines: {node: '>=6.0.0'} 206 | 207 | '@jridgewell/set-array@1.2.1': 208 | resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} 209 | engines: {node: '>=6.0.0'} 210 | 211 | '@jridgewell/source-map@0.3.6': 212 | resolution: {integrity: sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==} 213 | 214 | '@jridgewell/sourcemap-codec@1.5.0': 215 | resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} 216 | 217 | '@jridgewell/trace-mapping@0.3.25': 218 | resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} 219 | 220 | '@microsoft/api-extractor-model@7.29.8': 221 | resolution: {integrity: sha512-t3Z/xcO6TRbMcnKGVMs4uMzv/gd5j0NhMiJIGjD4cJMeFJ1Hf8wnLSx37vxlRlL0GWlGJhnFgxvnaL6JlS+73g==} 222 | 223 | '@microsoft/api-extractor@7.47.11': 224 | resolution: {integrity: sha512-lrudfbPub5wzBhymfFtgZKuBvXxoSIAdrvS2UbHjoMT2TjIEddq6Z13pcve7A03BAouw0x8sW8G4txdgfiSwpQ==} 225 | hasBin: true 226 | 227 | '@microsoft/tsdoc-config@0.17.0': 228 | resolution: {integrity: sha512-v/EYRXnCAIHxOHW+Plb6OWuUoMotxTN0GLatnpOb1xq0KuTNw/WI3pamJx/UbsoJP5k9MCw1QxvvhPcF9pH3Zg==} 229 | 230 | '@microsoft/tsdoc@0.15.0': 231 | resolution: {integrity: sha512-HZpPoABogPvjeJOdzCOSJsXeL/SMCBgBZMVC3X3d7YYp2gf31MfxhUoYUNwf1ERPJOnQc0wkFn9trqI6ZEdZuA==} 232 | 233 | '@rollup/pluginutils@5.1.3': 234 | resolution: {integrity: sha512-Pnsb6f32CD2W3uCaLZIzDmeFyQ2b8UWMFI7xtwUezpcGBDVDW6y9XgAWIlARiGAo6eNF5FK5aQTr0LFyNyqq5A==} 235 | engines: {node: '>=14.0.0'} 236 | peerDependencies: 237 | rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 238 | peerDependenciesMeta: 239 | rollup: 240 | optional: true 241 | 242 | '@rollup/rollup-android-arm-eabi@4.27.3': 243 | resolution: {integrity: sha512-EzxVSkIvCFxUd4Mgm4xR9YXrcp976qVaHnqom/Tgm+vU79k4vV4eYTjmRvGfeoW8m9LVcsAy/lGjcgVegKEhLQ==} 244 | cpu: [arm] 245 | os: [android] 246 | 247 | '@rollup/rollup-android-arm64@4.27.3': 248 | resolution: {integrity: sha512-LJc5pDf1wjlt9o/Giaw9Ofl+k/vLUaYsE2zeQGH85giX2F+wn/Cg8b3c5CDP3qmVmeO5NzwVUzQQxwZvC2eQKw==} 249 | cpu: [arm64] 250 | os: [android] 251 | 252 | '@rollup/rollup-darwin-arm64@4.27.3': 253 | resolution: {integrity: sha512-OuRysZ1Mt7wpWJ+aYKblVbJWtVn3Cy52h8nLuNSzTqSesYw1EuN6wKp5NW/4eSre3mp12gqFRXOKTcN3AI3LqA==} 254 | cpu: [arm64] 255 | os: [darwin] 256 | 257 | '@rollup/rollup-darwin-x64@4.27.3': 258 | resolution: {integrity: sha512-xW//zjJMlJs2sOrCmXdB4d0uiilZsOdlGQIC/jjmMWT47lkLLoB1nsNhPUcnoqyi5YR6I4h+FjBpILxbEy8JRg==} 259 | cpu: [x64] 260 | os: [darwin] 261 | 262 | '@rollup/rollup-freebsd-arm64@4.27.3': 263 | resolution: {integrity: sha512-58E0tIcwZ+12nK1WiLzHOD8I0d0kdrY/+o7yFVPRHuVGY3twBwzwDdTIBGRxLmyjciMYl1B/U515GJy+yn46qw==} 264 | cpu: [arm64] 265 | os: [freebsd] 266 | 267 | '@rollup/rollup-freebsd-x64@4.27.3': 268 | resolution: {integrity: sha512-78fohrpcVwTLxg1ZzBMlwEimoAJmY6B+5TsyAZ3Vok7YabRBUvjYTsRXPTjGEvv/mfgVBepbW28OlMEz4w8wGA==} 269 | cpu: [x64] 270 | os: [freebsd] 271 | 272 | '@rollup/rollup-linux-arm-gnueabihf@4.27.3': 273 | resolution: {integrity: sha512-h2Ay79YFXyQi+QZKo3ISZDyKaVD7uUvukEHTOft7kh00WF9mxAaxZsNs3o/eukbeKuH35jBvQqrT61fzKfAB/Q==} 274 | cpu: [arm] 275 | os: [linux] 276 | 277 | '@rollup/rollup-linux-arm-musleabihf@4.27.3': 278 | resolution: {integrity: sha512-Sv2GWmrJfRY57urktVLQ0VKZjNZGogVtASAgosDZ1aUB+ykPxSi3X1nWORL5Jk0sTIIwQiPH7iE3BMi9zGWfkg==} 279 | cpu: [arm] 280 | os: [linux] 281 | 282 | '@rollup/rollup-linux-arm64-gnu@4.27.3': 283 | resolution: {integrity: sha512-FPoJBLsPW2bDNWjSrwNuTPUt30VnfM8GPGRoLCYKZpPx0xiIEdFip3dH6CqgoT0RnoGXptaNziM0WlKgBc+OWQ==} 284 | cpu: [arm64] 285 | os: [linux] 286 | 287 | '@rollup/rollup-linux-arm64-musl@4.27.3': 288 | resolution: {integrity: sha512-TKxiOvBorYq4sUpA0JT+Fkh+l+G9DScnG5Dqx7wiiqVMiRSkzTclP35pE6eQQYjP4Gc8yEkJGea6rz4qyWhp3g==} 289 | cpu: [arm64] 290 | os: [linux] 291 | 292 | '@rollup/rollup-linux-powerpc64le-gnu@4.27.3': 293 | resolution: {integrity: sha512-v2M/mPvVUKVOKITa0oCFksnQQ/TqGrT+yD0184/cWHIu0LoIuYHwox0Pm3ccXEz8cEQDLk6FPKd1CCm+PlsISw==} 294 | cpu: [ppc64] 295 | os: [linux] 296 | 297 | '@rollup/rollup-linux-riscv64-gnu@4.27.3': 298 | resolution: {integrity: sha512-LdrI4Yocb1a/tFVkzmOE5WyYRgEBOyEhWYJe4gsDWDiwnjYKjNs7PS6SGlTDB7maOHF4kxevsuNBl2iOcj3b4A==} 299 | cpu: [riscv64] 300 | os: [linux] 301 | 302 | '@rollup/rollup-linux-s390x-gnu@4.27.3': 303 | resolution: {integrity: sha512-d4wVu6SXij/jyiwPvI6C4KxdGzuZOvJ6y9VfrcleHTwo68fl8vZC5ZYHsCVPUi4tndCfMlFniWgwonQ5CUpQcA==} 304 | cpu: [s390x] 305 | os: [linux] 306 | 307 | '@rollup/rollup-linux-x64-gnu@4.27.3': 308 | resolution: {integrity: sha512-/6bn6pp1fsCGEY5n3yajmzZQAh+mW4QPItbiWxs69zskBzJuheb3tNynEjL+mKOsUSFK11X4LYF2BwwXnzWleA==} 309 | cpu: [x64] 310 | os: [linux] 311 | 312 | '@rollup/rollup-linux-x64-musl@4.27.3': 313 | resolution: {integrity: sha512-nBXOfJds8OzUT1qUreT/en3eyOXd2EH5b0wr2bVB5999qHdGKkzGzIyKYaKj02lXk6wpN71ltLIaQpu58YFBoQ==} 314 | cpu: [x64] 315 | os: [linux] 316 | 317 | '@rollup/rollup-win32-arm64-msvc@4.27.3': 318 | resolution: {integrity: sha512-ogfbEVQgIZOz5WPWXF2HVb6En+kWzScuxJo/WdQTqEgeyGkaa2ui5sQav9Zkr7bnNCLK48uxmmK0TySm22eiuw==} 319 | cpu: [arm64] 320 | os: [win32] 321 | 322 | '@rollup/rollup-win32-ia32-msvc@4.27.3': 323 | resolution: {integrity: sha512-ecE36ZBMLINqiTtSNQ1vzWc5pXLQHlf/oqGp/bSbi7iedcjcNb6QbCBNG73Euyy2C+l/fn8qKWEwxr+0SSfs3w==} 324 | cpu: [ia32] 325 | os: [win32] 326 | 327 | '@rollup/rollup-win32-x64-msvc@4.27.3': 328 | resolution: {integrity: sha512-vliZLrDmYKyaUoMzEbMTg2JkerfBjn03KmAw9CykO0Zzkzoyd7o3iZNam/TpyWNjNT+Cz2iO3P9Smv2wgrR+Eg==} 329 | cpu: [x64] 330 | os: [win32] 331 | 332 | '@rushstack/node-core-library@5.9.0': 333 | resolution: {integrity: sha512-MMsshEWkTbXqxqFxD4gcIUWQOCeBChlGczdZbHfqmNZQFLHB3yWxDFSMHFUdu2/OB9NUk7Awn5qRL+rws4HQNg==} 334 | peerDependencies: 335 | '@types/node': '*' 336 | peerDependenciesMeta: 337 | '@types/node': 338 | optional: true 339 | 340 | '@rushstack/rig-package@0.5.3': 341 | resolution: {integrity: sha512-olzSSjYrvCNxUFZowevC3uz8gvKr3WTpHQ7BkpjtRpA3wK+T0ybep/SRUMfr195gBzJm5gaXw0ZMgjIyHqJUow==} 342 | 343 | '@rushstack/terminal@0.14.2': 344 | resolution: {integrity: sha512-2fC1wqu1VCExKC0/L+0noVcFQEXEnoBOtCIex1TOjBzEDWcw8KzJjjj7aTP6mLxepG0XIyn9OufeFb6SFsa+sg==} 345 | peerDependencies: 346 | '@types/node': '*' 347 | peerDependenciesMeta: 348 | '@types/node': 349 | optional: true 350 | 351 | '@rushstack/ts-command-line@4.23.0': 352 | resolution: {integrity: sha512-jYREBtsxduPV6ptNq8jOKp9+yx0ld1Tb/Tkdnlj8gTjazl1sF3DwX2VbluyYrNd0meWIL0bNeer7WDf5tKFjaQ==} 353 | 354 | '@tensorflow/tfjs-backend-cpu@3.21.0': 355 | resolution: {integrity: sha512-88S21UAdzyK0CsLUrH17GPTD+26E85OP9CqmLZslaWjWUmBkeTQ5Zqyp6iK+gELnLxPx6q7JsNEeFuPv4254lQ==} 356 | engines: {yarn: '>= 1.3.2'} 357 | peerDependencies: 358 | '@tensorflow/tfjs-core': 3.21.0 359 | 360 | '@tensorflow/tfjs-converter@3.21.0': 361 | resolution: {integrity: sha512-12Y4zVDq3yW+wSjSDpSv4HnpL2sDZrNiGSg8XNiDE4HQBdjdA+a+Q3sZF/8NV9y2yoBhL5L7V4mMLDdbZBd9/Q==} 362 | peerDependencies: 363 | '@tensorflow/tfjs-core': 3.21.0 364 | 365 | '@tensorflow/tfjs-core@3.21.0': 366 | resolution: {integrity: sha512-YSfsswOqWfd+M4bXIhT3hwtAb+IV8+ODwIxwdFR/7jTAPZP1wMVnSlpKnXHAN64HFOiP+Tm3HmKusEZ0+09A0w==} 367 | engines: {yarn: '>= 1.3.2'} 368 | 369 | '@types/argparse@1.0.38': 370 | resolution: {integrity: sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA==} 371 | 372 | '@types/estree@1.0.6': 373 | resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} 374 | 375 | '@types/long@4.0.2': 376 | resolution: {integrity: sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==} 377 | 378 | '@types/node@16.18.119': 379 | resolution: {integrity: sha512-ia7V9a2FnhUFfetng4/sRPBMTwHZUkPFY736rb1cg9AgG7MZdR97q7/nLR9om+sq5f1la9C857E0l/nrI0RiFQ==} 380 | 381 | '@types/offscreencanvas@2019.3.0': 382 | resolution: {integrity: sha512-esIJx9bQg+QYF0ra8GnvfianIY8qWB0GBx54PK5Eps6m+xTj86KLavHv6qDhzKcu5UUOgNfJ2pWaIIV7TRUd9Q==} 383 | 384 | '@types/seedrandom@2.4.34': 385 | resolution: {integrity: sha512-ytDiArvrn/3Xk6/vtylys5tlY6eo7Ane0hvcx++TKo6RxQXuVfW0AF/oeWqAj9dN29SyhtawuXstgmPlwNcv/A==} 386 | 387 | '@types/webgl-ext@0.0.30': 388 | resolution: {integrity: sha512-LKVgNmBxN0BbljJrVUwkxwRYqzsAEPcZOe6S2T6ZaBDIrFp0qu4FNlpc5sM1tGbXUYFgdVQIoeLk1Y1UoblyEg==} 389 | 390 | '@vitest/expect@2.1.5': 391 | resolution: {integrity: sha512-nZSBTW1XIdpZvEJyoP/Sy8fUg0b8od7ZpGDkTUcfJ7wz/VoZAFzFfLyxVxGFhUjJzhYqSbIpfMtl/+k/dpWa3Q==} 392 | 393 | '@vitest/mocker@2.1.5': 394 | resolution: {integrity: sha512-XYW6l3UuBmitWqSUXTNXcVBUCRytDogBsWuNXQijc00dtnU/9OqpXWp4OJroVrad/gLIomAq9aW8yWDBtMthhQ==} 395 | peerDependencies: 396 | msw: ^2.4.9 397 | vite: ^5.0.0 398 | peerDependenciesMeta: 399 | msw: 400 | optional: true 401 | vite: 402 | optional: true 403 | 404 | '@vitest/pretty-format@2.1.5': 405 | resolution: {integrity: sha512-4ZOwtk2bqG5Y6xRGHcveZVr+6txkH7M2e+nPFd6guSoN638v/1XQ0K06eOpi0ptVU/2tW/pIU4IoPotY/GZ9fw==} 406 | 407 | '@vitest/runner@2.1.5': 408 | resolution: {integrity: sha512-pKHKy3uaUdh7X6p1pxOkgkVAFW7r2I818vHDthYLvUyjRfkKOU6P45PztOch4DZarWQne+VOaIMwA/erSSpB9g==} 409 | 410 | '@vitest/snapshot@2.1.5': 411 | resolution: {integrity: sha512-zmYw47mhfdfnYbuhkQvkkzYroXUumrwWDGlMjpdUr4jBd3HZiV2w7CQHj+z7AAS4VOtWxI4Zt4bWt4/sKcoIjg==} 412 | 413 | '@vitest/spy@2.1.5': 414 | resolution: {integrity: sha512-aWZF3P0r3w6DiYTVskOYuhBc7EMc3jvn1TkBg8ttylFFRqNN2XGD7V5a4aQdk6QiUzZQ4klNBSpCLJgWNdIiNw==} 415 | 416 | '@vitest/utils@2.1.5': 417 | resolution: {integrity: sha512-yfj6Yrp0Vesw2cwJbP+cl04OC+IHFsuQsrsJBL9pyGeQXE56v1UAOQco+SR55Vf1nQzfV0QJg1Qum7AaWUwwYg==} 418 | 419 | '@vitest/web-worker@2.1.5': 420 | resolution: {integrity: sha512-Cl+jooxraKRVUGZCK7py/dgj4JqypxYRM3Mc/uQ+LUlSMC8yJ1lL12LnXSv/z3l/RI/OpmAH6iAVPKSf5LpjdQ==} 421 | peerDependencies: 422 | vitest: 2.1.5 423 | 424 | '@volar/language-core@2.4.10': 425 | resolution: {integrity: sha512-hG3Z13+nJmGaT+fnQzAkS0hjJRa2FCeqZt6Bd+oGNhUkQ+mTFsDETg5rqUTxyzIh5pSOGY7FHCWUS8G82AzLCA==} 426 | 427 | '@volar/source-map@2.4.10': 428 | resolution: {integrity: sha512-OCV+b5ihV0RF3A7vEvNyHPi4G4kFa6ukPmyVocmqm5QzOd8r5yAtiNvaPEjl8dNvgC/lj4JPryeeHLdXd62rWA==} 429 | 430 | '@volar/typescript@2.4.10': 431 | resolution: {integrity: sha512-F8ZtBMhSXyYKuBfGpYwqA5rsONnOwAVvjyE7KPYJ7wgZqo2roASqNWUnianOomJX5u1cxeRooHV59N0PhvEOgw==} 432 | 433 | '@vue/compiler-core@3.5.13': 434 | resolution: {integrity: sha512-oOdAkwqUfW1WqpwSYJce06wvt6HljgY3fGeM9NcVA1HaYOij3mZG9Rkysn0OHuyUAGMbEbARIpsG+LPVlBJ5/Q==} 435 | 436 | '@vue/compiler-dom@3.5.13': 437 | resolution: {integrity: sha512-ZOJ46sMOKUjO3e94wPdCzQ6P1Lx/vhp2RSvfaab88Ajexs0AHeV0uasYhi99WPaogmBlRHNRuly8xV75cNTMDA==} 438 | 439 | '@vue/compiler-vue2@2.7.16': 440 | resolution: {integrity: sha512-qYC3Psj9S/mfu9uVi5WvNZIzq+xnXMhOwbTFKKDD7b1lhpnn71jXSFdTQ+WsIEk0ONCd7VV2IMm7ONl6tbQ86A==} 441 | 442 | '@vue/language-core@2.1.6': 443 | resolution: {integrity: sha512-MW569cSky9R/ooKMh6xa2g1D0AtRKbL56k83dzus/bx//RDJk24RHWkMzbAlXjMdDNyxAaagKPRquBIxkxlCkg==} 444 | peerDependencies: 445 | typescript: '*' 446 | peerDependenciesMeta: 447 | typescript: 448 | optional: true 449 | 450 | '@vue/shared@3.5.13': 451 | resolution: {integrity: sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==} 452 | 453 | '@webgpu/types@0.1.16': 454 | resolution: {integrity: sha512-9E61voMP4+Rze02jlTXud++Htpjyyk8vw5Hyw9FGRrmhHQg2GqbuOfwf5Klrb8vTxc2XWI3EfO7RUHMpxTj26A==} 455 | 456 | acorn@8.14.0: 457 | resolution: {integrity: sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==} 458 | engines: {node: '>=0.4.0'} 459 | hasBin: true 460 | 461 | ajv-draft-04@1.0.0: 462 | resolution: {integrity: sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==} 463 | peerDependencies: 464 | ajv: ^8.5.0 465 | peerDependenciesMeta: 466 | ajv: 467 | optional: true 468 | 469 | ajv-formats@3.0.1: 470 | resolution: {integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==} 471 | peerDependencies: 472 | ajv: ^8.0.0 473 | peerDependenciesMeta: 474 | ajv: 475 | optional: true 476 | 477 | ajv@8.12.0: 478 | resolution: {integrity: sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==} 479 | 480 | ajv@8.13.0: 481 | resolution: {integrity: sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA==} 482 | 483 | argparse@1.0.10: 484 | resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} 485 | 486 | assertion-error@2.0.1: 487 | resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} 488 | engines: {node: '>=12'} 489 | 490 | balanced-match@1.0.2: 491 | resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} 492 | 493 | brace-expansion@1.1.11: 494 | resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} 495 | 496 | brace-expansion@2.0.1: 497 | resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} 498 | 499 | buffer-from@1.1.2: 500 | resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} 501 | 502 | cac@6.7.14: 503 | resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} 504 | engines: {node: '>=8'} 505 | 506 | chai@5.1.2: 507 | resolution: {integrity: sha512-aGtmf24DW6MLHHG5gCx4zaI3uBq3KRtxeVs0DjFH6Z0rDNbsvTxFASFvdj79pxjxZ8/5u3PIiN3IwEIQkiiuPw==} 508 | engines: {node: '>=12'} 509 | 510 | check-error@2.1.1: 511 | resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} 512 | engines: {node: '>= 16'} 513 | 514 | commander@2.20.3: 515 | resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} 516 | 517 | compare-versions@6.1.1: 518 | resolution: {integrity: sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==} 519 | 520 | computeds@0.0.1: 521 | resolution: {integrity: sha512-7CEBgcMjVmitjYo5q8JTJVra6X5mQ20uTThdK+0kR7UEaDrAWEQcRiBtWJzga4eRpP6afNwwLsX2SET2JhVB1Q==} 522 | 523 | concat-map@0.0.1: 524 | resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} 525 | 526 | confbox@0.1.8: 527 | resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} 528 | 529 | de-indent@1.0.2: 530 | resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==} 531 | 532 | debug@4.3.7: 533 | resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} 534 | engines: {node: '>=6.0'} 535 | peerDependencies: 536 | supports-color: '*' 537 | peerDependenciesMeta: 538 | supports-color: 539 | optional: true 540 | 541 | deep-eql@5.0.2: 542 | resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} 543 | engines: {node: '>=6'} 544 | 545 | entities@4.5.0: 546 | resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} 547 | engines: {node: '>=0.12'} 548 | 549 | es-module-lexer@1.5.4: 550 | resolution: {integrity: sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==} 551 | 552 | esbuild@0.21.5: 553 | resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} 554 | engines: {node: '>=12'} 555 | hasBin: true 556 | 557 | estree-walker@2.0.2: 558 | resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} 559 | 560 | estree-walker@3.0.3: 561 | resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} 562 | 563 | expect-type@1.1.0: 564 | resolution: {integrity: sha512-bFi65yM+xZgk+u/KRIpekdSYkTB5W1pEf0Lt8Q8Msh7b+eQ7LXVtIB1Bkm4fvclDEL1b2CZkMhv2mOeF8tMdkA==} 565 | engines: {node: '>=12.0.0'} 566 | 567 | fast-deep-equal@3.1.3: 568 | resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} 569 | 570 | fs-extra@7.0.1: 571 | resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} 572 | engines: {node: '>=6 <7 || >=8'} 573 | 574 | fsevents@2.3.3: 575 | resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} 576 | engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} 577 | os: [darwin] 578 | 579 | function-bind@1.1.2: 580 | resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} 581 | 582 | graceful-fs@4.2.11: 583 | resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} 584 | 585 | has-flag@4.0.0: 586 | resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} 587 | engines: {node: '>=8'} 588 | 589 | hasown@2.0.2: 590 | resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} 591 | engines: {node: '>= 0.4'} 592 | 593 | he@1.2.0: 594 | resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} 595 | hasBin: true 596 | 597 | import-lazy@4.0.0: 598 | resolution: {integrity: sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==} 599 | engines: {node: '>=8'} 600 | 601 | is-core-module@2.15.1: 602 | resolution: {integrity: sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==} 603 | engines: {node: '>= 0.4'} 604 | 605 | jju@1.4.0: 606 | resolution: {integrity: sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==} 607 | 608 | json-schema-traverse@1.0.0: 609 | resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} 610 | 611 | jsonfile@4.0.0: 612 | resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} 613 | 614 | kolorist@1.8.0: 615 | resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==} 616 | 617 | local-pkg@0.5.1: 618 | resolution: {integrity: sha512-9rrA30MRRP3gBD3HTGnC6cDFpaE1kVDWxWgqWJUN0RvDNAo+Nz/9GxB+nHOH0ifbVFy0hSA1V6vFDvnx54lTEQ==} 619 | engines: {node: '>=14'} 620 | 621 | lodash@4.17.21: 622 | resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} 623 | 624 | long@4.0.0: 625 | resolution: {integrity: sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==} 626 | 627 | loupe@3.1.2: 628 | resolution: {integrity: sha512-23I4pFZHmAemUnz8WZXbYRSKYj801VDaNv9ETuMh7IrMc7VuVVSo+Z9iLE3ni30+U48iDWfi30d3twAXBYmnCg==} 629 | 630 | lru-cache@6.0.0: 631 | resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} 632 | engines: {node: '>=10'} 633 | 634 | magic-string@0.30.13: 635 | resolution: {integrity: sha512-8rYBO+MsWkgjDSOvLomYnzhdwEG51olQ4zL5KXnNJWV5MNmrb4rTZdrtkhxjnD/QyZUqR/Z/XDsUs/4ej2nx0g==} 636 | 637 | minimatch@3.0.8: 638 | resolution: {integrity: sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==} 639 | 640 | minimatch@9.0.5: 641 | resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} 642 | engines: {node: '>=16 || 14 >=14.17'} 643 | 644 | mlly@1.7.3: 645 | resolution: {integrity: sha512-xUsx5n/mN0uQf4V548PKQ+YShA4/IW0KI1dZhrNrPCLG+xizETbHTkOa1f8/xut9JRPp8kQuMnz0oqwkTiLo/A==} 646 | 647 | ms@2.1.3: 648 | resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} 649 | 650 | muggle-string@0.4.1: 651 | resolution: {integrity: sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==} 652 | 653 | nanoid@3.3.7: 654 | resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} 655 | engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} 656 | hasBin: true 657 | 658 | node-fetch@2.6.13: 659 | resolution: {integrity: sha512-StxNAxh15zr77QvvkmveSQ8uCQ4+v5FkvNTj0OESmiHu+VRi/gXArXtkWMElOsOUNLtUEvI4yS+rdtOHZTwlQA==} 660 | engines: {node: 4.x || >=6.0.0} 661 | peerDependencies: 662 | encoding: ^0.1.0 663 | peerDependenciesMeta: 664 | encoding: 665 | optional: true 666 | 667 | path-browserify@1.0.1: 668 | resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} 669 | 670 | path-parse@1.0.7: 671 | resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} 672 | 673 | pathe@1.1.2: 674 | resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} 675 | 676 | pathval@2.0.0: 677 | resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==} 678 | engines: {node: '>= 14.16'} 679 | 680 | picocolors@1.1.1: 681 | resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} 682 | 683 | picomatch@4.0.2: 684 | resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} 685 | engines: {node: '>=12'} 686 | 687 | pkg-types@1.2.1: 688 | resolution: {integrity: sha512-sQoqa8alT3nHjGuTjuKgOnvjo4cljkufdtLMnO2LBP/wRwuDlo1tkaEdMxCRhyGRPacv/ztlZgDPm2b7FAmEvw==} 689 | 690 | postcss@8.4.49: 691 | resolution: {integrity: sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==} 692 | engines: {node: ^10 || ^12 || >=14} 693 | 694 | prettier@2.8.8: 695 | resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} 696 | engines: {node: '>=10.13.0'} 697 | hasBin: true 698 | 699 | punycode@2.3.1: 700 | resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} 701 | engines: {node: '>=6'} 702 | 703 | require-from-string@2.0.2: 704 | resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} 705 | engines: {node: '>=0.10.0'} 706 | 707 | resolve@1.22.8: 708 | resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} 709 | hasBin: true 710 | 711 | rollup@4.27.3: 712 | resolution: {integrity: sha512-SLsCOnlmGt9VoZ9Ek8yBK8tAdmPHeppkw+Xa7yDlCEhDTvwYei03JlWo1fdc7YTfLZ4tD8riJCUyAgTbszk1fQ==} 713 | engines: {node: '>=18.0.0', npm: '>=8.0.0'} 714 | hasBin: true 715 | 716 | seedrandom@3.0.5: 717 | resolution: {integrity: sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==} 718 | 719 | semver@7.5.4: 720 | resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==} 721 | engines: {node: '>=10'} 722 | hasBin: true 723 | 724 | siginfo@2.0.0: 725 | resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} 726 | 727 | source-map-js@1.2.1: 728 | resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} 729 | engines: {node: '>=0.10.0'} 730 | 731 | source-map-support@0.5.21: 732 | resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} 733 | 734 | source-map@0.6.1: 735 | resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} 736 | engines: {node: '>=0.10.0'} 737 | 738 | sprintf-js@1.0.3: 739 | resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} 740 | 741 | stackback@0.0.2: 742 | resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} 743 | 744 | std-env@3.8.0: 745 | resolution: {integrity: sha512-Bc3YwwCB+OzldMxOXJIIvC6cPRWr/LxOp48CdQTOkPyk/t4JWWJbrilwBd7RJzKV8QW7tJkcgAmeuLLJugl5/w==} 746 | 747 | string-argv@0.3.2: 748 | resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==} 749 | engines: {node: '>=0.6.19'} 750 | 751 | strip-json-comments@3.1.1: 752 | resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} 753 | engines: {node: '>=8'} 754 | 755 | supports-color@8.1.1: 756 | resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} 757 | engines: {node: '>=10'} 758 | 759 | supports-preserve-symlinks-flag@1.0.0: 760 | resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} 761 | engines: {node: '>= 0.4'} 762 | 763 | terser@5.36.0: 764 | resolution: {integrity: sha512-IYV9eNMuFAV4THUspIRXkLakHnV6XO7FEdtKjf/mDyrnqUg9LnlOn6/RwRvM9SZjR4GUq8Nk8zj67FzVARr74w==} 765 | engines: {node: '>=10'} 766 | hasBin: true 767 | 768 | tinybench@2.9.0: 769 | resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} 770 | 771 | tinyexec@0.3.1: 772 | resolution: {integrity: sha512-WiCJLEECkO18gwqIp6+hJg0//p23HXp4S+gGtAKu3mI2F2/sXC4FvHvXvB0zJVVaTPhx1/tOwdbRsa1sOBIKqQ==} 773 | 774 | tinypool@1.0.2: 775 | resolution: {integrity: sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA==} 776 | engines: {node: ^18.0.0 || >=20.0.0} 777 | 778 | tinyrainbow@1.2.0: 779 | resolution: {integrity: sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==} 780 | engines: {node: '>=14.0.0'} 781 | 782 | tinyspy@3.0.2: 783 | resolution: {integrity: sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==} 784 | engines: {node: '>=14.0.0'} 785 | 786 | tr46@0.0.3: 787 | resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} 788 | 789 | typescript@4.9.5: 790 | resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==} 791 | engines: {node: '>=4.2.0'} 792 | hasBin: true 793 | 794 | typescript@5.4.2: 795 | resolution: {integrity: sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==} 796 | engines: {node: '>=14.17'} 797 | hasBin: true 798 | 799 | ufo@1.5.4: 800 | resolution: {integrity: sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==} 801 | 802 | universalify@0.1.2: 803 | resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} 804 | engines: {node: '>= 4.0.0'} 805 | 806 | uri-js@4.4.1: 807 | resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} 808 | 809 | vite-node@2.1.5: 810 | resolution: {integrity: sha512-rd0QIgx74q4S1Rd56XIiL2cYEdyWn13cunYBIuqh9mpmQr7gGS0IxXoP8R6OaZtNQQLyXSWbd4rXKYUbhFpK5w==} 811 | engines: {node: ^18.0.0 || >=20.0.0} 812 | hasBin: true 813 | 814 | vite-plugin-dts@4.3.0: 815 | resolution: {integrity: sha512-LkBJh9IbLwL6/rxh0C1/bOurDrIEmRE7joC+jFdOEEciAFPbpEKOLSAr5nNh5R7CJ45cMbksTrFfy52szzC5eA==} 816 | engines: {node: ^14.18.0 || >=16.0.0} 817 | peerDependencies: 818 | typescript: '*' 819 | vite: '*' 820 | peerDependenciesMeta: 821 | vite: 822 | optional: true 823 | 824 | vite@5.4.11: 825 | resolution: {integrity: sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q==} 826 | engines: {node: ^18.0.0 || >=20.0.0} 827 | hasBin: true 828 | peerDependencies: 829 | '@types/node': ^18.0.0 || >=20.0.0 830 | less: '*' 831 | lightningcss: ^1.21.0 832 | sass: '*' 833 | sass-embedded: '*' 834 | stylus: '*' 835 | sugarss: '*' 836 | terser: ^5.4.0 837 | peerDependenciesMeta: 838 | '@types/node': 839 | optional: true 840 | less: 841 | optional: true 842 | lightningcss: 843 | optional: true 844 | sass: 845 | optional: true 846 | sass-embedded: 847 | optional: true 848 | stylus: 849 | optional: true 850 | sugarss: 851 | optional: true 852 | terser: 853 | optional: true 854 | 855 | vitest@2.1.5: 856 | resolution: {integrity: sha512-P4ljsdpuzRTPI/kbND2sDZ4VmieerR2c9szEZpjc+98Z9ebvnXmM5+0tHEKqYZumXqlvnmfWsjeFOjXVriDG7A==} 857 | engines: {node: ^18.0.0 || >=20.0.0} 858 | hasBin: true 859 | peerDependencies: 860 | '@edge-runtime/vm': '*' 861 | '@types/node': ^18.0.0 || >=20.0.0 862 | '@vitest/browser': 2.1.5 863 | '@vitest/ui': 2.1.5 864 | happy-dom: '*' 865 | jsdom: '*' 866 | peerDependenciesMeta: 867 | '@edge-runtime/vm': 868 | optional: true 869 | '@types/node': 870 | optional: true 871 | '@vitest/browser': 872 | optional: true 873 | '@vitest/ui': 874 | optional: true 875 | happy-dom: 876 | optional: true 877 | jsdom: 878 | optional: true 879 | 880 | vscode-uri@3.0.8: 881 | resolution: {integrity: sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==} 882 | 883 | webidl-conversions@3.0.1: 884 | resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} 885 | 886 | whatwg-url@5.0.0: 887 | resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} 888 | 889 | why-is-node-running@2.3.0: 890 | resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} 891 | engines: {node: '>=8'} 892 | hasBin: true 893 | 894 | yallist@4.0.0: 895 | resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} 896 | 897 | snapshots: 898 | 899 | '@babel/helper-string-parser@7.25.9': {} 900 | 901 | '@babel/helper-validator-identifier@7.25.9': {} 902 | 903 | '@babel/parser@7.26.2': 904 | dependencies: 905 | '@babel/types': 7.26.0 906 | 907 | '@babel/types@7.26.0': 908 | dependencies: 909 | '@babel/helper-string-parser': 7.25.9 910 | '@babel/helper-validator-identifier': 7.25.9 911 | 912 | '@esbuild/aix-ppc64@0.21.5': 913 | optional: true 914 | 915 | '@esbuild/android-arm64@0.21.5': 916 | optional: true 917 | 918 | '@esbuild/android-arm@0.21.5': 919 | optional: true 920 | 921 | '@esbuild/android-x64@0.21.5': 922 | optional: true 923 | 924 | '@esbuild/darwin-arm64@0.21.5': 925 | optional: true 926 | 927 | '@esbuild/darwin-x64@0.21.5': 928 | optional: true 929 | 930 | '@esbuild/freebsd-arm64@0.21.5': 931 | optional: true 932 | 933 | '@esbuild/freebsd-x64@0.21.5': 934 | optional: true 935 | 936 | '@esbuild/linux-arm64@0.21.5': 937 | optional: true 938 | 939 | '@esbuild/linux-arm@0.21.5': 940 | optional: true 941 | 942 | '@esbuild/linux-ia32@0.21.5': 943 | optional: true 944 | 945 | '@esbuild/linux-loong64@0.21.5': 946 | optional: true 947 | 948 | '@esbuild/linux-mips64el@0.21.5': 949 | optional: true 950 | 951 | '@esbuild/linux-ppc64@0.21.5': 952 | optional: true 953 | 954 | '@esbuild/linux-riscv64@0.21.5': 955 | optional: true 956 | 957 | '@esbuild/linux-s390x@0.21.5': 958 | optional: true 959 | 960 | '@esbuild/linux-x64@0.21.5': 961 | optional: true 962 | 963 | '@esbuild/netbsd-x64@0.21.5': 964 | optional: true 965 | 966 | '@esbuild/openbsd-x64@0.21.5': 967 | optional: true 968 | 969 | '@esbuild/sunos-x64@0.21.5': 970 | optional: true 971 | 972 | '@esbuild/win32-arm64@0.21.5': 973 | optional: true 974 | 975 | '@esbuild/win32-ia32@0.21.5': 976 | optional: true 977 | 978 | '@esbuild/win32-x64@0.21.5': 979 | optional: true 980 | 981 | '@jridgewell/gen-mapping@0.3.5': 982 | dependencies: 983 | '@jridgewell/set-array': 1.2.1 984 | '@jridgewell/sourcemap-codec': 1.5.0 985 | '@jridgewell/trace-mapping': 0.3.25 986 | optional: true 987 | 988 | '@jridgewell/resolve-uri@3.1.2': 989 | optional: true 990 | 991 | '@jridgewell/set-array@1.2.1': 992 | optional: true 993 | 994 | '@jridgewell/source-map@0.3.6': 995 | dependencies: 996 | '@jridgewell/gen-mapping': 0.3.5 997 | '@jridgewell/trace-mapping': 0.3.25 998 | optional: true 999 | 1000 | '@jridgewell/sourcemap-codec@1.5.0': {} 1001 | 1002 | '@jridgewell/trace-mapping@0.3.25': 1003 | dependencies: 1004 | '@jridgewell/resolve-uri': 3.1.2 1005 | '@jridgewell/sourcemap-codec': 1.5.0 1006 | optional: true 1007 | 1008 | '@microsoft/api-extractor-model@7.29.8(@types/node@16.18.119)': 1009 | dependencies: 1010 | '@microsoft/tsdoc': 0.15.0 1011 | '@microsoft/tsdoc-config': 0.17.0 1012 | '@rushstack/node-core-library': 5.9.0(@types/node@16.18.119) 1013 | transitivePeerDependencies: 1014 | - '@types/node' 1015 | 1016 | '@microsoft/api-extractor@7.47.11(@types/node@16.18.119)': 1017 | dependencies: 1018 | '@microsoft/api-extractor-model': 7.29.8(@types/node@16.18.119) 1019 | '@microsoft/tsdoc': 0.15.0 1020 | '@microsoft/tsdoc-config': 0.17.0 1021 | '@rushstack/node-core-library': 5.9.0(@types/node@16.18.119) 1022 | '@rushstack/rig-package': 0.5.3 1023 | '@rushstack/terminal': 0.14.2(@types/node@16.18.119) 1024 | '@rushstack/ts-command-line': 4.23.0(@types/node@16.18.119) 1025 | lodash: 4.17.21 1026 | minimatch: 3.0.8 1027 | resolve: 1.22.8 1028 | semver: 7.5.4 1029 | source-map: 0.6.1 1030 | typescript: 5.4.2 1031 | transitivePeerDependencies: 1032 | - '@types/node' 1033 | 1034 | '@microsoft/tsdoc-config@0.17.0': 1035 | dependencies: 1036 | '@microsoft/tsdoc': 0.15.0 1037 | ajv: 8.12.0 1038 | jju: 1.4.0 1039 | resolve: 1.22.8 1040 | 1041 | '@microsoft/tsdoc@0.15.0': {} 1042 | 1043 | '@rollup/pluginutils@5.1.3(rollup@4.27.3)': 1044 | dependencies: 1045 | '@types/estree': 1.0.6 1046 | estree-walker: 2.0.2 1047 | picomatch: 4.0.2 1048 | optionalDependencies: 1049 | rollup: 4.27.3 1050 | 1051 | '@rollup/rollup-android-arm-eabi@4.27.3': 1052 | optional: true 1053 | 1054 | '@rollup/rollup-android-arm64@4.27.3': 1055 | optional: true 1056 | 1057 | '@rollup/rollup-darwin-arm64@4.27.3': 1058 | optional: true 1059 | 1060 | '@rollup/rollup-darwin-x64@4.27.3': 1061 | optional: true 1062 | 1063 | '@rollup/rollup-freebsd-arm64@4.27.3': 1064 | optional: true 1065 | 1066 | '@rollup/rollup-freebsd-x64@4.27.3': 1067 | optional: true 1068 | 1069 | '@rollup/rollup-linux-arm-gnueabihf@4.27.3': 1070 | optional: true 1071 | 1072 | '@rollup/rollup-linux-arm-musleabihf@4.27.3': 1073 | optional: true 1074 | 1075 | '@rollup/rollup-linux-arm64-gnu@4.27.3': 1076 | optional: true 1077 | 1078 | '@rollup/rollup-linux-arm64-musl@4.27.3': 1079 | optional: true 1080 | 1081 | '@rollup/rollup-linux-powerpc64le-gnu@4.27.3': 1082 | optional: true 1083 | 1084 | '@rollup/rollup-linux-riscv64-gnu@4.27.3': 1085 | optional: true 1086 | 1087 | '@rollup/rollup-linux-s390x-gnu@4.27.3': 1088 | optional: true 1089 | 1090 | '@rollup/rollup-linux-x64-gnu@4.27.3': 1091 | optional: true 1092 | 1093 | '@rollup/rollup-linux-x64-musl@4.27.3': 1094 | optional: true 1095 | 1096 | '@rollup/rollup-win32-arm64-msvc@4.27.3': 1097 | optional: true 1098 | 1099 | '@rollup/rollup-win32-ia32-msvc@4.27.3': 1100 | optional: true 1101 | 1102 | '@rollup/rollup-win32-x64-msvc@4.27.3': 1103 | optional: true 1104 | 1105 | '@rushstack/node-core-library@5.9.0(@types/node@16.18.119)': 1106 | dependencies: 1107 | ajv: 8.13.0 1108 | ajv-draft-04: 1.0.0(ajv@8.13.0) 1109 | ajv-formats: 3.0.1(ajv@8.13.0) 1110 | fs-extra: 7.0.1 1111 | import-lazy: 4.0.0 1112 | jju: 1.4.0 1113 | resolve: 1.22.8 1114 | semver: 7.5.4 1115 | optionalDependencies: 1116 | '@types/node': 16.18.119 1117 | 1118 | '@rushstack/rig-package@0.5.3': 1119 | dependencies: 1120 | resolve: 1.22.8 1121 | strip-json-comments: 3.1.1 1122 | 1123 | '@rushstack/terminal@0.14.2(@types/node@16.18.119)': 1124 | dependencies: 1125 | '@rushstack/node-core-library': 5.9.0(@types/node@16.18.119) 1126 | supports-color: 8.1.1 1127 | optionalDependencies: 1128 | '@types/node': 16.18.119 1129 | 1130 | '@rushstack/ts-command-line@4.23.0(@types/node@16.18.119)': 1131 | dependencies: 1132 | '@rushstack/terminal': 0.14.2(@types/node@16.18.119) 1133 | '@types/argparse': 1.0.38 1134 | argparse: 1.0.10 1135 | string-argv: 0.3.2 1136 | transitivePeerDependencies: 1137 | - '@types/node' 1138 | 1139 | '@tensorflow/tfjs-backend-cpu@3.21.0(@tensorflow/tfjs-core@3.21.0)': 1140 | dependencies: 1141 | '@tensorflow/tfjs-core': 3.21.0 1142 | '@types/seedrandom': 2.4.34 1143 | seedrandom: 3.0.5 1144 | 1145 | '@tensorflow/tfjs-converter@3.21.0(@tensorflow/tfjs-core@3.21.0)': 1146 | dependencies: 1147 | '@tensorflow/tfjs-core': 3.21.0 1148 | 1149 | '@tensorflow/tfjs-core@3.21.0': 1150 | dependencies: 1151 | '@types/long': 4.0.2 1152 | '@types/offscreencanvas': 2019.3.0 1153 | '@types/seedrandom': 2.4.34 1154 | '@types/webgl-ext': 0.0.30 1155 | '@webgpu/types': 0.1.16 1156 | long: 4.0.0 1157 | node-fetch: 2.6.13 1158 | seedrandom: 3.0.5 1159 | transitivePeerDependencies: 1160 | - encoding 1161 | 1162 | '@types/argparse@1.0.38': {} 1163 | 1164 | '@types/estree@1.0.6': {} 1165 | 1166 | '@types/long@4.0.2': {} 1167 | 1168 | '@types/node@16.18.119': {} 1169 | 1170 | '@types/offscreencanvas@2019.3.0': {} 1171 | 1172 | '@types/seedrandom@2.4.34': {} 1173 | 1174 | '@types/webgl-ext@0.0.30': {} 1175 | 1176 | '@vitest/expect@2.1.5': 1177 | dependencies: 1178 | '@vitest/spy': 2.1.5 1179 | '@vitest/utils': 2.1.5 1180 | chai: 5.1.2 1181 | tinyrainbow: 1.2.0 1182 | 1183 | '@vitest/mocker@2.1.5(vite@5.4.11(@types/node@16.18.119)(terser@5.36.0))': 1184 | dependencies: 1185 | '@vitest/spy': 2.1.5 1186 | estree-walker: 3.0.3 1187 | magic-string: 0.30.13 1188 | optionalDependencies: 1189 | vite: 5.4.11(@types/node@16.18.119)(terser@5.36.0) 1190 | 1191 | '@vitest/pretty-format@2.1.5': 1192 | dependencies: 1193 | tinyrainbow: 1.2.0 1194 | 1195 | '@vitest/runner@2.1.5': 1196 | dependencies: 1197 | '@vitest/utils': 2.1.5 1198 | pathe: 1.1.2 1199 | 1200 | '@vitest/snapshot@2.1.5': 1201 | dependencies: 1202 | '@vitest/pretty-format': 2.1.5 1203 | magic-string: 0.30.13 1204 | pathe: 1.1.2 1205 | 1206 | '@vitest/spy@2.1.5': 1207 | dependencies: 1208 | tinyspy: 3.0.2 1209 | 1210 | '@vitest/utils@2.1.5': 1211 | dependencies: 1212 | '@vitest/pretty-format': 2.1.5 1213 | loupe: 3.1.2 1214 | tinyrainbow: 1.2.0 1215 | 1216 | '@vitest/web-worker@2.1.5(vitest@2.1.5(@types/node@16.18.119)(terser@5.36.0))': 1217 | dependencies: 1218 | debug: 4.3.7 1219 | vitest: 2.1.5(@types/node@16.18.119)(terser@5.36.0) 1220 | transitivePeerDependencies: 1221 | - supports-color 1222 | 1223 | '@volar/language-core@2.4.10': 1224 | dependencies: 1225 | '@volar/source-map': 2.4.10 1226 | 1227 | '@volar/source-map@2.4.10': {} 1228 | 1229 | '@volar/typescript@2.4.10': 1230 | dependencies: 1231 | '@volar/language-core': 2.4.10 1232 | path-browserify: 1.0.1 1233 | vscode-uri: 3.0.8 1234 | 1235 | '@vue/compiler-core@3.5.13': 1236 | dependencies: 1237 | '@babel/parser': 7.26.2 1238 | '@vue/shared': 3.5.13 1239 | entities: 4.5.0 1240 | estree-walker: 2.0.2 1241 | source-map-js: 1.2.1 1242 | 1243 | '@vue/compiler-dom@3.5.13': 1244 | dependencies: 1245 | '@vue/compiler-core': 3.5.13 1246 | '@vue/shared': 3.5.13 1247 | 1248 | '@vue/compiler-vue2@2.7.16': 1249 | dependencies: 1250 | de-indent: 1.0.2 1251 | he: 1.2.0 1252 | 1253 | '@vue/language-core@2.1.6(typescript@4.9.5)': 1254 | dependencies: 1255 | '@volar/language-core': 2.4.10 1256 | '@vue/compiler-dom': 3.5.13 1257 | '@vue/compiler-vue2': 2.7.16 1258 | '@vue/shared': 3.5.13 1259 | computeds: 0.0.1 1260 | minimatch: 9.0.5 1261 | muggle-string: 0.4.1 1262 | path-browserify: 1.0.1 1263 | optionalDependencies: 1264 | typescript: 4.9.5 1265 | 1266 | '@vue/shared@3.5.13': {} 1267 | 1268 | '@webgpu/types@0.1.16': {} 1269 | 1270 | acorn@8.14.0: {} 1271 | 1272 | ajv-draft-04@1.0.0(ajv@8.13.0): 1273 | optionalDependencies: 1274 | ajv: 8.13.0 1275 | 1276 | ajv-formats@3.0.1(ajv@8.13.0): 1277 | optionalDependencies: 1278 | ajv: 8.13.0 1279 | 1280 | ajv@8.12.0: 1281 | dependencies: 1282 | fast-deep-equal: 3.1.3 1283 | json-schema-traverse: 1.0.0 1284 | require-from-string: 2.0.2 1285 | uri-js: 4.4.1 1286 | 1287 | ajv@8.13.0: 1288 | dependencies: 1289 | fast-deep-equal: 3.1.3 1290 | json-schema-traverse: 1.0.0 1291 | require-from-string: 2.0.2 1292 | uri-js: 4.4.1 1293 | 1294 | argparse@1.0.10: 1295 | dependencies: 1296 | sprintf-js: 1.0.3 1297 | 1298 | assertion-error@2.0.1: {} 1299 | 1300 | balanced-match@1.0.2: {} 1301 | 1302 | brace-expansion@1.1.11: 1303 | dependencies: 1304 | balanced-match: 1.0.2 1305 | concat-map: 0.0.1 1306 | 1307 | brace-expansion@2.0.1: 1308 | dependencies: 1309 | balanced-match: 1.0.2 1310 | 1311 | buffer-from@1.1.2: 1312 | optional: true 1313 | 1314 | cac@6.7.14: {} 1315 | 1316 | chai@5.1.2: 1317 | dependencies: 1318 | assertion-error: 2.0.1 1319 | check-error: 2.1.1 1320 | deep-eql: 5.0.2 1321 | loupe: 3.1.2 1322 | pathval: 2.0.0 1323 | 1324 | check-error@2.1.1: {} 1325 | 1326 | commander@2.20.3: 1327 | optional: true 1328 | 1329 | compare-versions@6.1.1: {} 1330 | 1331 | computeds@0.0.1: {} 1332 | 1333 | concat-map@0.0.1: {} 1334 | 1335 | confbox@0.1.8: {} 1336 | 1337 | de-indent@1.0.2: {} 1338 | 1339 | debug@4.3.7: 1340 | dependencies: 1341 | ms: 2.1.3 1342 | 1343 | deep-eql@5.0.2: {} 1344 | 1345 | entities@4.5.0: {} 1346 | 1347 | es-module-lexer@1.5.4: {} 1348 | 1349 | esbuild@0.21.5: 1350 | optionalDependencies: 1351 | '@esbuild/aix-ppc64': 0.21.5 1352 | '@esbuild/android-arm': 0.21.5 1353 | '@esbuild/android-arm64': 0.21.5 1354 | '@esbuild/android-x64': 0.21.5 1355 | '@esbuild/darwin-arm64': 0.21.5 1356 | '@esbuild/darwin-x64': 0.21.5 1357 | '@esbuild/freebsd-arm64': 0.21.5 1358 | '@esbuild/freebsd-x64': 0.21.5 1359 | '@esbuild/linux-arm': 0.21.5 1360 | '@esbuild/linux-arm64': 0.21.5 1361 | '@esbuild/linux-ia32': 0.21.5 1362 | '@esbuild/linux-loong64': 0.21.5 1363 | '@esbuild/linux-mips64el': 0.21.5 1364 | '@esbuild/linux-ppc64': 0.21.5 1365 | '@esbuild/linux-riscv64': 0.21.5 1366 | '@esbuild/linux-s390x': 0.21.5 1367 | '@esbuild/linux-x64': 0.21.5 1368 | '@esbuild/netbsd-x64': 0.21.5 1369 | '@esbuild/openbsd-x64': 0.21.5 1370 | '@esbuild/sunos-x64': 0.21.5 1371 | '@esbuild/win32-arm64': 0.21.5 1372 | '@esbuild/win32-ia32': 0.21.5 1373 | '@esbuild/win32-x64': 0.21.5 1374 | 1375 | estree-walker@2.0.2: {} 1376 | 1377 | estree-walker@3.0.3: 1378 | dependencies: 1379 | '@types/estree': 1.0.6 1380 | 1381 | expect-type@1.1.0: {} 1382 | 1383 | fast-deep-equal@3.1.3: {} 1384 | 1385 | fs-extra@7.0.1: 1386 | dependencies: 1387 | graceful-fs: 4.2.11 1388 | jsonfile: 4.0.0 1389 | universalify: 0.1.2 1390 | 1391 | fsevents@2.3.3: 1392 | optional: true 1393 | 1394 | function-bind@1.1.2: {} 1395 | 1396 | graceful-fs@4.2.11: {} 1397 | 1398 | has-flag@4.0.0: {} 1399 | 1400 | hasown@2.0.2: 1401 | dependencies: 1402 | function-bind: 1.1.2 1403 | 1404 | he@1.2.0: {} 1405 | 1406 | import-lazy@4.0.0: {} 1407 | 1408 | is-core-module@2.15.1: 1409 | dependencies: 1410 | hasown: 2.0.2 1411 | 1412 | jju@1.4.0: {} 1413 | 1414 | json-schema-traverse@1.0.0: {} 1415 | 1416 | jsonfile@4.0.0: 1417 | optionalDependencies: 1418 | graceful-fs: 4.2.11 1419 | 1420 | kolorist@1.8.0: {} 1421 | 1422 | local-pkg@0.5.1: 1423 | dependencies: 1424 | mlly: 1.7.3 1425 | pkg-types: 1.2.1 1426 | 1427 | lodash@4.17.21: {} 1428 | 1429 | long@4.0.0: {} 1430 | 1431 | loupe@3.1.2: {} 1432 | 1433 | lru-cache@6.0.0: 1434 | dependencies: 1435 | yallist: 4.0.0 1436 | 1437 | magic-string@0.30.13: 1438 | dependencies: 1439 | '@jridgewell/sourcemap-codec': 1.5.0 1440 | 1441 | minimatch@3.0.8: 1442 | dependencies: 1443 | brace-expansion: 1.1.11 1444 | 1445 | minimatch@9.0.5: 1446 | dependencies: 1447 | brace-expansion: 2.0.1 1448 | 1449 | mlly@1.7.3: 1450 | dependencies: 1451 | acorn: 8.14.0 1452 | pathe: 1.1.2 1453 | pkg-types: 1.2.1 1454 | ufo: 1.5.4 1455 | 1456 | ms@2.1.3: {} 1457 | 1458 | muggle-string@0.4.1: {} 1459 | 1460 | nanoid@3.3.7: {} 1461 | 1462 | node-fetch@2.6.13: 1463 | dependencies: 1464 | whatwg-url: 5.0.0 1465 | 1466 | path-browserify@1.0.1: {} 1467 | 1468 | path-parse@1.0.7: {} 1469 | 1470 | pathe@1.1.2: {} 1471 | 1472 | pathval@2.0.0: {} 1473 | 1474 | picocolors@1.1.1: {} 1475 | 1476 | picomatch@4.0.2: {} 1477 | 1478 | pkg-types@1.2.1: 1479 | dependencies: 1480 | confbox: 0.1.8 1481 | mlly: 1.7.3 1482 | pathe: 1.1.2 1483 | 1484 | postcss@8.4.49: 1485 | dependencies: 1486 | nanoid: 3.3.7 1487 | picocolors: 1.1.1 1488 | source-map-js: 1.2.1 1489 | 1490 | prettier@2.8.8: {} 1491 | 1492 | punycode@2.3.1: {} 1493 | 1494 | require-from-string@2.0.2: {} 1495 | 1496 | resolve@1.22.8: 1497 | dependencies: 1498 | is-core-module: 2.15.1 1499 | path-parse: 1.0.7 1500 | supports-preserve-symlinks-flag: 1.0.0 1501 | 1502 | rollup@4.27.3: 1503 | dependencies: 1504 | '@types/estree': 1.0.6 1505 | optionalDependencies: 1506 | '@rollup/rollup-android-arm-eabi': 4.27.3 1507 | '@rollup/rollup-android-arm64': 4.27.3 1508 | '@rollup/rollup-darwin-arm64': 4.27.3 1509 | '@rollup/rollup-darwin-x64': 4.27.3 1510 | '@rollup/rollup-freebsd-arm64': 4.27.3 1511 | '@rollup/rollup-freebsd-x64': 4.27.3 1512 | '@rollup/rollup-linux-arm-gnueabihf': 4.27.3 1513 | '@rollup/rollup-linux-arm-musleabihf': 4.27.3 1514 | '@rollup/rollup-linux-arm64-gnu': 4.27.3 1515 | '@rollup/rollup-linux-arm64-musl': 4.27.3 1516 | '@rollup/rollup-linux-powerpc64le-gnu': 4.27.3 1517 | '@rollup/rollup-linux-riscv64-gnu': 4.27.3 1518 | '@rollup/rollup-linux-s390x-gnu': 4.27.3 1519 | '@rollup/rollup-linux-x64-gnu': 4.27.3 1520 | '@rollup/rollup-linux-x64-musl': 4.27.3 1521 | '@rollup/rollup-win32-arm64-msvc': 4.27.3 1522 | '@rollup/rollup-win32-ia32-msvc': 4.27.3 1523 | '@rollup/rollup-win32-x64-msvc': 4.27.3 1524 | fsevents: 2.3.3 1525 | 1526 | seedrandom@3.0.5: {} 1527 | 1528 | semver@7.5.4: 1529 | dependencies: 1530 | lru-cache: 6.0.0 1531 | 1532 | siginfo@2.0.0: {} 1533 | 1534 | source-map-js@1.2.1: {} 1535 | 1536 | source-map-support@0.5.21: 1537 | dependencies: 1538 | buffer-from: 1.1.2 1539 | source-map: 0.6.1 1540 | optional: true 1541 | 1542 | source-map@0.6.1: {} 1543 | 1544 | sprintf-js@1.0.3: {} 1545 | 1546 | stackback@0.0.2: {} 1547 | 1548 | std-env@3.8.0: {} 1549 | 1550 | string-argv@0.3.2: {} 1551 | 1552 | strip-json-comments@3.1.1: {} 1553 | 1554 | supports-color@8.1.1: 1555 | dependencies: 1556 | has-flag: 4.0.0 1557 | 1558 | supports-preserve-symlinks-flag@1.0.0: {} 1559 | 1560 | terser@5.36.0: 1561 | dependencies: 1562 | '@jridgewell/source-map': 0.3.6 1563 | acorn: 8.14.0 1564 | commander: 2.20.3 1565 | source-map-support: 0.5.21 1566 | optional: true 1567 | 1568 | tinybench@2.9.0: {} 1569 | 1570 | tinyexec@0.3.1: {} 1571 | 1572 | tinypool@1.0.2: {} 1573 | 1574 | tinyrainbow@1.2.0: {} 1575 | 1576 | tinyspy@3.0.2: {} 1577 | 1578 | tr46@0.0.3: {} 1579 | 1580 | typescript@4.9.5: {} 1581 | 1582 | typescript@5.4.2: {} 1583 | 1584 | ufo@1.5.4: {} 1585 | 1586 | universalify@0.1.2: {} 1587 | 1588 | uri-js@4.4.1: 1589 | dependencies: 1590 | punycode: 2.3.1 1591 | 1592 | vite-node@2.1.5(@types/node@16.18.119)(terser@5.36.0): 1593 | dependencies: 1594 | cac: 6.7.14 1595 | debug: 4.3.7 1596 | es-module-lexer: 1.5.4 1597 | pathe: 1.1.2 1598 | vite: 5.4.11(@types/node@16.18.119)(terser@5.36.0) 1599 | transitivePeerDependencies: 1600 | - '@types/node' 1601 | - less 1602 | - lightningcss 1603 | - sass 1604 | - sass-embedded 1605 | - stylus 1606 | - sugarss 1607 | - supports-color 1608 | - terser 1609 | 1610 | vite-plugin-dts@4.3.0(@types/node@16.18.119)(rollup@4.27.3)(typescript@4.9.5)(vite@5.4.11(@types/node@16.18.119)(terser@5.36.0)): 1611 | dependencies: 1612 | '@microsoft/api-extractor': 7.47.11(@types/node@16.18.119) 1613 | '@rollup/pluginutils': 5.1.3(rollup@4.27.3) 1614 | '@volar/typescript': 2.4.10 1615 | '@vue/language-core': 2.1.6(typescript@4.9.5) 1616 | compare-versions: 6.1.1 1617 | debug: 4.3.7 1618 | kolorist: 1.8.0 1619 | local-pkg: 0.5.1 1620 | magic-string: 0.30.13 1621 | typescript: 4.9.5 1622 | optionalDependencies: 1623 | vite: 5.4.11(@types/node@16.18.119)(terser@5.36.0) 1624 | transitivePeerDependencies: 1625 | - '@types/node' 1626 | - rollup 1627 | - supports-color 1628 | 1629 | vite@5.4.11(@types/node@16.18.119)(terser@5.36.0): 1630 | dependencies: 1631 | esbuild: 0.21.5 1632 | postcss: 8.4.49 1633 | rollup: 4.27.3 1634 | optionalDependencies: 1635 | '@types/node': 16.18.119 1636 | fsevents: 2.3.3 1637 | terser: 5.36.0 1638 | 1639 | vitest@2.1.5(@types/node@16.18.119)(terser@5.36.0): 1640 | dependencies: 1641 | '@vitest/expect': 2.1.5 1642 | '@vitest/mocker': 2.1.5(vite@5.4.11(@types/node@16.18.119)(terser@5.36.0)) 1643 | '@vitest/pretty-format': 2.1.5 1644 | '@vitest/runner': 2.1.5 1645 | '@vitest/snapshot': 2.1.5 1646 | '@vitest/spy': 2.1.5 1647 | '@vitest/utils': 2.1.5 1648 | chai: 5.1.2 1649 | debug: 4.3.7 1650 | expect-type: 1.1.0 1651 | magic-string: 0.30.13 1652 | pathe: 1.1.2 1653 | std-env: 3.8.0 1654 | tinybench: 2.9.0 1655 | tinyexec: 0.3.1 1656 | tinypool: 1.0.2 1657 | tinyrainbow: 1.2.0 1658 | vite: 5.4.11(@types/node@16.18.119)(terser@5.36.0) 1659 | vite-node: 2.1.5(@types/node@16.18.119)(terser@5.36.0) 1660 | why-is-node-running: 2.3.0 1661 | optionalDependencies: 1662 | '@types/node': 16.18.119 1663 | transitivePeerDependencies: 1664 | - less 1665 | - lightningcss 1666 | - msw 1667 | - sass 1668 | - sass-embedded 1669 | - stylus 1670 | - sugarss 1671 | - supports-color 1672 | - terser 1673 | 1674 | vscode-uri@3.0.8: {} 1675 | 1676 | webidl-conversions@3.0.1: {} 1677 | 1678 | whatwg-url@5.0.0: 1679 | dependencies: 1680 | tr46: 0.0.3 1681 | webidl-conversions: 3.0.1 1682 | 1683 | why-is-node-running@2.3.0: 1684 | dependencies: 1685 | siginfo: 2.0.0 1686 | stackback: 0.0.2 1687 | 1688 | yallist@4.0.0: {} 1689 | --------------------------------------------------------------------------------