From 2e02a6b6feb66006490d65490e7ff777d76ee3f9 Mon Sep 17 00:00:00 2001 From: Krisztian Somoracz Date: Wed, 15 Oct 2025 23:53:56 +0200 Subject: [PATCH 01/20] feat: modernize npm package structure and add TypeScript support - Update package.json with modern npm package configuration - Add comprehensive devDependencies for build, test, and code quality - Create tsconfig.json with ES2020 target and strict TypeScript settings - Convert JavaScript modules to TypeScript with proper typing - Add new src/ structure with TypeScript files - Maintain backward compatibility with existing exports - Prepare for build system with webpack and testing with jest --- package.json | 85 ++++++++++++++++++++++++++++++++++------ src/assets/assets.ts | 9 +++++ src/assets/index.ts | 1 + src/audio/audio.ts | 9 +++++ src/audio/index.ts | 1 + src/callback-utils.ts | 72 ++++++++++++++++++++++++++++++++++ src/dispose-utils.ts | 33 ++++++++++++++++ src/geom-utils.ts | 56 +++++++++++++++++++++++++++ src/index.ts | 7 ++++ src/object-utils.ts | 90 +++++++++++++++++++++++++++++++++++++++++++ src/time-utils.ts | 43 +++++++++++++++++++++ src/token.ts | 2 + src/vector3-utils.ts | 9 +++++ tsconfig.json | 30 +++++++++++++++ 14 files changed, 435 insertions(+), 12 deletions(-) create mode 100644 src/assets/assets.ts create mode 100644 src/assets/index.ts create mode 100644 src/audio/audio.ts create mode 100644 src/audio/index.ts create mode 100644 src/callback-utils.ts create mode 100644 src/dispose-utils.ts create mode 100644 src/geom-utils.ts create mode 100644 src/index.ts create mode 100644 src/object-utils.ts create mode 100644 src/time-utils.ts create mode 100644 src/token.ts create mode 100644 src/vector3-utils.ts create mode 100644 tsconfig.json diff --git a/package.json b/package.json index d4f141b..7de6287 100644 --- a/package.json +++ b/package.json @@ -1,25 +1,51 @@ { "name": "@newkrok/three-utils", "version": "1.1.0", - "description": "THREE JS related utils", "type": "module", + "description": "Three.js-based utility library providing essential tools for THREE.js applications including assets loading, audio management, geometry utilities, and more.", + "main": "./dist/index.js", + "module": "./dist/index.js", + "types": "./dist/index.d.ts", + "files": [ + "dist/", + "README.md", + "LICENSE" + ], "exports": { - ".": "./src/js/newkrok/three-utils/index.js", - "./src/*": "./src/*", - "./assets": "./src/js/newkrok/three-utils/assets/index.js", - "./audio": "./src/js/newkrok/three-utils/audio/index.js" + ".": { + "import": "./dist/index.js", + "require": "./dist/index.js" + }, + "./assets": { + "import": "./dist/assets/index.js", + "require": "./dist/assets/index.js" + }, + "./audio": { + "import": "./dist/audio/index.js", + "require": "./dist/audio/index.js" + } }, "repository": { "type": "git", - "url": "git+https://github.com/NewKrok/three-utils.git" + "url": "https://github.com/NewKrok/three-utils.git" }, "keywords": [ + "three", + "three.js", "threejs", "utils", + "utilities", "assets", "audio", "texture", - "model" + "model", + "webgl", + "3d", + "geometry", + "javascript", + "typescript", + "game development", + "3d applications" ], "author": "Istvan Krisztian Somoracz", "license": "MIT", @@ -27,10 +53,45 @@ "url": "https://github.com/NewKrok/three-utils/issues" }, "homepage": "https://github.com/NewKrok/three-utils#readme", - "dependencies": { - "three": "^0.141.0" - }, "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" + "build": "rimraf dist && tsc && webpack --config webpack.config.js", + "prepublishOnly": "npm run build", + "test": "jest", + "test:watch": "jest --watch", + "lint": "eslint src", + "prepare": "husky" + }, + "peerDependencies": { + "three": "^0.177.0" + }, + "devDependencies": { + "@babel/preset-env": "^7.26.0", + "@babel/preset-typescript": "^7.26.0", + "@commitlint/cli": "^19.8.0", + "@commitlint/config-conventional": "^19.8.0", + "@types/jest": "^29.5.14", + "@types/node": "^22.10.4", + "@types/three": "^0.177.0", + "@typescript-eslint/eslint-plugin": "^8.21.0", + "@typescript-eslint/parser": "^8.21.0", + "babel-jest": "^29.7.0", + "eslint": "^9.18.0", + "eslint-config-prettier": "^10.0.1", + "eslint-plugin-import": "^2.31.0", + "eslint-plugin-prettier": "^5.2.3", + "husky": "^9.1.7", + "jest": "^29.7.0", + "madge": "^8.0.0", + "prettier": "^3.4.2", + "rimraf": "^6.0.1", + "terser-webpack-plugin": "^5.3.11", + "ts-jest": "^29.2.5", + "ts-loader": "^9.5.2", + "ts-node": "^10.9.2", + "typedoc": "^0.28.1", + "typescript": "^5.7.3", + "webpack": "^5.97.1", + "webpack-bundle-analyzer": "^4.10.2", + "webpack-cli": "^6.0.1" } -} +} \ No newline at end of file diff --git a/src/assets/assets.ts b/src/assets/assets.ts new file mode 100644 index 0000000..6ad4e34 --- /dev/null +++ b/src/assets/assets.ts @@ -0,0 +1,9 @@ +// Basic assets utilities - simplified version +export const registerTexture = (id: string, texture: any): void => { + // Implementation will be added with full assets system +}; + +export const getTexture = (id: string): any => { + // Implementation will be added with full assets system + return null; +}; \ No newline at end of file diff --git a/src/assets/index.ts b/src/assets/index.ts new file mode 100644 index 0000000..f3faaad --- /dev/null +++ b/src/assets/index.ts @@ -0,0 +1 @@ +export * as AssetsUtils from "./assets.js"; \ No newline at end of file diff --git a/src/audio/audio.ts b/src/audio/audio.ts new file mode 100644 index 0000000..003c266 --- /dev/null +++ b/src/audio/audio.ts @@ -0,0 +1,9 @@ +// Basic audio utilities - simplified version +export const registerAudioBuffer = (id: string, audioBuffer: any): void => { + // Implementation will be added with full audio system +}; + +export const getAudioBuffer = (id: string): any => { + // Implementation will be added with full audio system + return null; +}; \ No newline at end of file diff --git a/src/audio/index.ts b/src/audio/index.ts new file mode 100644 index 0000000..e235aca --- /dev/null +++ b/src/audio/index.ts @@ -0,0 +1 @@ +export * as AudioUtils from "./audio.js"; \ No newline at end of file diff --git a/src/callback-utils.ts b/src/callback-utils.ts new file mode 100644 index 0000000..02bae22 --- /dev/null +++ b/src/callback-utils.ts @@ -0,0 +1,72 @@ +export const CallLimits = { + NO_LIMIT: -1, + CALL_1_PER_SECONDS: 1000, + CALL_15_PER_SECONDS: 1000 / 15, + CALL_30_PER_SECONDS: 1000 / 30, + CALL_45_PER_SECONDS: 1000 / 45, + CALL_60_PER_SECONDS: 1000 / 60, + CALL_120_PER_SECONDS: 1000 / 120, +} as const; + +interface CallData { + lastUpdate: number; + callCount: number; +} + +interface CallWithReducerParams { + id: string; + callback: (param?: any) => void; + callLimit: number; + elapsed: number; + callbackParam?: any; + forceCallCount?: boolean; +} + +let callData: Record = {}; + +export const callWithReducer = ({ + id, + callback, + callLimit, + elapsed, + callbackParam, + forceCallCount = false, +}: CallWithReducerParams): void => { + if (!elapsed) return; + if (!callData[id]) callData[id] = { lastUpdate: -1, callCount: 0 }; + + const call = () => { + if (callbackParam) callback(callbackParam); + else callback(); + }; + + if (callLimit === CallLimits.NO_LIMIT) { + call(); + return; + } + + if (forceCallCount) { + const expectedCallCount = Math.floor(elapsed / (callLimit * 1000)); + while ( + callData[id].lastUpdate === -1 || + expectedCallCount > callData[id].callCount + ) { + call(); + callData[id].lastUpdate += callLimit; + callData[id].callCount++; + } + callData[id].lastUpdate = elapsed; + } else if ( + callData[id].lastUpdate === -1 || + elapsed - callData[id].lastUpdate >= callLimit + ) { + call(); + callData[id].lastUpdate = elapsed; + } +}; + +export const clearCallReducerData = (id: string): boolean => delete callData[id]; + +export const clearAllCallReducerData = (): void => { + callData = {}; +}; \ No newline at end of file diff --git a/src/dispose-utils.ts b/src/dispose-utils.ts new file mode 100644 index 0000000..535a4ef --- /dev/null +++ b/src/dispose-utils.ts @@ -0,0 +1,33 @@ +import * as THREE from 'three'; + +export const disposeMaterials = ( + material: THREE.Material | Array +): void => { + if ((material as THREE.Material).isMaterial) { + const mat = material as THREE.Material; + (mat as any).map?.dispose(); + (mat as any).map = null; + mat.dispose(); + } else { + (material as Array).forEach(disposeMaterials); + } +}; + +export const deepDispose = (container: THREE.Mesh): void => { + const { isMesh, material, geometry } = container; + if (isMesh) { + if (material) { + disposeMaterials(material); + (container as any).material = null; + } + + if (geometry) { + geometry.dispose(); + (container as any).geometry = null; + } + container.parent?.remove(container); + } else if ((container as any).children) { + (container as any).children.forEach(deepDispose); + container.parent?.remove(container); + } +}; \ No newline at end of file diff --git a/src/geom-utils.ts b/src/geom-utils.ts new file mode 100644 index 0000000..d251252 --- /dev/null +++ b/src/geom-utils.ts @@ -0,0 +1,56 @@ +import * as THREE from 'three'; + +export const sign = ( + point1: THREE.Vector3, + point2: THREE.Vector3, + point3: THREE.Vector3 +): number => + (point1.x - point3.x) * (point2.z - point3.z) - + (point2.x - point3.x) * (point1.z - point3.z); + +export const isPointInATriangle = ( + point: THREE.Vector3, + trianglePointA: THREE.Vector3, + trianglePointB: THREE.Vector3, + trianglePointC: THREE.Vector3 +): boolean => { + const d1 = sign(point, trianglePointA, trianglePointB); + const d2 = sign(point, trianglePointB, trianglePointC); + const d3 = sign(point, trianglePointC, trianglePointA); + + return !((d1 < 0 || d2 < 0 || d3 < 0) && (d1 > 0 || d2 > 0 || d3 > 0)); +}; + +export const yFromTriangle = ( + point: THREE.Vector3, + trianglePointA: THREE.Vector3, + trianglePointB: THREE.Vector3, + trianglePointC: THREE.Vector3 +): number => { + const calc1 = + (trianglePointB.x - trianglePointA.x) * + (trianglePointC.y - trianglePointA.y) - + (trianglePointC.x - trianglePointA.x) * + (trianglePointB.y - trianglePointA.y); + const calc2 = + (trianglePointB.x - trianglePointA.x) * + (trianglePointC.z - trianglePointA.z) - + (trianglePointC.x - trianglePointA.x) * + (trianglePointB.z - trianglePointA.z); + const calc3 = + (trianglePointB.z - trianglePointA.z) * + (trianglePointC.y - trianglePointA.y) - + (trianglePointC.z - trianglePointA.z) * + (trianglePointB.y - trianglePointA.y); + const calc4 = + (trianglePointB.x - trianglePointA.x) * + (trianglePointC.z - trianglePointA.z) - + (trianglePointC.x - trianglePointA.x) * + (trianglePointB.z - trianglePointA.z); + + return ( + trianglePointA.y + + (calc1 / calc2) * (point.z - trianglePointA.z) - + (calc3 / calc4) * (point.x - trianglePointA.x) + ); +}; \ No newline at end of file diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..05b379d --- /dev/null +++ b/src/index.ts @@ -0,0 +1,7 @@ +export * as CallbackUtils from "./callback-utils.js"; +export * as DisposeUtils from "./dispose-utils.js"; +export * as ObjectUtils from "./object-utils.js"; +export * as TimeUtils from "./time-utils.js"; +export * as TokenUtils from "./token.js"; +export * as Vector3Utils from "./vector3-utils.js"; +export * as GeomUtils from "./geom-utils.js"; \ No newline at end of file diff --git a/src/object-utils.ts b/src/object-utils.ts new file mode 100644 index 0000000..48d0f4e --- /dev/null +++ b/src/object-utils.ts @@ -0,0 +1,90 @@ +export type ObjectOperationConfig = { + skippedProperties?: Array; + applyToFirstObject?: boolean; +}; + +export const patchObject = ( + objectA: T, + objectB: V, + config: ObjectOperationConfig = { skippedProperties: [], applyToFirstObject: false } +): T => { + const result = {} as any; + Object.keys(objectA as any).forEach((key) => { + if (!config.skippedProperties || !config.skippedProperties.includes(key)) { + if ( + typeof (objectA as any)[key] === "object" && + (objectA as any)[key] && + (objectB as any)[key] && + !Array.isArray((objectA as any)[key]) + ) { + result[key] = patchObject((objectA as any)[key], (objectB as any)[key], config); + } else { + result[key] = + (objectB as any)[key] === 0 + ? 0 + : (objectB as any)[key] === false + ? false + : (objectB as any)[key] || (objectA as any)[key]; + if (config.applyToFirstObject) (objectA as any)[key] = result[key]; + } + } + }); + return result; +}; + +export const deepMerge = ( + objectA: T, + objectB: V, + config: ObjectOperationConfig = { skippedProperties: [], applyToFirstObject: false } +): T | V => { + const result = {} as any; + Array.from( + new Set([...Object.keys((objectA || {}) as any), ...Object.keys((objectB || {}) as any)]) + ).forEach((key) => { + if (!config.skippedProperties || !config.skippedProperties.includes(key)) { + if ( + typeof (objectA as any)?.[key] === "object" && + (objectA as any)?.[key] && + (objectB as any)?.[key] && + !Array.isArray((objectA as any)[key]) + ) { + result[key] = deepMerge((objectA as any)[key], (objectB as any)[key], config); + } else { + result[key] = + (objectB as any)?.[key] === 0 + ? 0 + : (objectB as any)?.[key] === false + ? false + : (objectB as any)?.[key] || (objectA as any)?.[key]; + if (config.applyToFirstObject) (objectA as any)[key] = result[key]; + } + } + }); + return result; +}; + +export const getObjectDiff = ( + objectA: T, + objectB: V, + config: ObjectOperationConfig = { skippedProperties: [] } +): Partial => { + const result = {} as any; + Object.keys(objectA as any).forEach((key) => { + if (!config.skippedProperties || !config.skippedProperties.includes(key)) { + if ( + typeof (objectA as any)[key] === "object" && + (objectA as any)[key] && + (objectB as any)[key] && + !Array.isArray((objectA as any)[key]) + ) { + const objectDiff = getObjectDiff((objectA as any)[key], (objectB as any)[key], config); + if (Object.keys(objectDiff).length > 0) result[key] = objectDiff; + } else { + const mergedValue = + (objectB as any)[key] === 0 ? 0 : (objectB as any)[key] || (objectA as any)[key]; + if (mergedValue !== (objectA as any)[key]) result[key] = mergedValue; + } + } + }); + return result; +}; \ No newline at end of file diff --git a/src/time-utils.ts b/src/time-utils.ts new file mode 100644 index 0000000..a9213f3 --- /dev/null +++ b/src/time-utils.ts @@ -0,0 +1,43 @@ +export const TimePattern = { + HH_MM_SS: "HH:MM:SS", + MM_SS: "MM:SS", + MM_SS_MS: "MM:SS.MS", +} as const; + +interface TimeDetails { + hours: number; + minutes: number; + seconds: number; + milliseconds: number; +} + +interface PatternRule { + pattern: string; + routine: (timeDetails: TimeDetails) => string; +} + +const patterns: PatternRule[] = [ + { pattern: "HH", routine: ({ hours }) => String(hours).padStart(2, "0") }, + { pattern: "MM", routine: ({ minutes }) => String(minutes).padStart(2, "0") }, + { pattern: "SS", routine: ({ seconds }) => String(seconds).padStart(2, "0") }, + { + pattern: "MS", + routine: ({ milliseconds }) => String(milliseconds).padStart(3, "0"), + }, +]; + +export const formatTime = (timeInMS: number, pattern: string): string => { + const milliseconds = Math.floor(timeInMS % 1000); + const seconds = Math.floor((timeInMS / 1000) % 60); + const minutes = Math.floor(Math.floor(timeInMS / 1000 / 60) % 60); + const hours = Math.floor((Math.floor(timeInMS / 1000 / 60) / 60) % 24); + const timeDetails: TimeDetails = { hours, minutes, seconds, milliseconds }; + + let result = pattern; + patterns.forEach( + ({ pattern: currentPattern, routine }) => + (result = result.replace(currentPattern, routine(timeDetails))) + ); + + return result; +}; \ No newline at end of file diff --git a/src/token.ts b/src/token.ts new file mode 100644 index 0000000..94f2335 --- /dev/null +++ b/src/token.ts @@ -0,0 +1,2 @@ +let uniqueId = 0; +export const getUniqueId = (): number => uniqueId++; \ No newline at end of file diff --git a/src/vector3-utils.ts b/src/vector3-utils.ts new file mode 100644 index 0000000..a1bace9 --- /dev/null +++ b/src/vector3-utils.ts @@ -0,0 +1,9 @@ +import * as THREE from 'three'; + +export const absVector3 = (vector: THREE.Vector3): THREE.Vector3 => { + vector.x = Math.abs(vector.x); + vector.y = Math.abs(vector.y); + vector.z = Math.abs(vector.z); + + return vector; +}; \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..ee392c4 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,30 @@ +{ + "compilerOptions": { + "module": "ESNext", + "moduleResolution": "node", + "target": "ES2020", + "declaration": true, + "declarationMap": true, + "emitDeclarationOnly": false, + "outDir": "./dist", + "rootDir": "./src", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "baseUrl": "./", + "paths": { + "@newkrok/three-utils": [ + "./src/index.ts" + ] + } + }, + "sourceMap": true, + "include": [ + "src/**/*" + ], + "exclude": [ + "node_modules", + "dist", + "src/__tests__" + ] +} \ No newline at end of file From 16ca565d16a3e24af854c78198c0006832deadbd Mon Sep 17 00:00:00 2001 From: Krisztian Somoracz Date: Wed, 15 Oct 2025 23:56:16 +0200 Subject: [PATCH 02/20] feat: add webpack build configuration and generate dist files - Add webpack.config.js with ES module output and TypeScript support - Configure terser minification with console removal - Add bundle analyzer for build size monitoring - Set THREE.js as external dependency to avoid bundling - Generate complete dist/ folder with compiled JS and TypeScript definitions - Successfully create 3.8KB minified bundle - Include source maps for debugging --- dist/assets/assets.d.ts | 3 + dist/assets/assets.d.ts.map | 1 + dist/assets/assets.js | 8 + dist/assets/index.d.ts | 2 + dist/assets/index.d.ts.map | 1 + dist/assets/index.js | 1 + dist/audio/audio.d.ts | 3 + dist/audio/audio.d.ts.map | 1 + dist/audio/audio.js | 8 + dist/audio/index.d.ts | 2 + dist/audio/index.d.ts.map | 1 + dist/audio/index.js | 1 + dist/bundle-report.json | 1 + dist/callback-utils.d.ts | 22 + dist/callback-utils.d.ts.map | 1 + dist/callback-utils.js | 45 + dist/dispose-utils.d.ts | 4 + dist/dispose-utils.d.ts.map | 1 + dist/dispose-utils.js | 29 + dist/geom-utils.d.ts | 5 + dist/geom-utils.d.ts.map | 1 + dist/geom-utils.js | 29 + dist/index.d.ts | 8 + dist/index.d.ts.map | 1 + dist/index.js | 7 + dist/object-utils.d.ts | 8 + dist/object-utils.d.ts.map | 1 + dist/object-utils.js | 69 + dist/three-utils.min.js | 1 + dist/time-utils.d.ts | 7 + dist/time-utils.d.ts.map | 1 + dist/time-utils.js | 24 + dist/token.d.ts | 2 + dist/token.d.ts.map | 1 + dist/token.js | 2 + dist/vector3-utils.d.ts | 3 + dist/vector3-utils.d.ts.map | 1 + dist/vector3-utils.js | 6 + package-lock.json | 13457 +++++++++++++++++++++++++++++++++ webpack.config.js | 63 + 40 files changed, 13832 insertions(+) create mode 100644 dist/assets/assets.d.ts create mode 100644 dist/assets/assets.d.ts.map create mode 100644 dist/assets/assets.js create mode 100644 dist/assets/index.d.ts create mode 100644 dist/assets/index.d.ts.map create mode 100644 dist/assets/index.js create mode 100644 dist/audio/audio.d.ts create mode 100644 dist/audio/audio.d.ts.map create mode 100644 dist/audio/audio.js create mode 100644 dist/audio/index.d.ts create mode 100644 dist/audio/index.d.ts.map create mode 100644 dist/audio/index.js create mode 100644 dist/bundle-report.json create mode 100644 dist/callback-utils.d.ts create mode 100644 dist/callback-utils.d.ts.map create mode 100644 dist/callback-utils.js create mode 100644 dist/dispose-utils.d.ts create mode 100644 dist/dispose-utils.d.ts.map create mode 100644 dist/dispose-utils.js create mode 100644 dist/geom-utils.d.ts create mode 100644 dist/geom-utils.d.ts.map create mode 100644 dist/geom-utils.js create mode 100644 dist/index.d.ts create mode 100644 dist/index.d.ts.map create mode 100644 dist/index.js create mode 100644 dist/object-utils.d.ts create mode 100644 dist/object-utils.d.ts.map create mode 100644 dist/object-utils.js create mode 100644 dist/three-utils.min.js create mode 100644 dist/time-utils.d.ts create mode 100644 dist/time-utils.d.ts.map create mode 100644 dist/time-utils.js create mode 100644 dist/token.d.ts create mode 100644 dist/token.d.ts.map create mode 100644 dist/token.js create mode 100644 dist/vector3-utils.d.ts create mode 100644 dist/vector3-utils.d.ts.map create mode 100644 dist/vector3-utils.js create mode 100644 package-lock.json create mode 100644 webpack.config.js diff --git a/dist/assets/assets.d.ts b/dist/assets/assets.d.ts new file mode 100644 index 0000000..5ddc9e9 --- /dev/null +++ b/dist/assets/assets.d.ts @@ -0,0 +1,3 @@ +export declare const registerTexture: (id: string, texture: any) => void; +export declare const getTexture: (id: string) => any; +//# sourceMappingURL=assets.d.ts.map \ No newline at end of file diff --git a/dist/assets/assets.d.ts.map b/dist/assets/assets.d.ts.map new file mode 100644 index 0000000..75cc731 --- /dev/null +++ b/dist/assets/assets.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"assets.d.ts","sourceRoot":"","sources":["../../src/assets/assets.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,eAAe,GAAI,IAAI,MAAM,EAAE,SAAS,GAAG,KAAG,IAE1D,CAAC;AAEF,eAAO,MAAM,UAAU,GAAI,IAAI,MAAM,KAAG,GAGvC,CAAC"} \ No newline at end of file diff --git a/dist/assets/assets.js b/dist/assets/assets.js new file mode 100644 index 0000000..a9c6045 --- /dev/null +++ b/dist/assets/assets.js @@ -0,0 +1,8 @@ +// Basic assets utilities - simplified version +export const registerTexture = (id, texture) => { + // Implementation will be added with full assets system +}; +export const getTexture = (id) => { + // Implementation will be added with full assets system + return null; +}; diff --git a/dist/assets/index.d.ts b/dist/assets/index.d.ts new file mode 100644 index 0000000..463b77a --- /dev/null +++ b/dist/assets/index.d.ts @@ -0,0 +1,2 @@ +export * as AssetsUtils from "./assets.js"; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/dist/assets/index.d.ts.map b/dist/assets/index.d.ts.map new file mode 100644 index 0000000..472606a --- /dev/null +++ b/dist/assets/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/assets/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,WAAW,MAAM,aAAa,CAAC"} \ No newline at end of file diff --git a/dist/assets/index.js b/dist/assets/index.js new file mode 100644 index 0000000..3a65885 --- /dev/null +++ b/dist/assets/index.js @@ -0,0 +1 @@ +export * as AssetsUtils from "./assets.js"; diff --git a/dist/audio/audio.d.ts b/dist/audio/audio.d.ts new file mode 100644 index 0000000..46700fd --- /dev/null +++ b/dist/audio/audio.d.ts @@ -0,0 +1,3 @@ +export declare const registerAudioBuffer: (id: string, audioBuffer: any) => void; +export declare const getAudioBuffer: (id: string) => any; +//# sourceMappingURL=audio.d.ts.map \ No newline at end of file diff --git a/dist/audio/audio.d.ts.map b/dist/audio/audio.d.ts.map new file mode 100644 index 0000000..784bf78 --- /dev/null +++ b/dist/audio/audio.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"audio.d.ts","sourceRoot":"","sources":["../../src/audio/audio.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,mBAAmB,GAAI,IAAI,MAAM,EAAE,aAAa,GAAG,KAAG,IAElE,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,IAAI,MAAM,KAAG,GAG3C,CAAC"} \ No newline at end of file diff --git a/dist/audio/audio.js b/dist/audio/audio.js new file mode 100644 index 0000000..744b005 --- /dev/null +++ b/dist/audio/audio.js @@ -0,0 +1,8 @@ +// Basic audio utilities - simplified version +export const registerAudioBuffer = (id, audioBuffer) => { + // Implementation will be added with full audio system +}; +export const getAudioBuffer = (id) => { + // Implementation will be added with full audio system + return null; +}; diff --git a/dist/audio/index.d.ts b/dist/audio/index.d.ts new file mode 100644 index 0000000..1831824 --- /dev/null +++ b/dist/audio/index.d.ts @@ -0,0 +1,2 @@ +export * as AudioUtils from "./audio.js"; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/dist/audio/index.d.ts.map b/dist/audio/index.d.ts.map new file mode 100644 index 0000000..7f40e10 --- /dev/null +++ b/dist/audio/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/audio/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,UAAU,MAAM,YAAY,CAAC"} \ No newline at end of file diff --git a/dist/audio/index.js b/dist/audio/index.js new file mode 100644 index 0000000..d36e670 --- /dev/null +++ b/dist/audio/index.js @@ -0,0 +1 @@ +export * as AudioUtils from "./audio.js"; diff --git a/dist/bundle-report.json b/dist/bundle-report.json new file mode 100644 index 0000000..78909b7 --- /dev/null +++ b/dist/bundle-report.json @@ -0,0 +1 @@ +[{"label":"three-utils.min.js","isAsset":true,"statSize":8161,"groups":[{"label":"dist","path":"./dist","statSize":8161,"groups":[{"id":366,"label":"index.js + 7 modules (concatenated)","path":"./dist/index.js + 7 modules (concatenated)","statSize":8161,"parsedSize":0,"gzipSize":0,"concatenated":true,"groups":[{"label":"dist","path":"./dist/index.js + 7 modules (concatenated)/dist","statSize":8161,"groups":[{"id":null,"label":"index.js","path":"./dist/index.js + 7 modules (concatenated)/dist/index.js","statSize":342,"parsedSize":0,"gzipSize":0,"inaccurateSizes":true},{"id":null,"label":"callback-utils.js","path":"./dist/index.js + 7 modules (concatenated)/dist/callback-utils.js","statSize":1408,"parsedSize":0,"gzipSize":0,"inaccurateSizes":true},{"id":null,"label":"dispose-utils.js","path":"./dist/index.js + 7 modules (concatenated)/dist/dispose-utils.js","statSize":777,"parsedSize":0,"gzipSize":0,"inaccurateSizes":true},{"id":null,"label":"object-utils.js","path":"./dist/index.js + 7 modules (concatenated)/dist/object-utils.js","statSize":2808,"parsedSize":0,"gzipSize":0,"inaccurateSizes":true},{"id":null,"label":"time-utils.js","path":"./dist/index.js + 7 modules (concatenated)/dist/time-utils.js","statSize":1037,"parsedSize":0,"gzipSize":0,"inaccurateSizes":true},{"id":null,"label":"token.js","path":"./dist/index.js + 7 modules (concatenated)/dist/token.js","statSize":63,"parsedSize":0,"gzipSize":0,"inaccurateSizes":true},{"id":null,"label":"vector3-utils.js","path":"./dist/index.js + 7 modules (concatenated)/dist/vector3-utils.js","statSize":167,"parsedSize":0,"gzipSize":0,"inaccurateSizes":true},{"id":null,"label":"geom-utils.js","path":"./dist/index.js + 7 modules (concatenated)/dist/geom-utils.js","statSize":1559,"parsedSize":0,"gzipSize":0,"inaccurateSizes":true}],"parsedSize":0,"gzipSize":0,"inaccurateSizes":true}]}],"parsedSize":0,"gzipSize":0}],"isInitialByEntrypoint":{"main":true}}] \ No newline at end of file diff --git a/dist/callback-utils.d.ts b/dist/callback-utils.d.ts new file mode 100644 index 0000000..d9ea54d --- /dev/null +++ b/dist/callback-utils.d.ts @@ -0,0 +1,22 @@ +export declare const CallLimits: { + readonly NO_LIMIT: -1; + readonly CALL_1_PER_SECONDS: 1000; + readonly CALL_15_PER_SECONDS: number; + readonly CALL_30_PER_SECONDS: number; + readonly CALL_45_PER_SECONDS: number; + readonly CALL_60_PER_SECONDS: number; + readonly CALL_120_PER_SECONDS: number; +}; +interface CallWithReducerParams { + id: string; + callback: (param?: any) => void; + callLimit: number; + elapsed: number; + callbackParam?: any; + forceCallCount?: boolean; +} +export declare const callWithReducer: ({ id, callback, callLimit, elapsed, callbackParam, forceCallCount, }: CallWithReducerParams) => void; +export declare const clearCallReducerData: (id: string) => boolean; +export declare const clearAllCallReducerData: () => void; +export {}; +//# sourceMappingURL=callback-utils.d.ts.map \ No newline at end of file diff --git a/dist/callback-utils.d.ts.map b/dist/callback-utils.d.ts.map new file mode 100644 index 0000000..f3d7a36 --- /dev/null +++ b/dist/callback-utils.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"callback-utils.d.ts","sourceRoot":"","sources":["../src/callback-utils.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,UAAU;;;;;;;;CAQb,CAAC;AAOX,UAAU,qBAAqB;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,CAAC,KAAK,CAAC,EAAE,GAAG,KAAK,IAAI,CAAC;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,GAAG,CAAC;IACpB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC5B;AAID,eAAO,MAAM,eAAe,GAAI,sEAO7B,qBAAqB,KAAG,IAgC1B,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAAI,IAAI,MAAM,KAAG,OAA8B,CAAC;AAEjF,eAAO,MAAM,uBAAuB,QAAO,IAE1C,CAAC"} \ No newline at end of file diff --git a/dist/callback-utils.js b/dist/callback-utils.js new file mode 100644 index 0000000..a35e0e2 --- /dev/null +++ b/dist/callback-utils.js @@ -0,0 +1,45 @@ +export const CallLimits = { + NO_LIMIT: -1, + CALL_1_PER_SECONDS: 1000, + CALL_15_PER_SECONDS: 1000 / 15, + CALL_30_PER_SECONDS: 1000 / 30, + CALL_45_PER_SECONDS: 1000 / 45, + CALL_60_PER_SECONDS: 1000 / 60, + CALL_120_PER_SECONDS: 1000 / 120, +}; +let callData = {}; +export const callWithReducer = ({ id, callback, callLimit, elapsed, callbackParam, forceCallCount = false, }) => { + if (!elapsed) + return; + if (!callData[id]) + callData[id] = { lastUpdate: -1, callCount: 0 }; + const call = () => { + if (callbackParam) + callback(callbackParam); + else + callback(); + }; + if (callLimit === CallLimits.NO_LIMIT) { + call(); + return; + } + if (forceCallCount) { + const expectedCallCount = Math.floor(elapsed / (callLimit * 1000)); + while (callData[id].lastUpdate === -1 || + expectedCallCount > callData[id].callCount) { + call(); + callData[id].lastUpdate += callLimit; + callData[id].callCount++; + } + callData[id].lastUpdate = elapsed; + } + else if (callData[id].lastUpdate === -1 || + elapsed - callData[id].lastUpdate >= callLimit) { + call(); + callData[id].lastUpdate = elapsed; + } +}; +export const clearCallReducerData = (id) => delete callData[id]; +export const clearAllCallReducerData = () => { + callData = {}; +}; diff --git a/dist/dispose-utils.d.ts b/dist/dispose-utils.d.ts new file mode 100644 index 0000000..5547770 --- /dev/null +++ b/dist/dispose-utils.d.ts @@ -0,0 +1,4 @@ +import * as THREE from 'three'; +export declare const disposeMaterials: (material: THREE.Material | Array) => void; +export declare const deepDispose: (container: THREE.Mesh) => void; +//# sourceMappingURL=dispose-utils.d.ts.map \ No newline at end of file diff --git a/dist/dispose-utils.d.ts.map b/dist/dispose-utils.d.ts.map new file mode 100644 index 0000000..268ad7a --- /dev/null +++ b/dist/dispose-utils.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"dispose-utils.d.ts","sourceRoot":"","sources":["../src/dispose-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,eAAO,MAAM,gBAAgB,GACzB,UAAU,KAAK,CAAC,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,KACjD,IASF,CAAC;AAEF,eAAO,MAAM,WAAW,GAAI,WAAW,KAAK,CAAC,IAAI,KAAG,IAiBnD,CAAC"} \ No newline at end of file diff --git a/dist/dispose-utils.js b/dist/dispose-utils.js new file mode 100644 index 0000000..e00ece3 --- /dev/null +++ b/dist/dispose-utils.js @@ -0,0 +1,29 @@ +export const disposeMaterials = (material) => { + if (material.isMaterial) { + const mat = material; + mat.map?.dispose(); + mat.map = null; + mat.dispose(); + } + else { + material.forEach(disposeMaterials); + } +}; +export const deepDispose = (container) => { + const { isMesh, material, geometry } = container; + if (isMesh) { + if (material) { + disposeMaterials(material); + container.material = null; + } + if (geometry) { + geometry.dispose(); + container.geometry = null; + } + container.parent?.remove(container); + } + else if (container.children) { + container.children.forEach(deepDispose); + container.parent?.remove(container); + } +}; diff --git a/dist/geom-utils.d.ts b/dist/geom-utils.d.ts new file mode 100644 index 0000000..77a0d2a --- /dev/null +++ b/dist/geom-utils.d.ts @@ -0,0 +1,5 @@ +import * as THREE from 'three'; +export declare const sign: (point1: THREE.Vector3, point2: THREE.Vector3, point3: THREE.Vector3) => number; +export declare const isPointInATriangle: (point: THREE.Vector3, trianglePointA: THREE.Vector3, trianglePointB: THREE.Vector3, trianglePointC: THREE.Vector3) => boolean; +export declare const yFromTriangle: (point: THREE.Vector3, trianglePointA: THREE.Vector3, trianglePointB: THREE.Vector3, trianglePointC: THREE.Vector3) => number; +//# sourceMappingURL=geom-utils.d.ts.map \ No newline at end of file diff --git a/dist/geom-utils.d.ts.map b/dist/geom-utils.d.ts.map new file mode 100644 index 0000000..8dc7ee1 --- /dev/null +++ b/dist/geom-utils.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"geom-utils.d.ts","sourceRoot":"","sources":["../src/geom-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,eAAO,MAAM,IAAI,GACb,QAAQ,KAAK,CAAC,OAAO,EACrB,QAAQ,KAAK,CAAC,OAAO,EACrB,QAAQ,KAAK,CAAC,OAAO,KACtB,MAE8C,CAAC;AAElD,eAAO,MAAM,kBAAkB,GAC3B,OAAO,KAAK,CAAC,OAAO,EACpB,gBAAgB,KAAK,CAAC,OAAO,EAC7B,gBAAgB,KAAK,CAAC,OAAO,EAC7B,gBAAgB,KAAK,CAAC,OAAO,KAC9B,OAMF,CAAC;AAEF,eAAO,MAAM,aAAa,GACtB,OAAO,KAAK,CAAC,OAAO,EACpB,gBAAgB,KAAK,CAAC,OAAO,EAC7B,gBAAgB,KAAK,CAAC,OAAO,EAC7B,gBAAgB,KAAK,CAAC,OAAO,KAC9B,MA2BF,CAAC"} \ No newline at end of file diff --git a/dist/geom-utils.js b/dist/geom-utils.js new file mode 100644 index 0000000..cd87d99 --- /dev/null +++ b/dist/geom-utils.js @@ -0,0 +1,29 @@ +export const sign = (point1, point2, point3) => (point1.x - point3.x) * (point2.z - point3.z) - + (point2.x - point3.x) * (point1.z - point3.z); +export const isPointInATriangle = (point, trianglePointA, trianglePointB, trianglePointC) => { + const d1 = sign(point, trianglePointA, trianglePointB); + const d2 = sign(point, trianglePointB, trianglePointC); + const d3 = sign(point, trianglePointC, trianglePointA); + return !((d1 < 0 || d2 < 0 || d3 < 0) && (d1 > 0 || d2 > 0 || d3 > 0)); +}; +export const yFromTriangle = (point, trianglePointA, trianglePointB, trianglePointC) => { + const calc1 = (trianglePointB.x - trianglePointA.x) * + (trianglePointC.y - trianglePointA.y) - + (trianglePointC.x - trianglePointA.x) * + (trianglePointB.y - trianglePointA.y); + const calc2 = (trianglePointB.x - trianglePointA.x) * + (trianglePointC.z - trianglePointA.z) - + (trianglePointC.x - trianglePointA.x) * + (trianglePointB.z - trianglePointA.z); + const calc3 = (trianglePointB.z - trianglePointA.z) * + (trianglePointC.y - trianglePointA.y) - + (trianglePointC.z - trianglePointA.z) * + (trianglePointB.y - trianglePointA.y); + const calc4 = (trianglePointB.x - trianglePointA.x) * + (trianglePointC.z - trianglePointA.z) - + (trianglePointC.x - trianglePointA.x) * + (trianglePointB.z - trianglePointA.z); + return (trianglePointA.y + + (calc1 / calc2) * (point.z - trianglePointA.z) - + (calc3 / calc4) * (point.x - trianglePointA.x)); +}; diff --git a/dist/index.d.ts b/dist/index.d.ts new file mode 100644 index 0000000..600496a --- /dev/null +++ b/dist/index.d.ts @@ -0,0 +1,8 @@ +export * as CallbackUtils from "./callback-utils.js"; +export * as DisposeUtils from "./dispose-utils.js"; +export * as ObjectUtils from "./object-utils.js"; +export * as TimeUtils from "./time-utils.js"; +export * as TokenUtils from "./token.js"; +export * as Vector3Utils from "./vector3-utils.js"; +export * as GeomUtils from "./geom-utils.js"; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/dist/index.d.ts.map b/dist/index.d.ts.map new file mode 100644 index 0000000..6744c9f --- /dev/null +++ b/dist/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,aAAa,MAAM,qBAAqB,CAAC;AACrD,OAAO,KAAK,YAAY,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,WAAW,MAAM,mBAAmB,CAAC;AACjD,OAAO,KAAK,SAAS,MAAM,iBAAiB,CAAC;AAC7C,OAAO,KAAK,UAAU,MAAM,YAAY,CAAC;AACzC,OAAO,KAAK,YAAY,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,SAAS,MAAM,iBAAiB,CAAC"} \ No newline at end of file diff --git a/dist/index.js b/dist/index.js new file mode 100644 index 0000000..10abe79 --- /dev/null +++ b/dist/index.js @@ -0,0 +1,7 @@ +export * as CallbackUtils from "./callback-utils.js"; +export * as DisposeUtils from "./dispose-utils.js"; +export * as ObjectUtils from "./object-utils.js"; +export * as TimeUtils from "./time-utils.js"; +export * as TokenUtils from "./token.js"; +export * as Vector3Utils from "./vector3-utils.js"; +export * as GeomUtils from "./geom-utils.js"; diff --git a/dist/object-utils.d.ts b/dist/object-utils.d.ts new file mode 100644 index 0000000..5f3a9f8 --- /dev/null +++ b/dist/object-utils.d.ts @@ -0,0 +1,8 @@ +export type ObjectOperationConfig = { + skippedProperties?: Array; + applyToFirstObject?: boolean; +}; +export declare const patchObject: (objectA: T, objectB: V, config?: ObjectOperationConfig) => T; +export declare const deepMerge: (objectA: T, objectB: V, config?: ObjectOperationConfig) => T | V; +export declare const getObjectDiff: (objectA: T, objectB: V, config?: ObjectOperationConfig) => Partial; +//# sourceMappingURL=object-utils.d.ts.map \ No newline at end of file diff --git a/dist/object-utils.d.ts.map b/dist/object-utils.d.ts.map new file mode 100644 index 0000000..fbb1c30 --- /dev/null +++ b/dist/object-utils.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"object-utils.d.ts","sourceRoot":"","sources":["../src/object-utils.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,qBAAqB,GAAG;IAChC,iBAAiB,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAClC,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAChC,CAAC;AAEF,eAAO,MAAM,WAAW,GAAI,CAAC,EAAE,CAAC,EAC5B,SAAS,CAAC,EACV,SAAS,CAAC,EACV,SAAQ,qBAA4E,KACrF,CAuBF,CAAC;AAEF,eAAO,MAAM,SAAS,GAAI,CAAC,EAAE,CAAC,EAC1B,SAAS,CAAC,EACV,SAAS,CAAC,EACV,SAAQ,qBAA4E,KACrF,CAAC,GAAG,CAyBN,CAAC;AAEF,eAAO,MAAM,aAAa,GAAI,CAAC,EAAE,CAAC,EAC9B,SAAS,CAAC,EACV,SAAS,CAAC,EACV,SAAQ,qBAAiD,KAC1D,OAAO,CAAC,CAAC,GAAG,CAAC,CAoBf,CAAC"} \ No newline at end of file diff --git a/dist/object-utils.js b/dist/object-utils.js new file mode 100644 index 0000000..473900e --- /dev/null +++ b/dist/object-utils.js @@ -0,0 +1,69 @@ +export const patchObject = (objectA, objectB, config = { skippedProperties: [], applyToFirstObject: false }) => { + const result = {}; + Object.keys(objectA).forEach((key) => { + if (!config.skippedProperties || !config.skippedProperties.includes(key)) { + if (typeof objectA[key] === "object" && + objectA[key] && + objectB[key] && + !Array.isArray(objectA[key])) { + result[key] = patchObject(objectA[key], objectB[key], config); + } + else { + result[key] = + objectB[key] === 0 + ? 0 + : objectB[key] === false + ? false + : objectB[key] || objectA[key]; + if (config.applyToFirstObject) + objectA[key] = result[key]; + } + } + }); + return result; +}; +export const deepMerge = (objectA, objectB, config = { skippedProperties: [], applyToFirstObject: false }) => { + const result = {}; + Array.from(new Set([...Object.keys((objectA || {})), ...Object.keys((objectB || {}))])).forEach((key) => { + if (!config.skippedProperties || !config.skippedProperties.includes(key)) { + if (typeof objectA?.[key] === "object" && + objectA?.[key] && + objectB?.[key] && + !Array.isArray(objectA[key])) { + result[key] = deepMerge(objectA[key], objectB[key], config); + } + else { + result[key] = + objectB?.[key] === 0 + ? 0 + : objectB?.[key] === false + ? false + : objectB?.[key] || objectA?.[key]; + if (config.applyToFirstObject) + objectA[key] = result[key]; + } + } + }); + return result; +}; +export const getObjectDiff = (objectA, objectB, config = { skippedProperties: [] }) => { + const result = {}; + Object.keys(objectA).forEach((key) => { + if (!config.skippedProperties || !config.skippedProperties.includes(key)) { + if (typeof objectA[key] === "object" && + objectA[key] && + objectB[key] && + !Array.isArray(objectA[key])) { + const objectDiff = getObjectDiff(objectA[key], objectB[key], config); + if (Object.keys(objectDiff).length > 0) + result[key] = objectDiff; + } + else { + const mergedValue = objectB[key] === 0 ? 0 : objectB[key] || objectA[key]; + if (mergedValue !== objectA[key]) + result[key] = mergedValue; + } + } + }); + return result; +}; diff --git a/dist/three-utils.min.js b/dist/three-utils.min.js new file mode 100644 index 0000000..c64b562 --- /dev/null +++ b/dist/three-utils.min.js @@ -0,0 +1 @@ +var e={d:(t,r)=>{for(var a in r)e.o(r,a)&&!e.o(t,a)&&Object.defineProperty(t,a,{enumerable:!0,get:r[a]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r:e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})}},t={};e.r(t),e.d(t,{CallLimits:()=>p,callWithReducer:()=>c,clearAllCallReducerData:()=>S,clearCallReducerData:()=>d});var r={};e.r(r),e.d(r,{deepDispose:()=>u,disposeMaterials:()=>y});var a={};e.r(a),e.d(a,{deepMerge:()=>f,getObjectDiff:()=>b,patchObject:()=>M});var s={};e.r(s),e.d(s,{TimePattern:()=>_,formatTime:()=>h});var o={};e.r(o),e.d(o,{getUniqueId:()=>P});var l={};e.r(l),e.d(l,{absVector3:()=>x});var i={};e.r(i),e.d(i,{isPointInATriangle:()=>z,sign:()=>C,yFromTriangle:()=>j});const p={NO_LIMIT:-1,CALL_1_PER_SECONDS:1e3,CALL_15_PER_SECONDS:1e3/15,CALL_30_PER_SECONDS:1e3/30,CALL_45_PER_SECONDS:1e3/45,CALL_60_PER_SECONDS:1e3/60,CALL_120_PER_SECONDS:1e3/120};let n={};const c=({id:e,callback:t,callLimit:r,elapsed:a,callbackParam:s,forceCallCount:o=!1})=>{if(!a)return;n[e]||(n[e]={lastUpdate:-1,callCount:0});const l=()=>{s?t(s):t()};if(r!==p.NO_LIMIT)if(o){const t=Math.floor(a/(1e3*r));for(;-1===n[e].lastUpdate||t>n[e].callCount;)l(),n[e].lastUpdate+=r,n[e].callCount++;n[e].lastUpdate=a}else(-1===n[e].lastUpdate||a-n[e].lastUpdate>=r)&&(l(),n[e].lastUpdate=a);else l()},d=e=>delete n[e],S=()=>{n={}},y=e=>{if(e.isMaterial){const t=e;t.map?.dispose(),t.map=null,t.dispose()}else e.forEach(y)},u=e=>{const{isMesh:t,material:r,geometry:a}=e;t?(r&&(y(r),e.material=null),a&&(a.dispose(),e.geometry=null),e.parent?.remove(e)):e.children&&(e.children.forEach(u),e.parent?.remove(e))},M=(e,t,r={skippedProperties:[],applyToFirstObject:!1})=>{const a={};return Object.keys(e).forEach(s=>{r.skippedProperties&&r.skippedProperties.includes(s)||("object"==typeof e[s]&&e[s]&&t[s]&&!Array.isArray(e[s])?a[s]=M(e[s],t[s],r):(a[s]=0===t[s]?0:!1!==t[s]&&(t[s]||e[s]),r.applyToFirstObject&&(e[s]=a[s])))}),a},f=(e,t,r={skippedProperties:[],applyToFirstObject:!1})=>{const a={};return Array.from(new Set([...Object.keys(e||{}),...Object.keys(t||{})])).forEach(s=>{r.skippedProperties&&r.skippedProperties.includes(s)||("object"==typeof e?.[s]&&e?.[s]&&t?.[s]&&!Array.isArray(e[s])?a[s]=f(e[s],t[s],r):(a[s]=0===t?.[s]?0:!1!==t?.[s]&&(t?.[s]||e?.[s]),r.applyToFirstObject&&(e[s]=a[s])))}),a},b=(e,t,r={skippedProperties:[]})=>{const a={};return Object.keys(e).forEach(s=>{if(!r.skippedProperties||!r.skippedProperties.includes(s))if("object"==typeof e[s]&&e[s]&&t[s]&&!Array.isArray(e[s])){const o=b(e[s],t[s],r);Object.keys(o).length>0&&(a[s]=o)}else{const r=0===t[s]?0:t[s]||e[s];r!==e[s]&&(a[s]=r)}}),a},_={HH_MM_SS:"HH:MM:SS",MM_SS:"MM:SS",MM_SS_MS:"MM:SS.MS"},m=[{pattern:"HH",routine:({hours:e})=>String(e).padStart(2,"0")},{pattern:"MM",routine:({minutes:e})=>String(e).padStart(2,"0")},{pattern:"SS",routine:({seconds:e})=>String(e).padStart(2,"0")},{pattern:"MS",routine:({milliseconds:e})=>String(e).padStart(3,"0")}],h=(e,t)=>{const r=Math.floor(e%1e3),a=Math.floor(e/1e3%60),s=Math.floor(Math.floor(e/1e3/60)%60),o={hours:Math.floor(Math.floor(e/1e3/60)/60%24),minutes:s,seconds:a,milliseconds:r};let l=t;return m.forEach(({pattern:e,routine:t})=>l=l.replace(e,t(o))),l};let O=0;const P=()=>O++,x=e=>(e.x=Math.abs(e.x),e.y=Math.abs(e.y),e.z=Math.abs(e.z),e),C=(e,t,r)=>(e.x-r.x)*(t.z-r.z)-(t.x-r.x)*(e.z-r.z),z=(e,t,r,a)=>{const s=C(e,t,r),o=C(e,r,a),l=C(e,a,t);return!((s<0||o<0||l<0)&&(s>0||o>0||l>0))},j=(e,t,r,a)=>{const s=(r.x-t.x)*(a.y-t.y)-(a.x-t.x)*(r.y-t.y),o=(r.x-t.x)*(a.z-t.z)-(a.x-t.x)*(r.z-t.z),l=(r.z-t.z)*(a.y-t.y)-(a.z-t.z)*(r.y-t.y),i=(r.x-t.x)*(a.z-t.z)-(a.x-t.x)*(r.z-t.z);return t.y+s/o*(e.z-t.z)-l/i*(e.x-t.x)};export{t as CallbackUtils,r as DisposeUtils,i as GeomUtils,a as ObjectUtils,s as TimeUtils,o as TokenUtils,l as Vector3Utils}; \ No newline at end of file diff --git a/dist/time-utils.d.ts b/dist/time-utils.d.ts new file mode 100644 index 0000000..f3ea6ac --- /dev/null +++ b/dist/time-utils.d.ts @@ -0,0 +1,7 @@ +export declare const TimePattern: { + readonly HH_MM_SS: "HH:MM:SS"; + readonly MM_SS: "MM:SS"; + readonly MM_SS_MS: "MM:SS.MS"; +}; +export declare const formatTime: (timeInMS: number, pattern: string) => string; +//# sourceMappingURL=time-utils.d.ts.map \ No newline at end of file diff --git a/dist/time-utils.d.ts.map b/dist/time-utils.d.ts.map new file mode 100644 index 0000000..fd95806 --- /dev/null +++ b/dist/time-utils.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"time-utils.d.ts","sourceRoot":"","sources":["../src/time-utils.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,WAAW;;;;CAId,CAAC;AAwBX,eAAO,MAAM,UAAU,GAAI,UAAU,MAAM,EAAE,SAAS,MAAM,KAAG,MAc9D,CAAC"} \ No newline at end of file diff --git a/dist/time-utils.js b/dist/time-utils.js new file mode 100644 index 0000000..9ad9552 --- /dev/null +++ b/dist/time-utils.js @@ -0,0 +1,24 @@ +export const TimePattern = { + HH_MM_SS: "HH:MM:SS", + MM_SS: "MM:SS", + MM_SS_MS: "MM:SS.MS", +}; +const patterns = [ + { pattern: "HH", routine: ({ hours }) => String(hours).padStart(2, "0") }, + { pattern: "MM", routine: ({ minutes }) => String(minutes).padStart(2, "0") }, + { pattern: "SS", routine: ({ seconds }) => String(seconds).padStart(2, "0") }, + { + pattern: "MS", + routine: ({ milliseconds }) => String(milliseconds).padStart(3, "0"), + }, +]; +export const formatTime = (timeInMS, pattern) => { + const milliseconds = Math.floor(timeInMS % 1000); + const seconds = Math.floor((timeInMS / 1000) % 60); + const minutes = Math.floor(Math.floor(timeInMS / 1000 / 60) % 60); + const hours = Math.floor((Math.floor(timeInMS / 1000 / 60) / 60) % 24); + const timeDetails = { hours, minutes, seconds, milliseconds }; + let result = pattern; + patterns.forEach(({ pattern: currentPattern, routine }) => (result = result.replace(currentPattern, routine(timeDetails)))); + return result; +}; diff --git a/dist/token.d.ts b/dist/token.d.ts new file mode 100644 index 0000000..0317230 --- /dev/null +++ b/dist/token.d.ts @@ -0,0 +1,2 @@ +export declare const getUniqueId: () => number; +//# sourceMappingURL=token.d.ts.map \ No newline at end of file diff --git a/dist/token.d.ts.map b/dist/token.d.ts.map new file mode 100644 index 0000000..d3128e8 --- /dev/null +++ b/dist/token.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"token.d.ts","sourceRoot":"","sources":["../src/token.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,WAAW,QAAO,MAAoB,CAAC"} \ No newline at end of file diff --git a/dist/token.js b/dist/token.js new file mode 100644 index 0000000..81f09a1 --- /dev/null +++ b/dist/token.js @@ -0,0 +1,2 @@ +let uniqueId = 0; +export const getUniqueId = () => uniqueId++; diff --git a/dist/vector3-utils.d.ts b/dist/vector3-utils.d.ts new file mode 100644 index 0000000..88afdde --- /dev/null +++ b/dist/vector3-utils.d.ts @@ -0,0 +1,3 @@ +import * as THREE from 'three'; +export declare const absVector3: (vector: THREE.Vector3) => THREE.Vector3; +//# sourceMappingURL=vector3-utils.d.ts.map \ No newline at end of file diff --git a/dist/vector3-utils.d.ts.map b/dist/vector3-utils.d.ts.map new file mode 100644 index 0000000..f3c059e --- /dev/null +++ b/dist/vector3-utils.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"vector3-utils.d.ts","sourceRoot":"","sources":["../src/vector3-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,eAAO,MAAM,UAAU,GAAI,QAAQ,KAAK,CAAC,OAAO,KAAG,KAAK,CAAC,OAMxD,CAAC"} \ No newline at end of file diff --git a/dist/vector3-utils.js b/dist/vector3-utils.js new file mode 100644 index 0000000..eaf4898 --- /dev/null +++ b/dist/vector3-utils.js @@ -0,0 +1,6 @@ +export const absVector3 = (vector) => { + vector.x = Math.abs(vector.x); + vector.y = Math.abs(vector.y); + vector.z = Math.abs(vector.z); + return vector; +}; diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..67c2a9c --- /dev/null +++ b/package-lock.json @@ -0,0 +1,13457 @@ +{ + "name": "@newkrok/three-utils", + "version": "1.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "@newkrok/three-utils", + "version": "1.1.0", + "license": "MIT", + "devDependencies": { + "@babel/preset-env": "^7.26.0", + "@babel/preset-typescript": "^7.26.0", + "@commitlint/cli": "^19.8.0", + "@commitlint/config-conventional": "^19.8.0", + "@types/jest": "^29.5.14", + "@types/node": "^22.10.4", + "@types/three": "^0.177.0", + "@typescript-eslint/eslint-plugin": "^8.21.0", + "@typescript-eslint/parser": "^8.21.0", + "babel-jest": "^29.7.0", + "eslint": "^9.18.0", + "eslint-config-prettier": "^10.0.1", + "eslint-plugin-import": "^2.31.0", + "eslint-plugin-prettier": "^5.2.3", + "husky": "^9.1.7", + "jest": "^29.7.0", + "madge": "^8.0.0", + "prettier": "^3.4.2", + "rimraf": "^6.0.1", + "terser-webpack-plugin": "^5.3.11", + "ts-jest": "^29.2.5", + "ts-loader": "^9.5.2", + "ts-node": "^10.9.2", + "typedoc": "^0.28.1", + "typescript": "^5.7.3", + "webpack": "^5.97.1", + "webpack-bundle-analyzer": "^4.10.2", + "webpack-cli": "^6.0.1" + }, + "peerDependencies": { + "three": "^0.177.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.4.tgz", + "integrity": "sha512-YsmSKC29MJwf0gF8Rjjrg5LQCmyh+j/nD8/eP7f+BeoQTKYqs9RoWbjGOdy0+1Ekr68RJZMUOPVQaQisnIo4Rw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.4.tgz", + "integrity": "sha512-2BCOP7TN8M+gVDj7/ht3hsaO/B/n5oDbiAyyvnRlNOs+u1o+JWNYTQrmpuNp1/Wq2gcFrI01JAW+paEKDMx/CA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.3", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-module-transforms": "^7.28.3", + "@babel/helpers": "^7.28.4", + "@babel/parser": "^7.28.4", + "@babel/template": "^7.27.2", + "@babel/traverse": "^7.28.4", + "@babel/types": "^7.28.4", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.3.tgz", + "integrity": "sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.3", + "@babel/types": "^7.28.2", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.27.3", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz", + "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.3" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", + "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.27.2", + "@babel/helper-validator-option": "^7.27.1", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.28.3.tgz", + "integrity": "sha512-V9f6ZFIYSLNEbuGA/92uOvYsGCJNsuA8ESZ4ldc09bWk/j8H8TKiPw8Mk1eG6olpnO0ALHJmYfZvF4MEE4gajg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-member-expression-to-functions": "^7.27.1", + "@babel/helper-optimise-call-expression": "^7.27.1", + "@babel/helper-replace-supers": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", + "@babel/traverse": "^7.28.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.27.1.tgz", + "integrity": "sha512-uVDC72XVf8UbrH5qQTc18Agb8emwjTiZrQE11Nv3CuBEZmVvTwwE9CBUEvHku06gQCAyYf8Nv6ja1IN+6LMbxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.1", + "regexpu-core": "^6.2.0", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.5.tgz", + "integrity": "sha512-uJnGFcPsWQK8fvjgGP5LZUZZsYGIoPeRjSF5PGwrelYgq7Q15/Ft9NGFp1zglwgIv//W0uG4BevRuSJRyylZPg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-plugin-utils": "^7.27.1", + "debug": "^4.4.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.22.10" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.27.1.tgz", + "integrity": "sha512-E5chM8eWjTp/aNoVpcbfM7mLxu9XGLWYise2eBKGQomAk/Mb4XoxyqXTZbuTohbsl8EKqdlMhnDI2CCLfcs9wA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", + "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz", + "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1", + "@babel/traverse": "^7.28.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz", + "integrity": "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", + "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.27.1.tgz", + "integrity": "sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.1", + "@babel/helper-wrap-function": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.27.1.tgz", + "integrity": "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-member-expression-to-functions": "^7.27.1", + "@babel/helper-optimise-call-expression": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.27.1.tgz", + "integrity": "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", + "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.28.3.tgz", + "integrity": "sha512-zdf983tNfLZFletc0RRXYrHrucBEg95NIFMkn6K9dbeMYnsgHaSBGcQqdsCSStG2PYwRre0Qc2NNSCXbG+xc6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.27.2", + "@babel/traverse": "^7.28.3", + "@babel/types": "^7.28.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz", + "integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.4.tgz", + "integrity": "sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.4" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.27.1.tgz", + "integrity": "sha512-QPG3C9cCVRQLxAVwmefEmwdTanECuUBMQZ/ym5kiw3XKCGA7qkuQLcjWWHcrD/GKbn/WmJwaezfuuAOcyKlRPA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.27.1.tgz", + "integrity": "sha512-qNeq3bCKnGgLkEXUuFry6dPlGfCdQNZbn7yUAPCInwAJHMU7THJfrBSozkcWq5sNM6RcF3S8XyQL2A52KNR9IA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.27.1.tgz", + "integrity": "sha512-g4L7OYun04N1WyqMNjldFwlfPCLVkgB54A/YCXICZYBsvJJE3kByKv9c9+R/nAfmIfjl2rKYLNyMHboYbZaWaA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.27.1.tgz", + "integrity": "sha512-oO02gcONcD5O1iTLi/6frMJBIwWEHceWGSGqrpCmEL8nogiS6J9PBlE48CaK20/Jx1LuRml9aDftLgdjXT8+Cw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", + "@babel/plugin-transform-optional-chaining": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.28.3.tgz", + "integrity": "sha512-b6YTX108evsvE4YgWyQ921ZAFFQm3Bn+CA3+ZXlNVnPhx+UfsVURoPjfGAPCjBgrqo30yX/C2nZGX96DxvR9Iw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.28.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.27.1.tgz", + "integrity": "sha512-UT/Jrhw57xg4ILHLFnzFpPDlMbcdEicaAtjPQpbj9wa8T4r5KVWCimHcL/460g8Ht0DMxDyjsLgiWSkVjnwPFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.27.1.tgz", + "integrity": "sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.27.1.tgz", + "integrity": "sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.27.1.tgz", + "integrity": "sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-unicode-sets-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.27.1.tgz", + "integrity": "sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-generator-functions": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.28.0.tgz", + "integrity": "sha512-BEOdvX4+M765icNPZeidyADIvQ1m1gmunXufXxvRESy/jNNyfovIqUyE7MVgGBjWktCoJlzvFA1To2O4ymIO3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-remap-async-to-generator": "^7.27.1", + "@babel/traverse": "^7.28.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.27.1.tgz", + "integrity": "sha512-NREkZsZVJS4xmTr8qzE5y8AfIPqsdQfRuUiLRTEzb7Qii8iFWCyDKaUV2c0rCuh4ljDZ98ALHP/PetiBV2nddA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-remap-async-to-generator": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.27.1.tgz", + "integrity": "sha512-cnqkuOtZLapWYZUYM5rVIdv1nXYuFVIltZ6ZJ7nIj585QsjKM5dhL2Fu/lICXZ1OyIAFc7Qy+bvDAtTXqGrlhg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.4.tgz", + "integrity": "sha512-1yxmvN0MJHOhPVmAsmoW5liWwoILobu/d/ShymZmj867bAdxGbehIrew1DuLpw2Ukv+qDSSPQdYW1dLNE7t11A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-properties": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.27.1.tgz", + "integrity": "sha512-D0VcalChDMtuRvJIu3U/fwWjf8ZMykz5iZsg77Nuj821vCKI3zCyRLwRdWbsuJ/uRwZhZ002QtCqIkwC/ZkvbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.28.3.tgz", + "integrity": "sha512-LtPXlBbRoc4Njl/oh1CeD/3jC+atytbnf/UqLoqTDcEYGUPj022+rvfkbDYieUrSj3CaV4yHDByPE+T2HwfsJg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.28.3", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.4.tgz", + "integrity": "sha512-cFOlhIYPBv/iBoc+KS3M6et2XPtbT2HiCRfBXWtfpc9OAyostldxIf9YAYB6ypURBBbx+Qv6nyrLzASfJe+hBA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-globals": "^7.28.0", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-replace-supers": "^7.27.1", + "@babel/traverse": "^7.28.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.27.1.tgz", + "integrity": "sha512-lj9PGWvMTVksbWiDT2tW68zGS/cyo4AkZ/QTp0sQT0mjPopCmrSkzxeXkznjqBxzDI6TclZhOJbBmbBLjuOZUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/template": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.28.0.tgz", + "integrity": "sha512-v1nrSMBiKcodhsyJ4Gf+Z0U/yawmJDBOTpEB3mcQY52r9RIyPneGyAS/yM6seP/8I+mWI3elOMtT5dB8GJVs+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.28.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.27.1.tgz", + "integrity": "sha512-gEbkDVGRvjj7+T1ivxrfgygpT7GUd4vmODtYpbs0gZATdkX8/iSnOtZSxiZnsgm1YjTgjI6VKBGSJJevkrclzw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.27.1.tgz", + "integrity": "sha512-MTyJk98sHvSs+cvZ4nOauwTTG1JeonDjSGvGGUNHreGQns+Mpt6WX/dVzWBHgg+dYZhkC4X+zTDfkTU+Vy9y7Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.27.1.tgz", + "integrity": "sha512-hkGcueTEzuhB30B3eJCbCYeCaaEQOmQR0AdvzpD4LoN0GXMWzzGSuRrxR2xTnCrvNbVwK9N6/jQ92GSLfiZWoQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-dynamic-import": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.27.1.tgz", + "integrity": "sha512-MHzkWQcEmjzzVW9j2q8LGjwGWpG2mjwaaB0BNQwst3FIjqsg8Ct/mIZlvSPJvfi9y2AC8mi/ktxbFVL9pZ1I4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-explicit-resource-management": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-explicit-resource-management/-/plugin-transform-explicit-resource-management-7.28.0.tgz", + "integrity": "sha512-K8nhUcn3f6iB+P3gwCv/no7OdzOZQcKchW6N389V6PD8NUWKZHzndOd9sPDVbMoBsbmjMqlB4L9fm+fEFNVlwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/plugin-transform-destructuring": "^7.28.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.27.1.tgz", + "integrity": "sha512-uspvXnhHvGKf2r4VVtBpeFnuDWsJLQ6MF6lGJLC89jBR1uoVeqM416AZtTuhTezOfgHicpJQmoD5YUakO/YmXQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-export-namespace-from": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.27.1.tgz", + "integrity": "sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.27.1.tgz", + "integrity": "sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.27.1.tgz", + "integrity": "sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-json-strings": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.27.1.tgz", + "integrity": "sha512-6WVLVJiTjqcQauBhn1LkICsR2H+zm62I3h9faTDKt1qP4jn2o72tSvqMwtGFKGTpojce0gJs+76eZ2uCHRZh0Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-literals": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.27.1.tgz", + "integrity": "sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-logical-assignment-operators": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.27.1.tgz", + "integrity": "sha512-SJvDs5dXxiae4FbSL1aBJlG4wvl594N6YEVVn9e3JGulwioy6z3oPjx/sQBO3Y4NwUu5HNix6KJ3wBZoewcdbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.27.1.tgz", + "integrity": "sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.27.1.tgz", + "integrity": "sha512-iCsytMg/N9/oFq6n+gFTvUYDZQOMK5kEdeYxmxt91fcJGycfxVP9CnrxoliM0oumFERba2i8ZtwRUCMhvP1LnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.27.1.tgz", + "integrity": "sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.27.1.tgz", + "integrity": "sha512-w5N1XzsRbc0PQStASMksmUeqECuzKuTJer7kFagK8AXgpCMkeDMO5S+aaFb7A51ZYDF7XI34qsTX+fkHiIm5yA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.27.1.tgz", + "integrity": "sha512-iQBE/xC5BV1OxJbp6WG7jq9IWiD+xxlZhLrdwpPkTX3ydmXdvoCpyfJN7acaIBZaOqTfr76pgzqBJflNbeRK+w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.27.1.tgz", + "integrity": "sha512-SstR5JYy8ddZvD6MhV0tM/j16Qds4mIpJTOd1Yu9J9pJjH93bxHECF7pgtc28XvkzTD6Pxcm/0Z73Hvk7kb3Ng==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.27.1.tgz", + "integrity": "sha512-f6PiYeqXQ05lYq3TIfIDu/MtliKUbNwkGApPUvyo6+tc7uaR4cPjPe7DFPr15Uyycg2lZU6btZ575CuQoYh7MQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.27.1.tgz", + "integrity": "sha512-aGZh6xMo6q9vq1JGcw58lZ1Z0+i0xB2x0XaauNIUXd6O1xXc3RwoWEBlsTQrY4KQ9Jf0s5rgD6SiNkaUdJegTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-numeric-separator": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.27.1.tgz", + "integrity": "sha512-fdPKAcujuvEChxDBJ5c+0BTaS6revLV7CJL08e4m3de8qJfNIuCc2nc7XJYOjBoTMJeqSmwXJ0ypE14RCjLwaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-rest-spread": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.28.4.tgz", + "integrity": "sha512-373KA2HQzKhQCYiRVIRr+3MjpCObqzDlyrM6u4I201wL8Mp2wHf7uB8GhDwis03k2ti8Zr65Zyyqs1xOxUF/Ew==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/plugin-transform-destructuring": "^7.28.0", + "@babel/plugin-transform-parameters": "^7.27.7", + "@babel/traverse": "^7.28.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.27.1.tgz", + "integrity": "sha512-SFy8S9plRPbIcxlJ8A6mT/CxFdJx/c04JEctz4jf8YZaVS2px34j7NXRrlGlHkN/M2gnpL37ZpGRGVFLd3l8Ng==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-replace-supers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-catch-binding": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.27.1.tgz", + "integrity": "sha512-txEAEKzYrHEX4xSZN4kJ+OfKXFVSWKB2ZxM9dpcE3wT7smwkNmXo5ORRlVzMVdJbD+Q8ILTgSD7959uj+3Dm3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.27.1.tgz", + "integrity": "sha512-BQmKPPIuc8EkZgNKsv0X4bPmOoayeu4F1YCwx2/CfmDSXDbp7GnzlUH+/ul5VGfRg1AoFPsrIThlEBj2xb4CAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.27.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.27.7.tgz", + "integrity": "sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-methods": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.27.1.tgz", + "integrity": "sha512-10FVt+X55AjRAYI9BrdISN9/AQWHqldOeZDUoLyif1Kn05a56xVBXb8ZouL8pZ9jem8QpXaOt8TS7RHUIS+GPA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.27.1.tgz", + "integrity": "sha512-5J+IhqTi1XPa0DXF83jYOaARrX+41gOewWbkPyjMNRDqgOCqdffGh8L3f/Ek5utaEBZExjSAzcyjmV9SSAWObQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.1", + "@babel/helper-create-class-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.27.1.tgz", + "integrity": "sha512-oThy3BCuCha8kDZ8ZkgOg2exvPYUlprMukKQXI1r1pJ47NCvxfkEy8vK+r/hT9nF0Aa4H1WUPZZjHTFtAhGfmQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.28.4.tgz", + "integrity": "sha512-+ZEdQlBoRg9m2NnzvEeLgtvBMO4tkFBw5SQIUgLICgTrumLoU7lr+Oghi6km2PFj+dbUt2u1oby2w3BDO9YQnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regexp-modifiers": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.27.1.tgz", + "integrity": "sha512-TtEciroaiODtXvLZv4rmfMhkCv8jx3wgKpL68PuiPh2M4fvz5jhsA7697N1gMvkvr/JTF13DrFYyEbY9U7cVPA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.27.1.tgz", + "integrity": "sha512-V2ABPHIJX4kC7HegLkYoDpfg9PVmuWy/i6vUM5eGK22bx4YVFD3M5F0QQnWQoDs6AGsUWTVOopBiMFQgHaSkVw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.27.1.tgz", + "integrity": "sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-spread": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.27.1.tgz", + "integrity": "sha512-kpb3HUqaILBJcRFVhFUs6Trdd4mkrzcGXss+6/mxUd273PfbWqSDHRzMT2234gIg2QYfAjvXLSquP1xECSg09Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.27.1.tgz", + "integrity": "sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.27.1.tgz", + "integrity": "sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.27.1.tgz", + "integrity": "sha512-RiSILC+nRJM7FY5srIyc4/fGIwUhyDuuBSdWn4y6yT6gm652DpCHZjIipgn6B7MQ1ITOUnAKWixEUjQRIBIcLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typescript": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.28.0.tgz", + "integrity": "sha512-4AEiDEBPIZvLQaWlc9liCavE0xRM0dNca41WtBeM3jgFptfUOSG9z0uteLhq6+3rq+WB6jIvUwKDTpXEHPJ2Vg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-create-class-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", + "@babel/plugin-syntax-typescript": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.27.1.tgz", + "integrity": "sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-property-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.27.1.tgz", + "integrity": "sha512-uW20S39PnaTImxp39O5qFlHLS9LJEmANjMG7SxIhap8rCHqu0Ik+tLEPX5DKmHn6CsWQ7j3lix2tFOa5YtL12Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.27.1.tgz", + "integrity": "sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-sets-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.27.1.tgz", + "integrity": "sha512-EtkOujbc4cgvb0mlpQefi4NTPBzhSIevblFevACNLUspmrALgmEBdL/XfnyyITfd8fKBZrZys92zOWcik7j9Tw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/preset-env": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.28.3.tgz", + "integrity": "sha512-ROiDcM+GbYVPYBOeCR6uBXKkQpBExLl8k9HO1ygXEyds39j+vCCsjmj7S8GOniZQlEs81QlkdJZe76IpLSiqpg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.28.0", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-validator-option": "^7.27.1", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.27.1", + "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.27.1", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.27.1", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.27.1", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.28.3", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", + "@babel/plugin-syntax-import-assertions": "^7.27.1", + "@babel/plugin-syntax-import-attributes": "^7.27.1", + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.27.1", + "@babel/plugin-transform-async-generator-functions": "^7.28.0", + "@babel/plugin-transform-async-to-generator": "^7.27.1", + "@babel/plugin-transform-block-scoped-functions": "^7.27.1", + "@babel/plugin-transform-block-scoping": "^7.28.0", + "@babel/plugin-transform-class-properties": "^7.27.1", + "@babel/plugin-transform-class-static-block": "^7.28.3", + "@babel/plugin-transform-classes": "^7.28.3", + "@babel/plugin-transform-computed-properties": "^7.27.1", + "@babel/plugin-transform-destructuring": "^7.28.0", + "@babel/plugin-transform-dotall-regex": "^7.27.1", + "@babel/plugin-transform-duplicate-keys": "^7.27.1", + "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.27.1", + "@babel/plugin-transform-dynamic-import": "^7.27.1", + "@babel/plugin-transform-explicit-resource-management": "^7.28.0", + "@babel/plugin-transform-exponentiation-operator": "^7.27.1", + "@babel/plugin-transform-export-namespace-from": "^7.27.1", + "@babel/plugin-transform-for-of": "^7.27.1", + "@babel/plugin-transform-function-name": "^7.27.1", + "@babel/plugin-transform-json-strings": "^7.27.1", + "@babel/plugin-transform-literals": "^7.27.1", + "@babel/plugin-transform-logical-assignment-operators": "^7.27.1", + "@babel/plugin-transform-member-expression-literals": "^7.27.1", + "@babel/plugin-transform-modules-amd": "^7.27.1", + "@babel/plugin-transform-modules-commonjs": "^7.27.1", + "@babel/plugin-transform-modules-systemjs": "^7.27.1", + "@babel/plugin-transform-modules-umd": "^7.27.1", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.27.1", + "@babel/plugin-transform-new-target": "^7.27.1", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.27.1", + "@babel/plugin-transform-numeric-separator": "^7.27.1", + "@babel/plugin-transform-object-rest-spread": "^7.28.0", + "@babel/plugin-transform-object-super": "^7.27.1", + "@babel/plugin-transform-optional-catch-binding": "^7.27.1", + "@babel/plugin-transform-optional-chaining": "^7.27.1", + "@babel/plugin-transform-parameters": "^7.27.7", + "@babel/plugin-transform-private-methods": "^7.27.1", + "@babel/plugin-transform-private-property-in-object": "^7.27.1", + "@babel/plugin-transform-property-literals": "^7.27.1", + "@babel/plugin-transform-regenerator": "^7.28.3", + "@babel/plugin-transform-regexp-modifiers": "^7.27.1", + "@babel/plugin-transform-reserved-words": "^7.27.1", + "@babel/plugin-transform-shorthand-properties": "^7.27.1", + "@babel/plugin-transform-spread": "^7.27.1", + "@babel/plugin-transform-sticky-regex": "^7.27.1", + "@babel/plugin-transform-template-literals": "^7.27.1", + "@babel/plugin-transform-typeof-symbol": "^7.27.1", + "@babel/plugin-transform-unicode-escapes": "^7.27.1", + "@babel/plugin-transform-unicode-property-regex": "^7.27.1", + "@babel/plugin-transform-unicode-regex": "^7.27.1", + "@babel/plugin-transform-unicode-sets-regex": "^7.27.1", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "babel-plugin-polyfill-corejs2": "^0.4.14", + "babel-plugin-polyfill-corejs3": "^0.13.0", + "babel-plugin-polyfill-regenerator": "^0.6.5", + "core-js-compat": "^3.43.0", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-modules": { + "version": "0.1.6-no-external-plugins", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", + "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/preset-typescript": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.27.1.tgz", + "integrity": "sha512-l7WfQfX0WK4M0v2RudjuQK4u99BS6yLHYEmdtVPP7lKV013zr9DygFuWNlnbvQ9LR+LS0Egz/XAvGx5U9MX0fQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-validator-option": "^7.27.1", + "@babel/plugin-syntax-jsx": "^7.27.1", + "@babel/plugin-transform-modules-commonjs": "^7.27.1", + "@babel/plugin-transform-typescript": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/template": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", + "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/parser": "^7.27.2", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.4.tgz", + "integrity": "sha512-YEzuboP2qvQavAcjgQNVgsvHIDv6ZpwXvcvjmyySP2DIMuByS/6ioU5G9pYrWHM6T2YDfc7xga9iNzYOs12CFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.3", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.28.4", + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.4", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.4.tgz", + "integrity": "sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@commitlint/cli": { + "version": "19.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-19.8.1.tgz", + "integrity": "sha512-LXUdNIkspyxrlV6VDHWBmCZRtkEVRpBKxi2Gtw3J54cGWhLCTouVD/Q6ZSaSvd2YaDObWK8mDjrz3TIKtaQMAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/format": "^19.8.1", + "@commitlint/lint": "^19.8.1", + "@commitlint/load": "^19.8.1", + "@commitlint/read": "^19.8.1", + "@commitlint/types": "^19.8.1", + "tinyexec": "^1.0.0", + "yargs": "^17.0.0" + }, + "bin": { + "commitlint": "cli.js" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/config-conventional": { + "version": "19.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-19.8.1.tgz", + "integrity": "sha512-/AZHJL6F6B/G959CsMAzrPKKZjeEiAVifRyEwXxcT6qtqbPwGw+iQxmNS+Bu+i09OCtdNRW6pNpBvgPrtMr9EQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/types": "^19.8.1", + "conventional-changelog-conventionalcommits": "^7.0.2" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/config-validator": { + "version": "19.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-19.8.1.tgz", + "integrity": "sha512-0jvJ4u+eqGPBIzzSdqKNX1rvdbSU1lPNYlfQQRIFnBgLy26BtC0cFnr7c/AyuzExMxWsMOte6MkTi9I3SQ3iGQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/types": "^19.8.1", + "ajv": "^8.11.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/ensure": { + "version": "19.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-19.8.1.tgz", + "integrity": "sha512-mXDnlJdvDzSObafjYrOSvZBwkD01cqB4gbnnFuVyNpGUM5ijwU/r/6uqUmBXAAOKRfyEjpkGVZxaDsCVnHAgyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/types": "^19.8.1", + "lodash.camelcase": "^4.3.0", + "lodash.kebabcase": "^4.1.1", + "lodash.snakecase": "^4.1.1", + "lodash.startcase": "^4.4.0", + "lodash.upperfirst": "^4.3.1" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/execute-rule": { + "version": "19.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-19.8.1.tgz", + "integrity": "sha512-YfJyIqIKWI64Mgvn/sE7FXvVMQER/Cd+s3hZke6cI1xgNT/f6ZAz5heND0QtffH+KbcqAwXDEE1/5niYayYaQA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/format": { + "version": "19.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-19.8.1.tgz", + "integrity": "sha512-kSJj34Rp10ItP+Eh9oCItiuN/HwGQMXBnIRk69jdOwEW9llW9FlyqcWYbHPSGofmjsqeoxa38UaEA5tsbm2JWw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/types": "^19.8.1", + "chalk": "^5.3.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/is-ignored": { + "version": "19.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-19.8.1.tgz", + "integrity": "sha512-AceOhEhekBUQ5dzrVhDDsbMaY5LqtN8s1mqSnT2Kz1ERvVZkNihrs3Sfk1Je/rxRNbXYFzKZSHaPsEJJDJV8dg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/types": "^19.8.1", + "semver": "^7.6.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/is-ignored/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@commitlint/lint": { + "version": "19.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-19.8.1.tgz", + "integrity": "sha512-52PFbsl+1EvMuokZXLRlOsdcLHf10isTPlWwoY1FQIidTsTvjKXVXYb7AvtpWkDzRO2ZsqIgPK7bI98x8LRUEw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/is-ignored": "^19.8.1", + "@commitlint/parse": "^19.8.1", + "@commitlint/rules": "^19.8.1", + "@commitlint/types": "^19.8.1" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/load": { + "version": "19.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-19.8.1.tgz", + "integrity": "sha512-9V99EKG3u7z+FEoe4ikgq7YGRCSukAcvmKQuTtUyiYPnOd9a2/H9Ak1J9nJA1HChRQp9OA/sIKPugGS+FK/k1A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/config-validator": "^19.8.1", + "@commitlint/execute-rule": "^19.8.1", + "@commitlint/resolve-extends": "^19.8.1", + "@commitlint/types": "^19.8.1", + "chalk": "^5.3.0", + "cosmiconfig": "^9.0.0", + "cosmiconfig-typescript-loader": "^6.1.0", + "lodash.isplainobject": "^4.0.6", + "lodash.merge": "^4.6.2", + "lodash.uniq": "^4.5.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/message": { + "version": "19.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-19.8.1.tgz", + "integrity": "sha512-+PMLQvjRXiU+Ae0Wc+p99EoGEutzSXFVwQfa3jRNUZLNW5odZAyseb92OSBTKCu+9gGZiJASt76Cj3dLTtcTdg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/parse": { + "version": "19.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-19.8.1.tgz", + "integrity": "sha512-mmAHYcMBmAgJDKWdkjIGq50X4yB0pSGpxyOODwYmoexxxiUCy5JJT99t1+PEMK7KtsCtzuWYIAXYAiKR+k+/Jw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/types": "^19.8.1", + "conventional-changelog-angular": "^7.0.0", + "conventional-commits-parser": "^5.0.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/read": { + "version": "19.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-19.8.1.tgz", + "integrity": "sha512-03Jbjb1MqluaVXKHKRuGhcKWtSgh3Jizqy2lJCRbRrnWpcM06MYm8th59Xcns8EqBYvo0Xqb+2DoZFlga97uXQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/top-level": "^19.8.1", + "@commitlint/types": "^19.8.1", + "git-raw-commits": "^4.0.0", + "minimist": "^1.2.8", + "tinyexec": "^1.0.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/resolve-extends": { + "version": "19.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-19.8.1.tgz", + "integrity": "sha512-GM0mAhFk49I+T/5UCYns5ayGStkTt4XFFrjjf0L4S26xoMTSkdCf9ZRO8en1kuopC4isDFuEm7ZOm/WRVeElVg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/config-validator": "^19.8.1", + "@commitlint/types": "^19.8.1", + "global-directory": "^4.0.1", + "import-meta-resolve": "^4.0.0", + "lodash.mergewith": "^4.6.2", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/rules": { + "version": "19.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-19.8.1.tgz", + "integrity": "sha512-Hnlhd9DyvGiGwjfjfToMi1dsnw1EXKGJNLTcsuGORHz6SS9swRgkBsou33MQ2n51/boIDrbsg4tIBbRpEWK2kw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@commitlint/ensure": "^19.8.1", + "@commitlint/message": "^19.8.1", + "@commitlint/to-lines": "^19.8.1", + "@commitlint/types": "^19.8.1" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/to-lines": { + "version": "19.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-19.8.1.tgz", + "integrity": "sha512-98Mm5inzbWTKuZQr2aW4SReY6WUukdWXuZhrqf1QdKPZBCCsXuG87c+iP0bwtD6DBnmVVQjgp4whoHRVixyPBg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/top-level": { + "version": "19.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-19.8.1.tgz", + "integrity": "sha512-Ph8IN1IOHPSDhURCSXBz44+CIu+60duFwRsg6HqaISFHQHbmBtxVw4ZrFNIYUzEP7WwrNPxa2/5qJ//NK1FGcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^7.0.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@commitlint/types": { + "version": "19.8.1", + "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-19.8.1.tgz", + "integrity": "sha512-/yCrWGCoA1SVKOks25EGadP9Pnj0oAIHGpl2wH2M2Y46dPM2ueb8wyCVOD7O3WCTkaJ0IkKvzhl1JY7+uCT2Dw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/conventional-commits-parser": "^5.0.0", + "chalk": "^5.3.0" + }, + "engines": { + "node": ">=v18" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@dependents/detective-less": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@dependents/detective-less/-/detective-less-5.0.1.tgz", + "integrity": "sha512-Y6+WUMsTFWE5jb20IFP4YGa5IrGY/+a/FbOSjDF/wz9gepU2hwCYSXRHP/vPwBvwcY3SVMASt4yXxbXNXigmZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "gonzales-pe": "^4.3.0", + "node-source-walk": "^7.0.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@dimforge/rapier3d-compat": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@dimforge/rapier3d-compat/-/rapier3d-compat-0.12.0.tgz", + "integrity": "sha512-uekIGetywIgopfD97oDL5PfeezkFpNhwlzlaEYNOA0N6ghdsOvh/HYjSMek5Q2O1PYvRSDFcqFVJl4r4ZBwOow==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/@discoveryjs/json-ext": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", + "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz", + "integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.0.tgz", + "integrity": "sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.6", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-array/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.0.tgz", + "integrity": "sha512-WUFvV4WoIwW8Bv0KeKCIIEgdSiFOsulyN0xrMu+7z43q/hkOLXjvb5u7UC9jDxvRzcrbEmuZBX5yJZz1741jog==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.16.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.16.0.tgz", + "integrity": "sha512-nmC8/totwobIiFcGkDza3GIKfAw1+hLiYVrh3I1nIomQ8PEr5cxg34jnkmGawul/ep52wGRAcyeDCNtWKSOj4Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", + "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@eslint/eslintrc/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/eslintrc/node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/@eslint/eslintrc/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/js": { + "version": "9.37.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.37.0.tgz", + "integrity": "sha512-jaS+NJ+hximswBG6pjNX0uEJZkrT0zwpVi3BA3vX22aFGjJjmgSTSmPpZCRKmoBL5VY/M6p0xsSJx7rk7sy5gg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz", + "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.0.tgz", + "integrity": "sha512-sB5uyeq+dwCWyPi31B2gQlVlo+j5brPlWx4yZBrEaRo/nhdDE8Xke1gsGgtiBdaBTxuTkceLVuVt/pclrasb0A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.16.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@gerrit0/mini-shiki": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/@gerrit0/mini-shiki/-/mini-shiki-3.13.1.tgz", + "integrity": "sha512-fDWM5QQc70jwBIt/WYMybdyXdyBmoJe7r1hpM+V/bHnyla79sygVDK2/LlVxIPc4n5FA3B5Wzt7AQH2+psNphg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/engine-oniguruma": "^3.13.0", + "@shikijs/langs": "^3.13.0", + "@shikijs/themes": "^3.13.0", + "@shikijs/types": "^3.13.0", + "@shikijs/vscode-textmate": "^10.0.2" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.7", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", + "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.4.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@isaacs/balanced-match": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz", + "integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/@isaacs/brace-expansion": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz", + "integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@isaacs/balanced-match": "^4.0.1" + }, + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz", + "integrity": "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/console/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/console/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/core": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz", + "integrity": "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/reporters": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^29.7.0", + "jest-config": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-resolve-dependencies": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "jest-watcher": "^29.7.0", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/core/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/core/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/environment": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", + "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/expect": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "expect": "^29.7.0", + "jest-snapshot": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/expect-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", + "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "jest-get-type": "^29.6.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/fake-timers": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", + "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@sinonjs/fake-timers": "^10.0.2", + "@types/node": "*", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/globals": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz", + "integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/types": "^29.6.3", + "jest-mock": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/reporters": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz", + "integrity": "sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^6.0.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "slash": "^3.0.0", + "string-length": "^4.0.1", + "strip-ansi": "^6.0.0", + "v8-to-istanbul": "^9.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/reporters/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/reporters/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/reporters/node_modules/istanbul-lib-instrument": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", + "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@babel/core": "^7.23.9", + "@babel/parser": "^7.23.9", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@jest/reporters/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/source-map": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz", + "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.18", + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/test-result": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz", + "integrity": "sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/test-sequencer": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz", + "integrity": "sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/test-result": "^29.7.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/transform": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", + "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.2" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/transform/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/transform/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/types/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/types/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz", + "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@pkgr/core": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.9.tgz", + "integrity": "sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/pkgr" + } + }, + "node_modules/@polka/url": { + "version": "1.0.0-next.29", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz", + "integrity": "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rtsao/scc": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", + "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", + "dev": true, + "license": "MIT" + }, + "node_modules/@shikijs/engine-oniguruma": { + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-3.13.0.tgz", + "integrity": "sha512-O42rBGr4UDSlhT2ZFMxqM7QzIU+IcpoTMzb3W7AlziI1ZF7R8eS2M0yt5Ry35nnnTX/LTLXFPUjRFCIW+Operg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.13.0", + "@shikijs/vscode-textmate": "^10.0.2" + } + }, + "node_modules/@shikijs/langs": { + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-3.13.0.tgz", + "integrity": "sha512-672c3WAETDYHwrRP0yLy3W1QYB89Hbpj+pO4KhxK6FzIrDI2FoEXNiNCut6BQmEApYLfuYfpgOZaqbY+E9b8wQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.13.0" + } + }, + "node_modules/@shikijs/themes": { + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-3.13.0.tgz", + "integrity": "sha512-Vxw1Nm1/Od8jyA7QuAenaV78BG2nSr3/gCGdBkLpfLscddCkzkL36Q5b67SrLLfvAJTOUzW39x4FHVCFriPVgg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.13.0" + } + }, + "node_modules/@shikijs/types": { + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-3.13.0.tgz", + "integrity": "sha512-oM9P+NCFri/mmQ8LoFGVfVyemm5Hi27330zuOBp0annwJdKH1kOLndw3zCtAVDehPLg9fKqoEx3Ht/wNZxolfw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.4" + } + }, + "node_modules/@shikijs/vscode-textmate": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-10.0.2.tgz", + "integrity": "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@sinonjs/commons": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", + "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^3.0.0" + } + }, + "node_modules/@ts-graphviz/adapter": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@ts-graphviz/adapter/-/adapter-2.0.6.tgz", + "integrity": "sha512-kJ10lIMSWMJkLkkCG5gt927SnGZcBuG0s0HHswGzcHTgvtUe7yk5/3zTEr0bafzsodsOq5Gi6FhQeV775nC35Q==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ts-graphviz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/ts-graphviz" + } + ], + "license": "MIT", + "dependencies": { + "@ts-graphviz/common": "^2.1.5" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@ts-graphviz/ast": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@ts-graphviz/ast/-/ast-2.0.7.tgz", + "integrity": "sha512-e6+2qtNV99UT6DJSoLbHfkzfyqY84aIuoV8Xlb9+hZAjgpum8iVHprGeAMQ4rF6sKUAxrmY8rfF/vgAwoPc3gw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ts-graphviz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/ts-graphviz" + } + ], + "license": "MIT", + "dependencies": { + "@ts-graphviz/common": "^2.1.5" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@ts-graphviz/common": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@ts-graphviz/common/-/common-2.1.5.tgz", + "integrity": "sha512-S6/9+T6x8j6cr/gNhp+U2olwo1n0jKj/682QVqsh7yXWV6ednHYqxFw0ZsY3LyzT0N8jaZ6jQY9YD99le3cmvg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ts-graphviz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/ts-graphviz" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@ts-graphviz/core": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@ts-graphviz/core/-/core-2.0.7.tgz", + "integrity": "sha512-w071DSzP94YfN6XiWhOxnLpYT3uqtxJBDYdh6Jdjzt+Ce6DNspJsPQgpC7rbts/B8tEkq0LHoYuIF/O5Jh5rPg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ts-graphviz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/ts-graphviz" + } + ], + "license": "MIT", + "dependencies": { + "@ts-graphviz/ast": "^2.0.7", + "@ts-graphviz/common": "^2.1.5" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", + "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tweenjs/tween.js": { + "version": "23.1.3", + "resolved": "https://registry.npmjs.org/@tweenjs/tween.js/-/tween.js-23.1.3.tgz", + "integrity": "sha512-vJmvvwFxYuGnF2axRtPYocag6Clbb5YS7kLL+SO/TeVFzHqDIWrNKYtcsPMibjDx9O+bu+psAy9NKfWklassUA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", + "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.2" + } + }, + "node_modules/@types/conventional-commits-parser": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@types/conventional-commits-parser/-/conventional-commits-parser-5.0.1.tgz", + "integrity": "sha512-7uz5EHdzz2TqoMfV7ee61Egf5y6NkcO4FB/1iCCQnbeiI1F3xzv3vK5dBCXUCLQgGYS+mUeigK1iKQzvED+QnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/eslint": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", + "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/graceful-fs": { + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", + "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", + "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", + "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/jest": { + "version": "29.5.14", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.14.tgz", + "integrity": "sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "expect": "^29.0.0", + "pretty-format": "^29.0.0" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "22.18.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.18.10.tgz", + "integrity": "sha512-anNG/V/Efn/YZY4pRzbACnKxNKoBng2VTFydVu8RRs5hQjikP8CQfaeAV59VFSCzKNp90mXiVXW2QzV56rwMrg==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@types/stack-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/stats.js": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/stats.js/-/stats.js-0.17.4.tgz", + "integrity": "sha512-jIBvWWShCvlBqBNIZt0KAshWpvSjhkwkEu4ZUcASoAvhmrgAUI2t1dXrjSL4xXVLB4FznPrIsX3nKXFl/Dt4vA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/three": { + "version": "0.177.0", + "resolved": "https://registry.npmjs.org/@types/three/-/three-0.177.0.tgz", + "integrity": "sha512-/ZAkn4OLUijKQySNci47lFO+4JLE1TihEjsGWPUT+4jWqxtwOPPEwJV1C3k5MEx0mcBPCdkFjzRzDOnHEI1R+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@dimforge/rapier3d-compat": "~0.12.0", + "@tweenjs/tween.js": "~23.1.3", + "@types/stats.js": "*", + "@types/webxr": "*", + "@webgpu/types": "*", + "fflate": "~0.8.2", + "meshoptimizer": "~0.18.1" + } + }, + "node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/webxr": { + "version": "0.5.24", + "resolved": "https://registry.npmjs.org/@types/webxr/-/webxr-0.5.24.tgz", + "integrity": "sha512-h8fgEd/DpoS9CBrjEQXR+dIDraopAEfu4wYVNY2tEPwk60stPWhvZMf4Foo5FakuQ7HFZoa8WceaWFervK2Ovg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/yargs": { + "version": "17.0.33", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz", + "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.46.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.46.1.tgz", + "integrity": "sha512-rUsLh8PXmBjdiPY+Emjz9NX2yHvhS11v0SR6xNJkm5GM1MO9ea/1GoDKlHHZGrOJclL/cZ2i/vRUYVtjRhrHVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "8.46.1", + "@typescript-eslint/type-utils": "8.46.1", + "@typescript-eslint/utils": "8.46.1", + "@typescript-eslint/visitor-keys": "8.46.1", + "graphemer": "^1.4.0", + "ignore": "^7.0.0", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.46.1", + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.46.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.46.1.tgz", + "integrity": "sha512-6JSSaBZmsKvEkbRUkf7Zj7dru/8ZCrJxAqArcLaVMee5907JdtEbKGsZ7zNiIm/UAkpGUkaSMZEXShnN2D1HZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/scope-manager": "8.46.1", + "@typescript-eslint/types": "8.46.1", + "@typescript-eslint/typescript-estree": "8.46.1", + "@typescript-eslint/visitor-keys": "8.46.1", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/project-service": { + "version": "8.46.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.46.1.tgz", + "integrity": "sha512-FOIaFVMHzRskXr5J4Jp8lFVV0gz5ngv3RHmn+E4HYxSJ3DgDzU7fVI1/M7Ijh1zf6S7HIoaIOtln1H5y8V+9Zg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.46.1", + "@typescript-eslint/types": "^8.46.1", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.46.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.46.1.tgz", + "integrity": "sha512-weL9Gg3/5F0pVQKiF8eOXFZp8emqWzZsOJuWRUNtHT+UNV2xSJegmpCNQHy37aEQIbToTq7RHKhWvOsmbM680A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.46.1", + "@typescript-eslint/visitor-keys": "8.46.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.46.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.46.1.tgz", + "integrity": "sha512-X88+J/CwFvlJB+mK09VFqx5FE4H5cXD+H/Bdza2aEWkSb8hnWIQorNcscRl4IEo1Cz9VI/+/r/jnGWkbWPx54g==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.46.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.46.1.tgz", + "integrity": "sha512-+BlmiHIiqufBxkVnOtFwjah/vrkF4MtKKvpXrKSPLCkCtAp8H01/VV43sfqA98Od7nJpDcFnkwgyfQbOG0AMvw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.46.1", + "@typescript-eslint/typescript-estree": "8.46.1", + "@typescript-eslint/utils": "8.46.1", + "debug": "^4.3.4", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.46.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.46.1.tgz", + "integrity": "sha512-C+soprGBHwWBdkDpbaRC4paGBrkIXxVlNohadL5o0kfhsXqOC6GYH2S/Obmig+I0HTDl8wMaRySwrfrXVP8/pQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.46.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.46.1.tgz", + "integrity": "sha512-uIifjT4s8cQKFQ8ZBXXyoUODtRoAd7F7+G8MKmtzj17+1UbdzFl52AzRyZRyKqPHhgzvXunnSckVu36flGy8cg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.46.1", + "@typescript-eslint/tsconfig-utils": "8.46.1", + "@typescript-eslint/types": "8.46.1", + "@typescript-eslint/visitor-keys": "8.46.1", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.46.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.46.1.tgz", + "integrity": "sha512-vkYUy6LdZS7q1v/Gxb2Zs7zziuXN0wxqsetJdeZdRe/f5dwJFglmuvZBfTUivCtjH725C1jWCDfpadadD95EDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.7.0", + "@typescript-eslint/scope-manager": "8.46.1", + "@typescript-eslint/types": "8.46.1", + "@typescript-eslint/typescript-estree": "8.46.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.46.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.46.1.tgz", + "integrity": "sha512-ptkmIf2iDkNUjdeu2bQqhFPV1m6qTnFFjg7PPDjxKWaMaP0Z6I9l30Jr3g5QqbZGdw8YdYvLp+XnqnWWZOg/NA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.46.1", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@vue/compiler-core": { + "version": "3.5.22", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.22.tgz", + "integrity": "sha512-jQ0pFPmZwTEiRNSb+i9Ow/I/cHv2tXYqsnHKKyCQ08irI2kdF5qmYedmF8si8mA7zepUFmJ2hqzS8CQmNOWOkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.4", + "@vue/shared": "3.5.22", + "entities": "^4.5.0", + "estree-walker": "^2.0.2", + "source-map-js": "^1.2.1" + } + }, + "node_modules/@vue/compiler-dom": { + "version": "3.5.22", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.22.tgz", + "integrity": "sha512-W8RknzUM1BLkypvdz10OVsGxnMAuSIZs9Wdx1vzA3mL5fNMN15rhrSCLiTm6blWeACwUwizzPVqGJgOGBEN/hA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/compiler-core": "3.5.22", + "@vue/shared": "3.5.22" + } + }, + "node_modules/@vue/compiler-sfc": { + "version": "3.5.22", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.22.tgz", + "integrity": "sha512-tbTR1zKGce4Lj+JLzFXDq36K4vcSZbJ1RBu8FxcDv1IGRz//Dh2EBqksyGVypz3kXpshIfWKGOCcqpSbyGWRJQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.4", + "@vue/compiler-core": "3.5.22", + "@vue/compiler-dom": "3.5.22", + "@vue/compiler-ssr": "3.5.22", + "@vue/shared": "3.5.22", + "estree-walker": "^2.0.2", + "magic-string": "^0.30.19", + "postcss": "^8.5.6", + "source-map-js": "^1.2.1" + } + }, + "node_modules/@vue/compiler-ssr": { + "version": "3.5.22", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.22.tgz", + "integrity": "sha512-GdgyLvg4R+7T8Nk2Mlighx7XGxq/fJf9jaVofc3IL0EPesTE86cP/8DD1lT3h1JeZr2ySBvyqKQJgbS54IX1Ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/compiler-dom": "3.5.22", + "@vue/shared": "3.5.22" + } + }, + "node_modules/@vue/shared": { + "version": "3.5.22", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.22.tgz", + "integrity": "sha512-F4yc6palwq3TT0u+FYf0Ns4Tfl9GRFURDN2gWG7L1ecIaS/4fCIuFOjMTnCyjsu/OK6vaDKLCrGAa+KvvH+h4w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", + "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/helper-numbers": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", + "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", + "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", + "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", + "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.13.2", + "@webassemblyjs/helper-api-error": "1.13.2", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", + "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", + "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/wasm-gen": "1.14.1" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", + "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", + "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", + "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", + "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/helper-wasm-section": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-opt": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1", + "@webassemblyjs/wast-printer": "1.14.1" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", + "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", + "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", + "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-api-error": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", + "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webgpu/types": { + "version": "0.1.66", + "resolved": "https://registry.npmjs.org/@webgpu/types/-/types-0.1.66.tgz", + "integrity": "sha512-YA2hLrwLpDsRueNDXIMqN9NTzD6bCDkuXbOSe0heS+f8YE8usA6Gbv1prj81pzVHrbaAma7zObnIC+I6/sXJgA==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@webpack-cli/configtest": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-3.0.1.tgz", + "integrity": "sha512-u8d0pJ5YFgneF/GuvEiDA61Tf1VDomHHYMjv/wc9XzYj7nopltpG96nXN5dJRstxZhcNpV1g+nT6CydO7pHbjA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12.0" + }, + "peerDependencies": { + "webpack": "^5.82.0", + "webpack-cli": "6.x.x" + } + }, + "node_modules/@webpack-cli/info": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-3.0.1.tgz", + "integrity": "sha512-coEmDzc2u/ffMvuW9aCjoRzNSPDl/XLuhPdlFRpT9tZHmJ/039az33CE7uH+8s0uL1j5ZNtfdv0HkfaKRBGJsQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12.0" + }, + "peerDependencies": { + "webpack": "^5.82.0", + "webpack-cli": "6.x.x" + } + }, + "node_modules/@webpack-cli/serve": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-3.0.1.tgz", + "integrity": "sha512-sbgw03xQaCLiT6gcY/6u3qBDn01CWw/nbaXl3gTdTFuJJ75Gffv3E3DBpgvY2fkkrdS1fpjaXNOmJlnbtKauKg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12.0" + }, + "peerDependencies": { + "webpack": "^5.82.0", + "webpack-cli": "6.x.x" + }, + "peerDependenciesMeta": { + "webpack-dev-server": { + "optional": true + } + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-import-phases": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz", + "integrity": "sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.13.0" + }, + "peerDependencies": { + "acorn": "^8.14.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", + "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "dev": true, + "license": "MIT" + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/app-module-path": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/app-module-path/-/app-module-path-2.2.0.tgz", + "integrity": "sha512-gkco+qxENJV+8vFcDiiFhuoSvRXb2a/QPqpSoWhVz829VNJfOTnELbBmPmNKFxf3xdNnw4DWCkzkDaavcX/1YQ==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true, + "license": "MIT" + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", + "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "is-array-buffer": "^3.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-ify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz", + "integrity": "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==", + "dev": true, + "license": "MIT" + }, + "node_modules/array-includes": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.9.tgz", + "integrity": "sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.24.0", + "es-object-atoms": "^1.1.1", + "get-intrinsic": "^1.3.0", + "is-string": "^1.1.1", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.findlastindex": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.6.tgz", + "integrity": "sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-shim-unscopables": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz", + "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz", + "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", + "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ast-module-types": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ast-module-types/-/ast-module-types-6.0.1.tgz", + "integrity": "sha512-WHw67kLXYbZuHTmcdbIrVArCq5wxo6NEuj3hiYAWr8mwJeC+C2mMCIBIWCiDoCye/OF/xelc+teJ1ERoWmnEIA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/async-function": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", + "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/babel-jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", + "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/transform": "^29.7.0", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^29.6.3", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.8.0" + } + }, + "node_modules/babel-jest/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/babel-jest/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-jest-hoist": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", + "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.1.14", + "@types/babel__traverse": "^7.0.6" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.4.14", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.14.tgz", + "integrity": "sha512-Co2Y9wX854ts6U8gAAPXfn0GmAyctHuK8n0Yhfjd6t30g7yvKjspvvOo9yG+z52PZRgFErt7Ka2pYnXCjLKEpg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.27.7", + "@babel/helper-define-polyfill-provider": "^0.6.5", + "semver": "^6.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.13.0.tgz", + "integrity": "sha512-U+GNwMdSFgzVmfhNm8GJUX88AadB3uo9KpJqS3FaqNIPKgySuvMb+bHPsOmmuWyIcuqZj/pzt1RUIUZns4y2+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.5", + "core-js-compat": "^3.43.0" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.5.tgz", + "integrity": "sha512-ISqQ2frbiNU9vIJkzg7dlPpznPZ4jOiUQ1uSmB0fEHeowtN3COYRsXr/xexn64NpU13P06jc/L5TgiJXOgrbEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.5" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-preset-current-node-syntax": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.2.0.tgz", + "integrity": "sha512-E/VlAEzRrsLEb2+dv8yp3bo4scof3l9nR4lrld+Iy5NyVqgVYUJnDAmunkhPMisRI32Qc4iRiz425d8vM++2fg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-import-attributes": "^7.24.7", + "@babel/plugin-syntax-import-meta": "^7.10.4", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5" + }, + "peerDependencies": { + "@babel/core": "^7.0.0 || ^8.0.0-0" + } + }, + "node_modules/babel-preset-jest": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", + "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-plugin-jest-hoist": "^29.6.3", + "babel-preset-current-node-syntax": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/baseline-browser-mapping": { + "version": "2.8.16", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.16.tgz", + "integrity": "sha512-OMu3BGQ4E7P1ErFsIPpbJh0qvDudM/UuJeHgkAvfWe+0HFJCXh+t/l8L6fVLR55RI/UbKrVLnAXZSVwd9ysWYw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.js" + } + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.26.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.26.3.tgz", + "integrity": "sha512-lAUU+02RFBuCKQPj/P6NgjlbCnLBMp4UtgTx7vNHd3XSIJF87s9a5rA3aH2yw3GS9DqZAUbOtZdCCiZeVRqt0w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.8.9", + "caniuse-lite": "^1.0.30001746", + "electron-to-chromium": "^1.5.227", + "node-releases": "^2.0.21", + "update-browserslist-db": "^1.1.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/bs-logger": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", + "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-json-stable-stringify": "2.x" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "node-int64": "^0.4.0" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/call-bind": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001750", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001750.tgz", + "integrity": "sha512-cuom0g5sdX6rw00qOoLNSFCJ9/mYIsuSOA+yzpDw8eopiFqcVwQvZHqov0vmEighRxX++cfC0Vg1G+1Iy/mSpQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chalk": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/chrome-trace-event": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", + "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0" + } + }, + "node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cjs-module-lexer": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz", + "integrity": "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-spinners": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", + "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/collect-v8-coverage": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.3.tgz", + "integrity": "sha512-1L5aqIkwPfiodaMgQunkF1zRhNqifHBmtbbbxcr6yVxxBnliw4TDOW6NxpO8DJLgJ16OT+Y4ztZqP6p/FtXnAw==", + "dev": true, + "license": "MIT" + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", + "dev": true, + "license": "MIT" + }, + "node_modules/compare-func": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", + "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-ify": "^1.0.0", + "dot-prop": "^5.1.0" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/conventional-changelog-angular": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-7.0.0.tgz", + "integrity": "sha512-ROjNchA9LgfNMTTFSIWPzebCwOGFdgkEq45EnvvrmSLvCtAw0HSmrCs7/ty+wAeYUZyNay0YMUNYFTRL72PkBQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "compare-func": "^2.0.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/conventional-changelog-conventionalcommits": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-7.0.2.tgz", + "integrity": "sha512-NKXYmMR/Hr1DevQegFB4MwfM5Vv0m4UIxKZTTYuD98lpTknaZlSRrDOG4X7wIXpGkfsYxZTghUN+Qq+T0YQI7w==", + "dev": true, + "license": "ISC", + "dependencies": { + "compare-func": "^2.0.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/conventional-commits-parser": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-5.0.0.tgz", + "integrity": "sha512-ZPMl0ZJbw74iS9LuX9YIAiW8pfM5p3yh2o/NbXHbkFuZzY5jvdi5jFycEOkmBW5H5I7nA+D6f3UcsCLP2vvSEA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-text-path": "^2.0.0", + "JSONStream": "^1.3.5", + "meow": "^12.0.1", + "split2": "^4.0.0" + }, + "bin": { + "conventional-commits-parser": "cli.mjs" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/core-js-compat": { + "version": "3.46.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.46.0.tgz", + "integrity": "sha512-p9hObIIEENxSV8xIu+V68JjSeARg6UVMG5mR+JEUguG3sI6MsiS1njz2jHmyJDvA+8jX/sytkBHup6kxhM9law==", + "dev": true, + "license": "MIT", + "dependencies": { + "browserslist": "^4.26.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/cosmiconfig": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", + "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", + "dev": true, + "license": "MIT", + "dependencies": { + "env-paths": "^2.2.1", + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/cosmiconfig-typescript-loader": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-6.2.0.tgz", + "integrity": "sha512-GEN39v7TgdxgIoNcdkRE3uiAzQt3UXLyHbRHD6YoL048XAeOomyxaP+Hh/+2C6C2wYjxJ2onhJcsQp+L4YEkVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "jiti": "^2.6.1" + }, + "engines": { + "node": ">=v18" + }, + "peerDependencies": { + "@types/node": "*", + "cosmiconfig": ">=9", + "typescript": ">=5" + } + }, + "node_modules/cosmiconfig/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/cosmiconfig/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/create-jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", + "integrity": "sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "prompts": "^2.0.1" + }, + "bin": { + "create-jest": "bin/create-jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/create-jest/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/create-jest/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/dargs": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/dargs/-/dargs-8.1.0.tgz", + "integrity": "sha512-wAV9QHOsNbwnWdNW2FYvE1P56wtgSbM+3SZcdGiWQILwVjACCXDCI3Ai8QlCjMDB8YK5zySiXZYBiwGmNY3lnw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/data-view-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", + "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", + "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/inspect-js" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", + "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/debounce": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz", + "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==", + "dev": true, + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/dedent": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.7.0.tgz", + "integrity": "sha512-HGFtf8yhuhGhqO07SV79tRp+br4MnbdjeVxotpn1QBl30pcLLCQjX5b2295ll0fv8RKDKsmWYrl05usHM9CewQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "babel-plugin-macros": "^3.1.0" + }, + "peerDependenciesMeta": { + "babel-plugin-macros": { + "optional": true + } + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/dependency-tree": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/dependency-tree/-/dependency-tree-11.2.0.tgz", + "integrity": "sha512-+C1H3mXhcvMCeu5i2Jpg9dc0N29TWTuT6vJD7mHLAfVmAbo9zW8NlkvQ1tYd3PDMab0IRQM0ccoyX68EZtx9xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "commander": "^12.1.0", + "filing-cabinet": "^5.0.3", + "precinct": "^12.2.0", + "typescript": "^5.8.3" + }, + "bin": { + "dependency-tree": "bin/cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/dependency-tree/node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/detective-amd": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/detective-amd/-/detective-amd-6.0.1.tgz", + "integrity": "sha512-TtyZ3OhwUoEEIhTFoc1C9IyJIud3y+xYkSRjmvCt65+ycQuc3VcBrPRTMWoO/AnuCyOB8T5gky+xf7Igxtjd3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "ast-module-types": "^6.0.1", + "escodegen": "^2.1.0", + "get-amd-module-type": "^6.0.1", + "node-source-walk": "^7.0.1" + }, + "bin": { + "detective-amd": "bin/cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/detective-cjs": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/detective-cjs/-/detective-cjs-6.0.1.tgz", + "integrity": "sha512-tLTQsWvd2WMcmn/60T2inEJNhJoi7a//PQ7DwRKEj1yEeiQs4mrONgsUtEJKnZmrGWBBmE0kJ1vqOG/NAxwaJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "ast-module-types": "^6.0.1", + "node-source-walk": "^7.0.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/detective-es6": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/detective-es6/-/detective-es6-5.0.1.tgz", + "integrity": "sha512-XusTPuewnSUdoxRSx8OOI6xIA/uld/wMQwYsouvFN2LAg7HgP06NF1lHRV3x6BZxyL2Kkoih4ewcq8hcbGtwew==", + "dev": true, + "license": "MIT", + "dependencies": { + "node-source-walk": "^7.0.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/detective-postcss": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/detective-postcss/-/detective-postcss-7.0.1.tgz", + "integrity": "sha512-bEOVpHU9picRZux5XnwGsmCN4+8oZo7vSW0O0/Enq/TO5R2pIAP2279NsszpJR7ocnQt4WXU0+nnh/0JuK4KHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-url": "^1.2.4", + "postcss-values-parser": "^6.0.2" + }, + "engines": { + "node": "^14.0.0 || >=16.0.0" + }, + "peerDependencies": { + "postcss": "^8.4.47" + } + }, + "node_modules/detective-sass": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/detective-sass/-/detective-sass-6.0.1.tgz", + "integrity": "sha512-jSGPO8QDy7K7pztUmGC6aiHkexBQT4GIH+mBAL9ZyBmnUIOFbkfZnO8wPRRJFP/QP83irObgsZHCoDHZ173tRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "gonzales-pe": "^4.3.0", + "node-source-walk": "^7.0.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/detective-scss": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/detective-scss/-/detective-scss-5.0.1.tgz", + "integrity": "sha512-MAyPYRgS6DCiS6n6AoSBJXLGVOydsr9huwXORUlJ37K3YLyiN0vYHpzs3AdJOgHobBfispokoqrEon9rbmKacg==", + "dev": true, + "license": "MIT", + "dependencies": { + "gonzales-pe": "^4.3.0", + "node-source-walk": "^7.0.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/detective-stylus": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/detective-stylus/-/detective-stylus-5.0.1.tgz", + "integrity": "sha512-Dgn0bUqdGbE3oZJ+WCKf8Dmu7VWLcmRJGc6RCzBgG31DLIyai9WAoEhYRgIHpt/BCRMrnXLbGWGPQuBUrnF0TA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/detective-typescript": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/detective-typescript/-/detective-typescript-14.0.0.tgz", + "integrity": "sha512-pgN43/80MmWVSEi5LUuiVvO/0a9ss5V7fwVfrJ4QzAQRd3cwqU1SfWGXJFcNKUqoD5cS+uIovhw5t/0rSeC5Mw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/typescript-estree": "^8.23.0", + "ast-module-types": "^6.0.1", + "node-source-walk": "^7.0.1" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "typescript": "^5.4.4" + } + }, + "node_modules/detective-vue2": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/detective-vue2/-/detective-vue2-2.2.0.tgz", + "integrity": "sha512-sVg/t6O2z1zna8a/UIV6xL5KUa2cMTQbdTIIvqNM0NIPswp52fe43Nwmbahzj3ww4D844u/vC2PYfiGLvD3zFA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@dependents/detective-less": "^5.0.1", + "@vue/compiler-sfc": "^3.5.13", + "detective-es6": "^5.0.1", + "detective-sass": "^6.0.1", + "detective-scss": "^5.0.1", + "detective-stylus": "^5.0.1", + "detective-typescript": "^14.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "typescript": "^5.4.4" + } + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/diff-sequences": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-obj": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/duplexer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", + "dev": true, + "license": "MIT" + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true, + "license": "MIT" + }, + "node_modules/electron-to-chromium": { + "version": "1.5.237", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.237.tgz", + "integrity": "sha512-icUt1NvfhGLar5lSWH3tHNzablaA5js3HVHacQimfP8ViEBOQv+L7DKEuHdbTZ0SKCO1ogTJTIL1Gwk9S6Qvcg==", + "dev": true, + "license": "ISC" + }, + "node_modules/emittery": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", + "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/enhanced-resolve": { + "version": "5.18.3", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.3.tgz", + "integrity": "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/envinfo": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.18.0.tgz", + "integrity": "sha512-02QGCLRW+Jb8PC270ic02lat+N57iBaWsvHjcJViqp6UVupRB+Vsg7brYPTqEFXvsdTql3KnSczv5ModZFpl8Q==", + "dev": true, + "license": "MIT", + "bin": { + "envinfo": "dist/cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/error-ex": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", + "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-abstract": { + "version": "1.24.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.0.tgz", + "integrity": "sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.2", + "arraybuffer.prototype.slice": "^1.0.4", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "data-view-buffer": "^1.0.2", + "data-view-byte-length": "^1.0.2", + "data-view-byte-offset": "^1.0.1", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-set-tostringtag": "^2.1.0", + "es-to-primitive": "^1.3.0", + "function.prototype.name": "^1.1.8", + "get-intrinsic": "^1.3.0", + "get-proto": "^1.0.1", + "get-symbol-description": "^1.1.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "internal-slot": "^1.1.0", + "is-array-buffer": "^3.0.5", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.2", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.2.1", + "is-set": "^2.0.3", + "is-shared-array-buffer": "^1.0.4", + "is-string": "^1.1.1", + "is-typed-array": "^1.1.15", + "is-weakref": "^1.1.1", + "math-intrinsics": "^1.1.0", + "object-inspect": "^1.13.4", + "object-keys": "^1.1.1", + "object.assign": "^4.1.7", + "own-keys": "^1.0.1", + "regexp.prototype.flags": "^1.5.4", + "safe-array-concat": "^1.1.3", + "safe-push-apply": "^1.0.0", + "safe-regex-test": "^1.1.0", + "set-proto": "^1.0.0", + "stop-iteration-iterator": "^1.1.0", + "string.prototype.trim": "^1.2.10", + "string.prototype.trimend": "^1.0.9", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.3", + "typed-array-byte-length": "^1.0.3", + "typed-array-byte-offset": "^1.0.4", + "typed-array-length": "^1.0.7", + "unbox-primitive": "^1.1.0", + "which-typed-array": "^1.1.19" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "dev": true, + "license": "MIT" + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz", + "integrity": "sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-to-primitive": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", + "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7", + "is-date-object": "^1.0.5", + "is-symbol": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/escodegen": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/eslint": { + "version": "9.37.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.37.0.tgz", + "integrity": "sha512-XyLmROnACWqSxiGYArdef1fItQd47weqB7iwtfr9JHwRrqIXZdcFMvvEcL9xHCmL0SNsOvF0c42lWyM1U5dgig==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.21.0", + "@eslint/config-helpers": "^0.4.0", + "@eslint/core": "^0.16.0", + "@eslint/eslintrc": "^3.3.1", + "@eslint/js": "9.37.0", + "@eslint/plugin-kit": "^0.4.0", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.4.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-config-prettier": { + "version": "10.1.8", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.1.8.tgz", + "integrity": "sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==", + "dev": true, + "license": "MIT", + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "funding": { + "url": "https://opencollective.com/eslint-config-prettier" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-module-utils": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.1.tgz", + "integrity": "sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.2.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.32.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.32.0.tgz", + "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rtsao/scc": "^1.1.0", + "array-includes": "^3.1.9", + "array.prototype.findlastindex": "^1.2.6", + "array.prototype.flat": "^1.3.3", + "array.prototype.flatmap": "^1.3.3", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.12.1", + "hasown": "^2.0.2", + "is-core-module": "^2.16.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.8", + "object.groupby": "^1.0.3", + "object.values": "^1.2.1", + "semver": "^6.3.1", + "string.prototype.trimend": "^1.0.9", + "tsconfig-paths": "^3.15.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" + } + }, + "node_modules/eslint-plugin-import/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/eslint-plugin-prettier": { + "version": "5.5.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.5.4.tgz", + "integrity": "sha512-swNtI95SToIz05YINMA6Ox5R057IMAmWZ26GqPxusAp1TZzj+IdY9tXNWWD3vkF/wEqydCONcwjTFpxybBqZsg==", + "dev": true, + "license": "MIT", + "dependencies": { + "prettier-linter-helpers": "^1.0.0", + "synckit": "^0.11.7" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint-plugin-prettier" + }, + "peerDependencies": { + "@types/eslint": ">=8.0.0", + "eslint": ">=8.0.0", + "eslint-config-prettier": ">= 7.0.0 <10.0.0 || >=10.1.0", + "prettier": ">=3.0.0" + }, + "peerDependenciesMeta": { + "@types/eslint": { + "optional": true + }, + "eslint-config-prettier": { + "optional": true + } + } + }, + "node_modules/eslint-scope": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", + "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/eslint/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/eslint/node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/eslint/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/eslint/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/eslint/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/espree": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.15.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree/node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true, + "license": "MIT" + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/expect": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/expect-utils": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-diff": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", + "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", + "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/fastest-levenshtein": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", + "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.9.1" + } + }, + "node_modules/fastq": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fb-watchman": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "bser": "2.1.1" + } + }, + "node_modules/fflate": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz", + "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==", + "dev": true, + "license": "MIT" + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/filing-cabinet": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/filing-cabinet/-/filing-cabinet-5.0.3.tgz", + "integrity": "sha512-PlPcMwVWg60NQkhvfoxZs4wEHjhlOO/y7OAm4sKM60o1Z9nttRY4mcdQxp/iZ+kg/Vv6Hw1OAaTbYVM9DA9pYg==", + "dev": true, + "license": "MIT", + "dependencies": { + "app-module-path": "^2.2.0", + "commander": "^12.1.0", + "enhanced-resolve": "^5.18.0", + "module-definition": "^6.0.1", + "module-lookup-amd": "^9.0.3", + "resolve": "^1.22.10", + "resolve-dependency-path": "^4.0.1", + "sass-lookup": "^6.1.0", + "stylus-lookup": "^6.1.0", + "tsconfig-paths": "^4.2.0", + "typescript": "^5.7.3" + }, + "bin": { + "filing-cabinet": "bin/cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/filing-cabinet/node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/filing-cabinet/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/filing-cabinet/node_modules/tsconfig-paths": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz", + "integrity": "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==", + "dev": true, + "license": "MIT", + "dependencies": { + "json5": "^2.2.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-7.0.0.tgz", + "integrity": "sha512-YyZM99iHrqLKjmt4LJDj58KI+fYyufRLBSYcqycxf//KpBk9FoewoGX0450m9nB44qrZnovzC2oeP5hUibxc/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^7.2.0", + "path-exists": "^5.0.0", + "unicorn-magic": "^0.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "license": "BSD-3-Clause", + "bin": { + "flat": "cli.js" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "dev": true, + "license": "ISC" + }, + "node_modules/for-each": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/foreground-child/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function.prototype.name": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", + "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "functions-have-names": "^1.2.3", + "hasown": "^2.0.2", + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/generator-function": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz", + "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-amd-module-type": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-amd-module-type/-/get-amd-module-type-6.0.1.tgz", + "integrity": "sha512-MtjsmYiCXcYDDrGqtNbeIYdAl85n+5mSv2r3FbzER/YV3ZILw4HNNIw34HuV5pyl0jzs6GFYU1VHVEefhgcNHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ast-module-types": "^6.0.1", + "node-source-walk": "^7.0.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-own-enumerable-property-symbols": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", + "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==", + "dev": true, + "license": "ISC" + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-symbol-description": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", + "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/git-raw-commits": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-4.0.0.tgz", + "integrity": "sha512-ICsMM1Wk8xSGMowkOmPrzo2Fgmfo4bMHLNX6ytHjajRJUqvHOw/TFapQ+QG75c3X/tTDDhOSRPGC52dDbNM8FQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "dargs": "^8.0.0", + "meow": "^12.0.1", + "split2": "^4.0.0" + }, + "bin": { + "git-raw-commits": "cli.mjs" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/global-directory": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/global-directory/-/global-directory-4.0.1.tgz", + "integrity": "sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ini": "4.1.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gonzales-pe": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/gonzales-pe/-/gonzales-pe-4.3.0.tgz", + "integrity": "sha512-otgSPpUmdWJ43VXyiNgEYE4luzHCL2pz4wQ0OnDluC6Eg4Ko3Vexy/SrSynglw/eR+OhkzmqFCZa/OFa/RgAOQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "gonzales": "bin/gonzales.js" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true, + "license": "MIT" + }, + "node_modules/gzip-size": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", + "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "duplexer": "^0.1.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/handlebars": { + "version": "4.7.8", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", + "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.2", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, + "node_modules/has-bigints": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", + "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", + "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true, + "license": "MIT" + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/husky": { + "version": "9.1.7", + "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.7.tgz", + "integrity": "sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==", + "dev": true, + "license": "MIT", + "bin": { + "husky": "bin.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/typicode" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-fresh/node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/import-local": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", + "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", + "dev": true, + "license": "MIT", + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-meta-resolve": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.2.0.tgz", + "integrity": "sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/ini": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.1.tgz", + "integrity": "sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/internal-slot": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", + "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/interpret": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", + "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", + "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-async-function": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", + "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "async-function": "^1.0.0", + "call-bound": "^1.0.3", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", + "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-bigints": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-boolean-object": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", + "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-view": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", + "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", + "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-finalizationregistry": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", + "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/is-generator-function": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz", + "integrity": "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.4", + "generator-function": "^2.0.0", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", + "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "license": "MIT", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-regex": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", + "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", + "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-string": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", + "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", + "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-symbols": "^1.1.0", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-text-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-2.0.0.tgz", + "integrity": "sha512-+oDTluR6WEjdXEJMnC2z6A4FRwFoYuvShVVEGsS7ewc0UTi2QtAKMDJuL4BDEVt+5T7MjFo12RP8ghOM75oKJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "text-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-url": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz", + "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-url-superb": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-url-superb/-/is-url-superb-4.0.0.tgz", + "integrity": "sha512-GI+WjezhPPcbM+tqE9LnmsY5qqjwHzTvjJ36wxYX5ujNXefSUJ/T17r5bqDV8yLhcgB59KTPNOc9O9cmHTPWsA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz", + "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", + "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true, + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-reports": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz", + "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jackspeak": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.1.1.tgz", + "integrity": "sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", + "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/core": "^29.7.0", + "@jest/types": "^29.6.3", + "import-local": "^3.0.2", + "jest-cli": "^29.7.0" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-changed-files": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.7.0.tgz", + "integrity": "sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==", + "dev": true, + "license": "MIT", + "dependencies": { + "execa": "^5.0.0", + "jest-util": "^29.7.0", + "p-limit": "^3.1.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-circus": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz", + "integrity": "sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^1.0.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^29.7.0", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "p-limit": "^3.1.0", + "pretty-format": "^29.7.0", + "pure-rand": "^6.0.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-circus/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-circus/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-cli": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz", + "integrity": "sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/core": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "create-jest": "^29.7.0", + "exit": "^0.1.2", + "import-local": "^3.0.2", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "yargs": "^17.3.1" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-cli/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-cli/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-config": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz", + "integrity": "sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/test-sequencer": "^29.7.0", + "@jest/types": "^29.6.3", + "babel-jest": "^29.7.0", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-circus": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@types/node": "*", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/jest-config/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-config/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-diff": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", + "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^29.6.3", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-diff/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-diff/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-docblock": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz", + "integrity": "sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "detect-newline": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-each": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.7.0.tgz", + "integrity": "sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "jest-util": "^29.7.0", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-each/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-each/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-environment-node": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", + "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-get-type": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", + "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-haste-map": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", + "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "micromatch": "^4.0.4", + "walker": "^1.0.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" + } + }, + "node_modules/jest-leak-detector": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz", + "integrity": "sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==", + "dev": true, + "license": "MIT", + "dependencies": { + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-matcher-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", + "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-matcher-utils/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-matcher-utils/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-message-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", + "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.6.3", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-message-util/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-message-util/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-mock": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", + "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-pnp-resolver": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true + } + } + }, + "node_modules/jest-regex-util": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", + "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz", + "integrity": "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "resolve": "^1.20.0", + "resolve.exports": "^2.0.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve-dependencies": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz", + "integrity": "sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==", + "dev": true, + "license": "MIT", + "dependencies": { + "jest-regex-util": "^29.6.3", + "jest-snapshot": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-resolve/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-runner": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz", + "integrity": "sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/environment": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "graceful-fs": "^4.2.9", + "jest-docblock": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-leak-detector": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-resolve": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-util": "^29.7.0", + "jest-watcher": "^29.7.0", + "jest-worker": "^29.7.0", + "p-limit": "^3.1.0", + "source-map-support": "0.5.13" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runner/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-runner/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-runtime": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz", + "integrity": "sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/globals": "^29.7.0", + "@jest/source-map": "^29.6.3", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runtime/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-runtime/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-snapshot": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz", + "integrity": "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.11.6", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-jsx": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/types": "^7.3.3", + "@jest/expect-utils": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^29.7.0", + "graceful-fs": "^4.2.9", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "natural-compare": "^1.4.0", + "pretty-format": "^29.7.0", + "semver": "^7.5.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-snapshot/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-snapshot/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-util/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-util/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-validate": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", + "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "leven": "^3.1.0", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-validate/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-validate/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-validate/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-watcher": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz", + "integrity": "sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "jest-util": "^29.7.0", + "string-length": "^4.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-watcher/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-watcher/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/jiti": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz", + "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", + "dev": true, + "engines": [ + "node >= 0.2.0" + ], + "license": "MIT" + }, + "node_modules/JSONStream": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "dev": true, + "license": "(MIT OR Apache-2.0)", + "dependencies": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + }, + "bin": { + "JSONStream": "bin.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true, + "license": "MIT" + }, + "node_modules/linkify-it": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "uc.micro": "^2.0.0" + } + }, + "node_modules/loader-runner": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.1.tgz", + "integrity": "sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.11.5" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/locate-path": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", + "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^6.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.kebabcase": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz", + "integrity": "sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.mergewith": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz", + "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.snakecase": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz", + "integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.startcase": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.startcase/-/lodash.startcase-4.4.0.tgz", + "integrity": "sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.upperfirst": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz", + "integrity": "sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg==", + "dev": true, + "license": "MIT" + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-symbols/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/log-symbols/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/lunr": { + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz", + "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==", + "dev": true, + "license": "MIT" + }, + "node_modules/madge": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/madge/-/madge-8.0.0.tgz", + "integrity": "sha512-9sSsi3TBPhmkTCIpVQF0SPiChj1L7Rq9kU2KDG1o6v2XH9cCw086MopjVCD+vuoL5v8S77DTbVopTO8OUiQpIw==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.2", + "commander": "^7.2.0", + "commondir": "^1.0.1", + "debug": "^4.3.4", + "dependency-tree": "^11.0.0", + "ora": "^5.4.1", + "pluralize": "^8.0.0", + "pretty-ms": "^7.0.1", + "rc": "^1.2.8", + "stream-to-array": "^2.3.0", + "ts-graphviz": "^2.1.2", + "walkdir": "^0.4.1" + }, + "bin": { + "madge": "bin/cli.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "individual", + "url": "https://www.paypal.me/pahen" + }, + "peerDependencies": { + "typescript": "^5.4.4" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/madge/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/madge/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/magic-string": { + "version": "0.30.19", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.19.tgz", + "integrity": "sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true, + "license": "ISC" + }, + "node_modules/makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "tmpl": "1.0.5" + } + }, + "node_modules/markdown-it": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", + "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1", + "entities": "^4.4.0", + "linkify-it": "^5.0.0", + "mdurl": "^2.0.0", + "punycode.js": "^2.3.1", + "uc.micro": "^2.1.0" + }, + "bin": { + "markdown-it": "bin/markdown-it.mjs" + } + }, + "node_modules/markdown-it/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/mdurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", + "dev": true, + "license": "MIT" + }, + "node_modules/meow": { + "version": "12.1.1", + "resolved": "https://registry.npmjs.org/meow/-/meow-12.1.1.tgz", + "integrity": "sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16.10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true, + "license": "MIT" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/meshoptimizer": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/meshoptimizer/-/meshoptimizer-0.18.1.tgz", + "integrity": "sha512-ZhoIoL7TNV4s5B6+rx5mC//fw8/POGyNxS/DZyCJeiZ12ScLfVwRE/GfsxwiTkMYYD5DmK2/JXnEVXqL4rF+Sw==", + "dev": true, + "license": "MIT" + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/module-definition": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/module-definition/-/module-definition-6.0.1.tgz", + "integrity": "sha512-FeVc50FTfVVQnolk/WQT8MX+2WVcDnTGiq6Wo+/+lJ2ET1bRVi3HG3YlJUfqagNMc/kUlFSoR96AJkxGpKz13g==", + "dev": true, + "license": "MIT", + "dependencies": { + "ast-module-types": "^6.0.1", + "node-source-walk": "^7.0.1" + }, + "bin": { + "module-definition": "bin/cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/module-lookup-amd": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/module-lookup-amd/-/module-lookup-amd-9.0.5.tgz", + "integrity": "sha512-Rs5FVpVcBYRHPLuhHOjgbRhosaQYLtEo3JIeDIbmNo7mSssi1CTzwMh8v36gAzpbzLGXI9wB/yHh+5+3fY1QVw==", + "dev": true, + "license": "MIT", + "dependencies": { + "commander": "^12.1.0", + "glob": "^7.2.3", + "requirejs": "^2.3.7", + "requirejs-config-file": "^4.0.0" + }, + "bin": { + "lookup-amd": "bin/cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/module-lookup-amd/node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/mrmime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", + "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-releases": { + "version": "2.0.23", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.23.tgz", + "integrity": "sha512-cCmFDMSm26S6tQSDpBCg/NR8NENrVPhAJSf+XbxBG4rPFaaonlEoE9wHQmun+cls499TQGSb7ZyPBRlzgKfpeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-source-walk": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/node-source-walk/-/node-source-walk-7.0.1.tgz", + "integrity": "sha512-3VW/8JpPqPvnJvseXowjZcirPisssnBuDikk6JIZ8jQzF7KJQX52iPFX4RYYxLycYH7IbMRSPUOga/esVjy5Yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.26.7" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.groupby": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", + "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.values": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz", + "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/opener": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", + "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", + "dev": true, + "license": "(WTFPL OR MIT)", + "bin": { + "opener": "bin/opener-bin.js" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/ora": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/ora/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/own-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", + "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.6", + "object-keys": "^1.1.1", + "safe-push-apply": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", + "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate/node_modules/p-limit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", + "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^1.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate/node_modules/yocto-queue": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.2.1.tgz", + "integrity": "sha512-AyeEbWOu/TAXdxlV9wmGcR0+yh2j3vYPGOECcIj2S7MkrLyC7ne+oye2BKTItt0ii2PHk4cDy+95+LshzbXnGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse-ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-2.1.0.tgz", + "integrity": "sha512-kHt7kzLoS9VBZfUsiKjv43mr91ea+U05EyKkEtqp7vNbHxmaVuEqN7XxeEVnGrMtYOAxGrDElSi96K7EgO1zCA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/path-exists": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", + "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "license": "MIT" + }, + "node_modules/path-scurry": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.0.tgz", + "integrity": "sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "11.2.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.2.tgz", + "integrity": "sha512-F9ODfyqML2coTIsQpSkRHnLSZMtkU8Q+mSfcaIyKwy58u+8k5nvAYeiNhsyMARvzNcXJ9QfWVrcPsC9e9rAxtg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pirates": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", + "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-dir/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/pluralize": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", + "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/postcss": { + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-values-parser": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-values-parser/-/postcss-values-parser-6.0.2.tgz", + "integrity": "sha512-YLJpK0N1brcNJrs9WatuJFtHaV9q5aAOj+S4DI5S7jgHlRfm0PIbDCAFRYMQD5SHq7Fy6xsDhyutgS0QOAs0qw==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "color-name": "^1.1.4", + "is-url-superb": "^4.0.0", + "quote-unquote": "^1.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "postcss": "^8.2.9" + } + }, + "node_modules/precinct": { + "version": "12.2.0", + "resolved": "https://registry.npmjs.org/precinct/-/precinct-12.2.0.tgz", + "integrity": "sha512-NFBMuwIfaJ4SocE9YXPU/n4AcNSoFMVFjP72nvl3cx69j/ke61/hPOWFREVxLkFhhEGnA8ZuVfTqJBa+PK3b5w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@dependents/detective-less": "^5.0.1", + "commander": "^12.1.0", + "detective-amd": "^6.0.1", + "detective-cjs": "^6.0.1", + "detective-es6": "^5.0.1", + "detective-postcss": "^7.0.1", + "detective-sass": "^6.0.1", + "detective-scss": "^5.0.1", + "detective-stylus": "^5.0.1", + "detective-typescript": "^14.0.0", + "detective-vue2": "^2.2.0", + "module-definition": "^6.0.1", + "node-source-walk": "^7.0.1", + "postcss": "^8.5.1", + "typescript": "^5.7.3" + }, + "bin": { + "precinct": "bin/cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/precinct/node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz", + "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-diff": "^1.1.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/pretty-ms": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-7.0.1.tgz", + "integrity": "sha512-973driJZvxiGOQ5ONsFhOF/DtzPMOMtgC11kCpUrPGMTgqp2q/1gwzCquocrN33is0VZ5GFHXZYMM9l6h67v2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "parse-ms": "^2.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/punycode.js": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", + "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/pure-rand": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz", + "integrity": "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ], + "license": "MIT" + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/quote-unquote": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/quote-unquote/-/quote-unquote-1.0.0.tgz", + "integrity": "sha512-twwRO/ilhlG/FIgYeKGFqyHhoEhqgnKVkcmqMKi2r524gz3ZbDTcyFt38E9xjJI2vT+KbRNHVbnJ/e0I25Azwg==", + "dev": true, + "license": "MIT" + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/rc/node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true, + "license": "ISC" + }, + "node_modules/rc/node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true, + "license": "MIT" + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/rechoir": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", + "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve": "^1.20.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", + "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.1", + "which-builtin-type": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", + "dev": true, + "license": "MIT" + }, + "node_modules/regenerate-unicode-properties": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.2.tgz", + "integrity": "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", + "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexpu-core": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.4.0.tgz", + "integrity": "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA==", + "dev": true, + "license": "MIT", + "dependencies": { + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.2.2", + "regjsgen": "^0.8.0", + "regjsparser": "^0.13.0", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.2.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/regjsparser": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.13.0.tgz", + "integrity": "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "jsesc": "~3.1.0" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/requirejs": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/requirejs/-/requirejs-2.3.7.tgz", + "integrity": "sha512-DouTG8T1WanGok6Qjg2SXuCMzszOo0eHeH9hDZ5Y4x8Je+9JB38HdTLT4/VA8OaUhBa0JPVHJ0pyBkM1z+pDsw==", + "dev": true, + "license": "MIT", + "bin": { + "r_js": "bin/r.js", + "r.js": "bin/r.js" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/requirejs-config-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/requirejs-config-file/-/requirejs-config-file-4.0.0.tgz", + "integrity": "sha512-jnIre8cbWOyvr8a5F2KuqBnY+SDA4NXr/hzEZJG79Mxm2WiFQz2dzhC8ibtPJS7zkmBEl1mxSwp5HhC1W4qpxw==", + "dev": true, + "license": "MIT", + "dependencies": { + "esprima": "^4.0.0", + "stringify-object": "^3.2.1" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/resolve": { + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-dependency-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/resolve-dependency-path/-/resolve-dependency-path-4.0.1.tgz", + "integrity": "sha512-YQftIIC4vzO9UMhO/sCgXukNyiwVRCVaxiWskCBy7Zpqkplm8kTAISZ8O1MoKW1ca6xzgLUBjZTcDgypXvXxiQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve.exports": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.3.tgz", + "integrity": "sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.0.1.tgz", + "integrity": "sha512-9dkvaxAsk/xNXSJzMgFqqMCuFgt2+KsOFek3TMLfo8NCPfWpBmqwyNn5Y+NX56QUYfCtsyhF3ayiboEoUmJk/A==", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^11.0.0", + "package-json-from-dist": "^1.0.0" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/glob": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.3.tgz", + "integrity": "sha512-2Nim7dha1KVkaiF4q6Dj+ngPPMdfvLJEOpZk/jKiUAkqKebpGAWQXAq9z1xu9HKu5lWfqw/FASuccEjyznjPaA==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.3.1", + "jackspeak": "^4.1.1", + "minimatch": "^10.0.3", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^2.0.0" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/minimatch": { + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.3.tgz", + "integrity": "sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==", + "dev": true, + "license": "ISC", + "dependencies": { + "@isaacs/brace-expansion": "^5.0.0" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-array-concat": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", + "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "has-symbols": "^1.1.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safe-push-apply": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", + "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-regex-test": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/sass-lookup": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/sass-lookup/-/sass-lookup-6.1.0.tgz", + "integrity": "sha512-Zx+lVyoWqXZxHuYWlTA17Z5sczJ6braNT2C7rmClw+c4E7r/n911Zwss3h1uHI9reR5AgHZyNHF7c2+VIp5AUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "commander": "^12.1.0", + "enhanced-resolve": "^5.18.0" + }, + "bin": { + "sass-lookup": "bin/cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/sass-lookup/node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/schema-utils": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.3.tgz", + "integrity": "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", + "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/sirv": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.4.tgz", + "integrity": "sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@polka/url": "^1.0.0-next.24", + "mrmime": "^2.0.0", + "totalist": "^3.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true, + "license": "MIT" + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 10.x" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/stop-iteration-iterator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", + "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "internal-slot": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/stream-to-array": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/stream-to-array/-/stream-to-array-2.3.0.tgz", + "integrity": "sha512-UsZtOYEn4tWU2RGLOXr/o/xjRBftZRlG3dEWoaHr8j4GuypJ3isitGbVyjQKAuMu+xbiop8q224TjiZWc4XTZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "^1.1.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", + "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-data-property": "^1.1.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-object-atoms": "^1.0.0", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", + "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/stringify-object": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", + "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "get-own-enumerable-property-symbols": "^3.0.0", + "is-obj": "^1.0.1", + "is-regexp": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/stringify-object/node_modules/is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/stylus-lookup": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/stylus-lookup/-/stylus-lookup-6.1.0.tgz", + "integrity": "sha512-5QSwgxAzXPMN+yugy61C60PhoANdItfdjSEZR8siFwz7yL9jTmV0UBKDCfn3K8GkGB4g0Y9py7vTCX8rFu4/pQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "commander": "^12.1.0" + }, + "bin": { + "stylus-lookup": "bin/cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/stylus-lookup/node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/synckit": { + "version": "0.11.11", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.11.tgz", + "integrity": "sha512-MeQTA1r0litLUf0Rp/iisCaL8761lKAZHaimlbGK4j0HysC4PLfqygQj9srcs0m2RdtDYnF8UuYyKpbjHYp7Jw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@pkgr/core": "^0.2.9" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/synckit" + } + }, + "node_modules/tapable": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz", + "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/terser": { + "version": "5.44.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.44.0.tgz", + "integrity": "sha512-nIVck8DK+GM/0Frwd+nIhZ84pR/BX7rmXMfYwyg+Sri5oGVE99/E3KvXqpC2xHFxyqXyGHTKBSioxxplrO4I4w==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.15.0", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.3.14", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.14.tgz", + "integrity": "sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.25", + "jest-worker": "^27.4.5", + "schema-utils": "^4.3.0", + "serialize-javascript": "^6.0.2", + "terser": "^5.31.1" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/terser-webpack-plugin/node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/terser-webpack-plugin/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/terser/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/terser/node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "license": "ISC", + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/test-exclude/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/test-exclude/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/text-extensions": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-2.4.0.tgz", + "integrity": "sha512-te/NtwBwfiNRLf9Ijqx3T0nlqZiQ2XrrtBvu+cLL8ZRrGkO0NHTug8MYFKyoSrv/sHTaSKfilUkizV6XhxMJ3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/three": { + "version": "0.177.0", + "resolved": "https://registry.npmjs.org/three/-/three-0.177.0.tgz", + "integrity": "sha512-EiXv5/qWAaGI+Vz2A+JfavwYCMdGjxVsrn3oBwllUoqYeaBO75J63ZfyaQKoiLrqNHoTlUc6PFgMXnS0kI45zg==", + "license": "MIT", + "peer": true + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyexec": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.1.tgz", + "integrity": "sha512-5uC6DDlmeqiOwCPmK9jMSdOuZTh8bU39Ys6yidB+UTt5hfZUPGAypSgFRiEp+jbi9qH40BLDvy85jIU88wKSqw==", + "dev": true, + "license": "MIT" + }, + "node_modules/tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/totalist": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", + "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/ts-api-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", + "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, + "node_modules/ts-graphviz": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/ts-graphviz/-/ts-graphviz-2.1.6.tgz", + "integrity": "sha512-XyLVuhBVvdJTJr2FJJV2L1pc4MwSjMhcunRVgDE9k4wbb2ee7ORYnPewxMWUav12vxyfUM686MSGsqnVRIInuw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ts-graphviz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/ts-graphviz" + } + ], + "license": "MIT", + "dependencies": { + "@ts-graphviz/adapter": "^2.0.6", + "@ts-graphviz/ast": "^2.0.7", + "@ts-graphviz/common": "^2.1.5", + "@ts-graphviz/core": "^2.0.7" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/ts-jest": { + "version": "29.4.5", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.4.5.tgz", + "integrity": "sha512-HO3GyiWn2qvTQA4kTgjDcXiMwYQt68a1Y8+JuLRVpdIzm+UOLSHgl/XqR4c6nzJkq5rOkjc02O2I7P7l/Yof0Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "bs-logger": "^0.2.6", + "fast-json-stable-stringify": "^2.1.0", + "handlebars": "^4.7.8", + "json5": "^2.2.3", + "lodash.memoize": "^4.1.2", + "make-error": "^1.3.6", + "semver": "^7.7.3", + "type-fest": "^4.41.0", + "yargs-parser": "^21.1.1" + }, + "bin": { + "ts-jest": "cli.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0" + }, + "peerDependencies": { + "@babel/core": ">=7.0.0-beta.0 <8", + "@jest/transform": "^29.0.0 || ^30.0.0", + "@jest/types": "^29.0.0 || ^30.0.0", + "babel-jest": "^29.0.0 || ^30.0.0", + "jest": "^29.0.0 || ^30.0.0", + "jest-util": "^29.0.0 || ^30.0.0", + "typescript": ">=4.3 <6" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "@jest/transform": { + "optional": true + }, + "@jest/types": { + "optional": true + }, + "babel-jest": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "jest-util": { + "optional": true + } + } + }, + "node_modules/ts-jest/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ts-jest/node_modules/type-fest": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ts-loader": { + "version": "9.5.4", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.5.4.tgz", + "integrity": "sha512-nCz0rEwunlTZiy6rXFByQU1kVVpCIgUpc/psFiKVrUwrizdnIbRFu8w7bxhUF0X613DYwT4XzrZHpVyMe758hQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "enhanced-resolve": "^5.0.0", + "micromatch": "^4.0.0", + "semver": "^7.3.4", + "source-map": "^0.7.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "typescript": "*", + "webpack": "^5.0.0" + } + }, + "node_modules/ts-loader/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/ts-loader/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/ts-loader/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ts-loader/node_modules/source-map": { + "version": "0.7.6", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", + "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">= 12" + } + }, + "node_modules/ts-node": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/tsconfig-paths": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tsconfig-paths/node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/tsconfig-paths/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", + "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", + "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.15", + "reflect.getprototypeof": "^1.0.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", + "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0", + "reflect.getprototypeof": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typedoc": { + "version": "0.28.14", + "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.28.14.tgz", + "integrity": "sha512-ftJYPvpVfQvFzpkoSfHLkJybdA/geDJ8BGQt/ZnkkhnBYoYW6lBgPQXu6vqLxO4X75dA55hX8Af847H5KXlEFA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@gerrit0/mini-shiki": "^3.12.0", + "lunr": "^2.3.9", + "markdown-it": "^14.1.0", + "minimatch": "^9.0.5", + "yaml": "^2.8.1" + }, + "bin": { + "typedoc": "bin/typedoc" + }, + "engines": { + "node": ">= 18", + "pnpm": ">= 10" + }, + "peerDependencies": { + "typescript": "5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x || 5.5.x || 5.6.x || 5.7.x || 5.8.x || 5.9.x" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/uc.micro": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", + "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", + "dev": true, + "license": "MIT" + }, + "node_modules/uglify-js": { + "version": "3.19.3", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", + "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", + "dev": true, + "license": "BSD-2-Clause", + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/unbox-primitive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", + "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-bigints": "^1.0.2", + "has-symbols": "^1.1.0", + "which-boxed-primitive": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", + "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.1.tgz", + "integrity": "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.2.0.tgz", + "integrity": "sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicorn-magic": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", + "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", + "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true, + "license": "MIT" + }, + "node_modules/v8-to-istanbul": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", + "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==", + "dev": true, + "license": "ISC", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^2.0.0" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/walkdir": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/walkdir/-/walkdir-0.4.1.tgz", + "integrity": "sha512-3eBwRyEln6E1MSzcxcVpQIhRG8Q1jLvEqRmCZqS3dsfXEDR/AhOF4d+jHg1qvDCpYaVRZjENPQyrVxAkQqxPgQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "makeerror": "1.0.12" + } + }, + "node_modules/watchpack": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.4.tgz", + "integrity": "sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "dev": true, + "license": "MIT", + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/webpack": { + "version": "5.102.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.102.1.tgz", + "integrity": "sha512-7h/weGm9d/ywQ6qzJ+Xy+r9n/3qgp/thalBbpOi5i223dPXKi04IBtqPN9nTd+jBc7QKfvDbaBnFipYp4sJAUQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/eslint-scope": "^3.7.7", + "@types/estree": "^1.0.8", + "@types/json-schema": "^7.0.15", + "@webassemblyjs/ast": "^1.14.1", + "@webassemblyjs/wasm-edit": "^1.14.1", + "@webassemblyjs/wasm-parser": "^1.14.1", + "acorn": "^8.15.0", + "acorn-import-phases": "^1.0.3", + "browserslist": "^4.26.3", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.17.3", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.11", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^4.3.3", + "tapable": "^2.3.0", + "terser-webpack-plugin": "^5.3.11", + "watchpack": "^2.4.4", + "webpack-sources": "^3.3.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-bundle-analyzer": { + "version": "4.10.2", + "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.10.2.tgz", + "integrity": "sha512-vJptkMm9pk5si4Bv922ZbKLV8UTT4zib4FPgXMhgzUny0bfDDkLXAVQs3ly3fS4/TN9ROFtb0NFrm04UXFE/Vw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@discoveryjs/json-ext": "0.5.7", + "acorn": "^8.0.4", + "acorn-walk": "^8.0.0", + "commander": "^7.2.0", + "debounce": "^1.2.1", + "escape-string-regexp": "^4.0.0", + "gzip-size": "^6.0.0", + "html-escaper": "^2.0.2", + "opener": "^1.5.2", + "picocolors": "^1.0.0", + "sirv": "^2.0.3", + "ws": "^7.3.1" + }, + "bin": { + "webpack-bundle-analyzer": "lib/bin/analyzer.js" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/webpack-cli": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-6.0.1.tgz", + "integrity": "sha512-MfwFQ6SfwinsUVi0rNJm7rHZ31GyTcpVE5pgVA3hwFRb7COD4TzjUUwhGWKfO50+xdc2MQPuEBBJoqIMGt3JDw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@discoveryjs/json-ext": "^0.6.1", + "@webpack-cli/configtest": "^3.0.1", + "@webpack-cli/info": "^3.0.1", + "@webpack-cli/serve": "^3.0.1", + "colorette": "^2.0.14", + "commander": "^12.1.0", + "cross-spawn": "^7.0.3", + "envinfo": "^7.14.0", + "fastest-levenshtein": "^1.0.12", + "import-local": "^3.0.2", + "interpret": "^3.1.1", + "rechoir": "^0.8.0", + "webpack-merge": "^6.0.1" + }, + "bin": { + "webpack-cli": "bin/cli.js" + }, + "engines": { + "node": ">=18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.82.0" + }, + "peerDependenciesMeta": { + "webpack-bundle-analyzer": { + "optional": true + }, + "webpack-dev-server": { + "optional": true + } + } + }, + "node_modules/webpack-cli/node_modules/@discoveryjs/json-ext": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.6.3.tgz", + "integrity": "sha512-4B4OijXeVNOPZlYA2oEwWOTkzyltLao+xbotHQeqN++Rv27Y6s818+n2Qkp8q+Fxhn0t/5lA5X1Mxktud8eayQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.17.0" + } + }, + "node_modules/webpack-cli/node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/webpack-merge": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-6.0.1.tgz", + "integrity": "sha512-hXXvrjtx2PLYx4qruKl+kyRSLc52V+cCvMxRjmKwoA+CBbbF5GfIBtR6kCvl0fYGqTUPKB+1ktVmTHqMOzgCBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "clone-deep": "^4.0.1", + "flat": "^5.0.2", + "wildcard": "^2.0.1" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/webpack-sources": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.3.tgz", + "integrity": "sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack/node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/webpack/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", + "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-bigint": "^1.1.0", + "is-boolean-object": "^1.2.1", + "is-number-object": "^1.1.1", + "is-string": "^1.1.1", + "is-symbol": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", + "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", + "is-async-function": "^2.0.0", + "is-date-object": "^1.1.0", + "is-finalizationregistry": "^1.1.0", + "is-generator-function": "^1.0.10", + "is-regex": "^1.2.1", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.1.0", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-collection": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.19", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", + "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/wildcard": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", + "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/write-file-atomic": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "dev": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/ws": { + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + }, + "node_modules/yaml": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.1.tgz", + "integrity": "sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==", + "dev": true, + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + } + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/webpack.config.js b/webpack.config.js new file mode 100644 index 0000000..1013308 --- /dev/null +++ b/webpack.config.js @@ -0,0 +1,63 @@ +import path from 'path'; +import TerserPlugin from 'terser-webpack-plugin'; +import { fileURLToPath } from 'url'; +import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); + +export default { + entry: './dist/index.js', + output: { + path: path.resolve(__dirname, 'dist'), + filename: 'three-utils.min.js', + module: true, + library: { + type: 'module', + }, + }, + experiments: { + outputModule: true, + }, + mode: 'production', + resolve: { + extensions: ['.ts', '.js'], + mainFields: ['module', 'main'] + }, + module: { + rules: [ + { + test: /\.ts$/, + use: 'ts-loader', + exclude: /node_modules/, + }, + ], + }, + optimization: { + usedExports: true, + minimize: true, + minimizer: [ + new TerserPlugin({ + terserOptions: { + compress: { + drop_console: true, + }, + format: { + comments: false, + }, + }, + }), + ], + }, + plugins: [ + new BundleAnalyzerPlugin({ + analyzerMode: 'json', + reportFilename: 'bundle-report.json', + openAnalyzer: false, + sourceType: 'module', + }), + ], + externals: { + three: 'THREE' + }, +}; \ No newline at end of file From 0b501e44a329e1b8df291bb86acffd0df15e84a4 Mon Sep 17 00:00:00 2001 From: Krisztian Somoracz Date: Wed, 15 Oct 2025 23:58:27 +0200 Subject: [PATCH 03/20] feat: add ESLint and Prettier configuration with code formatting - Add eslint.config.mjs with TypeScript and import rules - Configure Prettier with consistent formatting rules - Apply automatic code formatting to all source files - Set up import ordering and newline enforcement - Configure TypeScript-specific linting rules - Enable prettier integration with ESLint - Fix all formatting issues across the codebase --- .prettierrc | 6 + dist/assets/index.d.ts | 2 +- dist/assets/index.js | 2 +- dist/audio/index.d.ts | 2 +- dist/audio/index.js | 2 +- dist/bundle-report.json | 2 +- dist/callback-utils.d.ts.map | 2 +- dist/dispose-utils.d.ts.map | 2 +- dist/geom-utils.d.ts.map | 2 +- dist/index.d.ts | 14 +- dist/index.js | 14 +- dist/object-utils.d.ts.map | 2 +- dist/object-utils.js | 25 ++- dist/time-utils.js | 16 +- eslint.config.mjs | 49 +++++ src/assets/assets.ts | 8 +- src/assets/index.ts | 2 +- src/audio/audio.ts | 8 +- src/audio/index.ts | 2 +- src/callback-utils.ts | 101 +++++------ src/dispose-utils.ts | 48 ++--- src/geom-utils.ts | 86 ++++----- src/index.ts | 14 +- src/js/newkrok/three-utils/assets/assets.js | 8 +- src/js/newkrok/three-utils/assets/index.js | 2 +- src/js/newkrok/three-utils/assets/loaders.js | 6 +- src/js/newkrok/three-utils/audio/audio.js | 8 +- src/js/newkrok/three-utils/audio/index.js | 2 +- src/js/newkrok/three-utils/index.js | 14 +- src/js/newkrok/three-utils/object-utils.js | 14 +- src/js/newkrok/three-utils/time-utils.js | 16 +- src/object-utils.ts | 177 +++++++++++-------- src/time-utils.ts | 56 +++--- src/token.ts | 2 +- src/vector3-utils.ts | 10 +- webpack.config.js | 102 +++++------ 36 files changed, 459 insertions(+), 369 deletions(-) create mode 100644 .prettierrc create mode 100644 eslint.config.mjs diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..c8b9c24 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,6 @@ +{ + "semi": true, + "singleQuote": true, + "tabWidth": 2, + "trailingComma": "es5" +} \ No newline at end of file diff --git a/dist/assets/index.d.ts b/dist/assets/index.d.ts index 463b77a..90e7c99 100644 --- a/dist/assets/index.d.ts +++ b/dist/assets/index.d.ts @@ -1,2 +1,2 @@ -export * as AssetsUtils from "./assets.js"; +export * as AssetsUtils from './assets.js'; //# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/dist/assets/index.js b/dist/assets/index.js index 3a65885..a600e64 100644 --- a/dist/assets/index.js +++ b/dist/assets/index.js @@ -1 +1 @@ -export * as AssetsUtils from "./assets.js"; +export * as AssetsUtils from './assets.js'; diff --git a/dist/audio/index.d.ts b/dist/audio/index.d.ts index 1831824..839eb73 100644 --- a/dist/audio/index.d.ts +++ b/dist/audio/index.d.ts @@ -1,2 +1,2 @@ -export * as AudioUtils from "./audio.js"; +export * as AudioUtils from './audio.js'; //# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/dist/audio/index.js b/dist/audio/index.js index d36e670..944d0e4 100644 --- a/dist/audio/index.js +++ b/dist/audio/index.js @@ -1 +1 @@ -export * as AudioUtils from "./audio.js"; +export * as AudioUtils from './audio.js'; diff --git a/dist/bundle-report.json b/dist/bundle-report.json index 78909b7..6ba643d 100644 --- a/dist/bundle-report.json +++ b/dist/bundle-report.json @@ -1 +1 @@ -[{"label":"three-utils.min.js","isAsset":true,"statSize":8161,"groups":[{"label":"dist","path":"./dist","statSize":8161,"groups":[{"id":366,"label":"index.js + 7 modules (concatenated)","path":"./dist/index.js + 7 modules (concatenated)","statSize":8161,"parsedSize":0,"gzipSize":0,"concatenated":true,"groups":[{"label":"dist","path":"./dist/index.js + 7 modules (concatenated)/dist","statSize":8161,"groups":[{"id":null,"label":"index.js","path":"./dist/index.js + 7 modules (concatenated)/dist/index.js","statSize":342,"parsedSize":0,"gzipSize":0,"inaccurateSizes":true},{"id":null,"label":"callback-utils.js","path":"./dist/index.js + 7 modules (concatenated)/dist/callback-utils.js","statSize":1408,"parsedSize":0,"gzipSize":0,"inaccurateSizes":true},{"id":null,"label":"dispose-utils.js","path":"./dist/index.js + 7 modules (concatenated)/dist/dispose-utils.js","statSize":777,"parsedSize":0,"gzipSize":0,"inaccurateSizes":true},{"id":null,"label":"object-utils.js","path":"./dist/index.js + 7 modules (concatenated)/dist/object-utils.js","statSize":2808,"parsedSize":0,"gzipSize":0,"inaccurateSizes":true},{"id":null,"label":"time-utils.js","path":"./dist/index.js + 7 modules (concatenated)/dist/time-utils.js","statSize":1037,"parsedSize":0,"gzipSize":0,"inaccurateSizes":true},{"id":null,"label":"token.js","path":"./dist/index.js + 7 modules (concatenated)/dist/token.js","statSize":63,"parsedSize":0,"gzipSize":0,"inaccurateSizes":true},{"id":null,"label":"vector3-utils.js","path":"./dist/index.js + 7 modules (concatenated)/dist/vector3-utils.js","statSize":167,"parsedSize":0,"gzipSize":0,"inaccurateSizes":true},{"id":null,"label":"geom-utils.js","path":"./dist/index.js + 7 modules (concatenated)/dist/geom-utils.js","statSize":1559,"parsedSize":0,"gzipSize":0,"inaccurateSizes":true}],"parsedSize":0,"gzipSize":0,"inaccurateSizes":true}]}],"parsedSize":0,"gzipSize":0}],"isInitialByEntrypoint":{"main":true}}] \ No newline at end of file +[{"label":"three-utils.min.js","isAsset":true,"statSize":8242,"groups":[{"label":"dist","path":"./dist","statSize":8242,"groups":[{"id":366,"label":"index.js + 7 modules (concatenated)","path":"./dist/index.js + 7 modules (concatenated)","statSize":8242,"parsedSize":0,"gzipSize":0,"concatenated":true,"groups":[{"label":"dist","path":"./dist/index.js + 7 modules (concatenated)/dist","statSize":8242,"groups":[{"id":null,"label":"index.js","path":"./dist/index.js + 7 modules (concatenated)/dist/index.js","statSize":342,"parsedSize":0,"gzipSize":0,"inaccurateSizes":true},{"id":null,"label":"callback-utils.js","path":"./dist/index.js + 7 modules (concatenated)/dist/callback-utils.js","statSize":1408,"parsedSize":0,"gzipSize":0,"inaccurateSizes":true},{"id":null,"label":"dispose-utils.js","path":"./dist/index.js + 7 modules (concatenated)/dist/dispose-utils.js","statSize":777,"parsedSize":0,"gzipSize":0,"inaccurateSizes":true},{"id":null,"label":"object-utils.js","path":"./dist/index.js + 7 modules (concatenated)/dist/object-utils.js","statSize":2889,"parsedSize":0,"gzipSize":0,"inaccurateSizes":true},{"id":null,"label":"time-utils.js","path":"./dist/index.js + 7 modules (concatenated)/dist/time-utils.js","statSize":1037,"parsedSize":0,"gzipSize":0,"inaccurateSizes":true},{"id":null,"label":"token.js","path":"./dist/index.js + 7 modules (concatenated)/dist/token.js","statSize":63,"parsedSize":0,"gzipSize":0,"inaccurateSizes":true},{"id":null,"label":"vector3-utils.js","path":"./dist/index.js + 7 modules (concatenated)/dist/vector3-utils.js","statSize":167,"parsedSize":0,"gzipSize":0,"inaccurateSizes":true},{"id":null,"label":"geom-utils.js","path":"./dist/index.js + 7 modules (concatenated)/dist/geom-utils.js","statSize":1559,"parsedSize":0,"gzipSize":0,"inaccurateSizes":true}],"parsedSize":0,"gzipSize":0,"inaccurateSizes":true}]}],"parsedSize":0,"gzipSize":0}],"isInitialByEntrypoint":{"main":true}}] \ No newline at end of file diff --git a/dist/callback-utils.d.ts.map b/dist/callback-utils.d.ts.map index f3d7a36..e9182ba 100644 --- a/dist/callback-utils.d.ts.map +++ b/dist/callback-utils.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"callback-utils.d.ts","sourceRoot":"","sources":["../src/callback-utils.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,UAAU;;;;;;;;CAQb,CAAC;AAOX,UAAU,qBAAqB;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,CAAC,KAAK,CAAC,EAAE,GAAG,KAAK,IAAI,CAAC;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,GAAG,CAAC;IACpB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC5B;AAID,eAAO,MAAM,eAAe,GAAI,sEAO7B,qBAAqB,KAAG,IAgC1B,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAAI,IAAI,MAAM,KAAG,OAA8B,CAAC;AAEjF,eAAO,MAAM,uBAAuB,QAAO,IAE1C,CAAC"} \ No newline at end of file +{"version":3,"file":"callback-utils.d.ts","sourceRoot":"","sources":["../src/callback-utils.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,UAAU;;;;;;;;CAQb,CAAC;AAOX,UAAU,qBAAqB;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,CAAC,KAAK,CAAC,EAAE,GAAG,KAAK,IAAI,CAAC;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,GAAG,CAAC;IACpB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAID,eAAO,MAAM,eAAe,GAAI,sEAO7B,qBAAqB,KAAG,IAgC1B,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAAI,IAAI,MAAM,KAAG,OAC7B,CAAC;AAEtB,eAAO,MAAM,uBAAuB,QAAO,IAE1C,CAAC"} \ No newline at end of file diff --git a/dist/dispose-utils.d.ts.map b/dist/dispose-utils.d.ts.map index 268ad7a..c4eb0c7 100644 --- a/dist/dispose-utils.d.ts.map +++ b/dist/dispose-utils.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"dispose-utils.d.ts","sourceRoot":"","sources":["../src/dispose-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,eAAO,MAAM,gBAAgB,GACzB,UAAU,KAAK,CAAC,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,KACjD,IASF,CAAC;AAEF,eAAO,MAAM,WAAW,GAAI,WAAW,KAAK,CAAC,IAAI,KAAG,IAiBnD,CAAC"} \ No newline at end of file +{"version":3,"file":"dispose-utils.d.ts","sourceRoot":"","sources":["../src/dispose-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,eAAO,MAAM,gBAAgB,GAC3B,UAAU,KAAK,CAAC,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,KAC/C,IASF,CAAC;AAEF,eAAO,MAAM,WAAW,GAAI,WAAW,KAAK,CAAC,IAAI,KAAG,IAiBnD,CAAC"} \ No newline at end of file diff --git a/dist/geom-utils.d.ts.map b/dist/geom-utils.d.ts.map index 8dc7ee1..1fb18c2 100644 --- a/dist/geom-utils.d.ts.map +++ b/dist/geom-utils.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"geom-utils.d.ts","sourceRoot":"","sources":["../src/geom-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,eAAO,MAAM,IAAI,GACb,QAAQ,KAAK,CAAC,OAAO,EACrB,QAAQ,KAAK,CAAC,OAAO,EACrB,QAAQ,KAAK,CAAC,OAAO,KACtB,MAE8C,CAAC;AAElD,eAAO,MAAM,kBAAkB,GAC3B,OAAO,KAAK,CAAC,OAAO,EACpB,gBAAgB,KAAK,CAAC,OAAO,EAC7B,gBAAgB,KAAK,CAAC,OAAO,EAC7B,gBAAgB,KAAK,CAAC,OAAO,KAC9B,OAMF,CAAC;AAEF,eAAO,MAAM,aAAa,GACtB,OAAO,KAAK,CAAC,OAAO,EACpB,gBAAgB,KAAK,CAAC,OAAO,EAC7B,gBAAgB,KAAK,CAAC,OAAO,EAC7B,gBAAgB,KAAK,CAAC,OAAO,KAC9B,MA2BF,CAAC"} \ No newline at end of file +{"version":3,"file":"geom-utils.d.ts","sourceRoot":"","sources":["../src/geom-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,eAAO,MAAM,IAAI,GACf,QAAQ,KAAK,CAAC,OAAO,EACrB,QAAQ,KAAK,CAAC,OAAO,EACrB,QAAQ,KAAK,CAAC,OAAO,KACpB,MAE4C,CAAC;AAEhD,eAAO,MAAM,kBAAkB,GAC7B,OAAO,KAAK,CAAC,OAAO,EACpB,gBAAgB,KAAK,CAAC,OAAO,EAC7B,gBAAgB,KAAK,CAAC,OAAO,EAC7B,gBAAgB,KAAK,CAAC,OAAO,KAC5B,OAMF,CAAC;AAEF,eAAO,MAAM,aAAa,GACxB,OAAO,KAAK,CAAC,OAAO,EACpB,gBAAgB,KAAK,CAAC,OAAO,EAC7B,gBAAgB,KAAK,CAAC,OAAO,EAC7B,gBAAgB,KAAK,CAAC,OAAO,KAC5B,MA2BF,CAAC"} \ No newline at end of file diff --git a/dist/index.d.ts b/dist/index.d.ts index 600496a..606e4ed 100644 --- a/dist/index.d.ts +++ b/dist/index.d.ts @@ -1,8 +1,8 @@ -export * as CallbackUtils from "./callback-utils.js"; -export * as DisposeUtils from "./dispose-utils.js"; -export * as ObjectUtils from "./object-utils.js"; -export * as TimeUtils from "./time-utils.js"; -export * as TokenUtils from "./token.js"; -export * as Vector3Utils from "./vector3-utils.js"; -export * as GeomUtils from "./geom-utils.js"; +export * as CallbackUtils from './callback-utils.js'; +export * as DisposeUtils from './dispose-utils.js'; +export * as ObjectUtils from './object-utils.js'; +export * as TimeUtils from './time-utils.js'; +export * as TokenUtils from './token.js'; +export * as Vector3Utils from './vector3-utils.js'; +export * as GeomUtils from './geom-utils.js'; //# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/dist/index.js b/dist/index.js index 10abe79..25589c9 100644 --- a/dist/index.js +++ b/dist/index.js @@ -1,7 +1,7 @@ -export * as CallbackUtils from "./callback-utils.js"; -export * as DisposeUtils from "./dispose-utils.js"; -export * as ObjectUtils from "./object-utils.js"; -export * as TimeUtils from "./time-utils.js"; -export * as TokenUtils from "./token.js"; -export * as Vector3Utils from "./vector3-utils.js"; -export * as GeomUtils from "./geom-utils.js"; +export * as CallbackUtils from './callback-utils.js'; +export * as DisposeUtils from './dispose-utils.js'; +export * as ObjectUtils from './object-utils.js'; +export * as TimeUtils from './time-utils.js'; +export * as TokenUtils from './token.js'; +export * as Vector3Utils from './vector3-utils.js'; +export * as GeomUtils from './geom-utils.js'; diff --git a/dist/object-utils.d.ts.map b/dist/object-utils.d.ts.map index fbb1c30..5af2da7 100644 --- a/dist/object-utils.d.ts.map +++ b/dist/object-utils.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"object-utils.d.ts","sourceRoot":"","sources":["../src/object-utils.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,qBAAqB,GAAG;IAChC,iBAAiB,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAClC,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAChC,CAAC;AAEF,eAAO,MAAM,WAAW,GAAI,CAAC,EAAE,CAAC,EAC5B,SAAS,CAAC,EACV,SAAS,CAAC,EACV,SAAQ,qBAA4E,KACrF,CAuBF,CAAC;AAEF,eAAO,MAAM,SAAS,GAAI,CAAC,EAAE,CAAC,EAC1B,SAAS,CAAC,EACV,SAAS,CAAC,EACV,SAAQ,qBAA4E,KACrF,CAAC,GAAG,CAyBN,CAAC;AAEF,eAAO,MAAM,aAAa,GAAI,CAAC,EAAE,CAAC,EAC9B,SAAS,CAAC,EACV,SAAS,CAAC,EACV,SAAQ,qBAAiD,KAC1D,OAAO,CAAC,CAAC,GAAG,CAAC,CAoBf,CAAC"} \ No newline at end of file +{"version":3,"file":"object-utils.d.ts","sourceRoot":"","sources":["../src/object-utils.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,qBAAqB,GAAG;IAClC,iBAAiB,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAClC,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B,CAAC;AAEF,eAAO,MAAM,WAAW,GAAI,CAAC,EAAE,CAAC,EAC9B,SAAS,CAAC,EACV,SAAS,CAAC,EACV,SAAQ,qBAGP,KACA,CA2BF,CAAC;AAEF,eAAO,MAAM,SAAS,GAAI,CAAC,EAAE,CAAC,EAC5B,SAAS,CAAC,EACV,SAAS,CAAC,EACV,SAAQ,qBAGP,KACA,CAAC,GAAG,CAgCN,CAAC;AAEF,eAAO,MAAM,aAAa,GAAI,CAAC,EAAE,CAAC,EAChC,SAAS,CAAC,EACV,SAAS,CAAC,EACV,SAAQ,qBAAiD,KACxD,OAAO,CAAC,CAAC,GAAG,CAAC,CA0Bf,CAAC"} \ No newline at end of file diff --git a/dist/object-utils.js b/dist/object-utils.js index 473900e..1c999f9 100644 --- a/dist/object-utils.js +++ b/dist/object-utils.js @@ -1,8 +1,11 @@ -export const patchObject = (objectA, objectB, config = { skippedProperties: [], applyToFirstObject: false }) => { +export const patchObject = (objectA, objectB, config = { + skippedProperties: [], + applyToFirstObject: false, +}) => { const result = {}; Object.keys(objectA).forEach((key) => { if (!config.skippedProperties || !config.skippedProperties.includes(key)) { - if (typeof objectA[key] === "object" && + if (typeof objectA[key] === 'object' && objectA[key] && objectB[key] && !Array.isArray(objectA[key])) { @@ -22,11 +25,17 @@ export const patchObject = (objectA, objectB, config = { skippedProperties: [], }); return result; }; -export const deepMerge = (objectA, objectB, config = { skippedProperties: [], applyToFirstObject: false }) => { +export const deepMerge = (objectA, objectB, config = { + skippedProperties: [], + applyToFirstObject: false, +}) => { const result = {}; - Array.from(new Set([...Object.keys((objectA || {})), ...Object.keys((objectB || {}))])).forEach((key) => { + Array.from(new Set([ + ...Object.keys((objectA || {})), + ...Object.keys((objectB || {})), + ])).forEach((key) => { if (!config.skippedProperties || !config.skippedProperties.includes(key)) { - if (typeof objectA?.[key] === "object" && + if (typeof objectA?.[key] === 'object' && objectA?.[key] && objectB?.[key] && !Array.isArray(objectA[key])) { @@ -50,7 +59,7 @@ export const getObjectDiff = (objectA, objectB, config = { skippedProperties: [] const result = {}; Object.keys(objectA).forEach((key) => { if (!config.skippedProperties || !config.skippedProperties.includes(key)) { - if (typeof objectA[key] === "object" && + if (typeof objectA[key] === 'object' && objectA[key] && objectB[key] && !Array.isArray(objectA[key])) { @@ -59,7 +68,9 @@ export const getObjectDiff = (objectA, objectB, config = { skippedProperties: [] result[key] = objectDiff; } else { - const mergedValue = objectB[key] === 0 ? 0 : objectB[key] || objectA[key]; + const mergedValue = objectB[key] === 0 + ? 0 + : objectB[key] || objectA[key]; if (mergedValue !== objectA[key]) result[key] = mergedValue; } diff --git a/dist/time-utils.js b/dist/time-utils.js index 9ad9552..5d675d9 100644 --- a/dist/time-utils.js +++ b/dist/time-utils.js @@ -1,15 +1,15 @@ export const TimePattern = { - HH_MM_SS: "HH:MM:SS", - MM_SS: "MM:SS", - MM_SS_MS: "MM:SS.MS", + HH_MM_SS: 'HH:MM:SS', + MM_SS: 'MM:SS', + MM_SS_MS: 'MM:SS.MS', }; const patterns = [ - { pattern: "HH", routine: ({ hours }) => String(hours).padStart(2, "0") }, - { pattern: "MM", routine: ({ minutes }) => String(minutes).padStart(2, "0") }, - { pattern: "SS", routine: ({ seconds }) => String(seconds).padStart(2, "0") }, + { pattern: 'HH', routine: ({ hours }) => String(hours).padStart(2, '0') }, + { pattern: 'MM', routine: ({ minutes }) => String(minutes).padStart(2, '0') }, + { pattern: 'SS', routine: ({ seconds }) => String(seconds).padStart(2, '0') }, { - pattern: "MS", - routine: ({ milliseconds }) => String(milliseconds).padStart(3, "0"), + pattern: 'MS', + routine: ({ milliseconds }) => String(milliseconds).padStart(3, '0'), }, ]; export const formatTime = (timeInMS, pattern) => { diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 0000000..eb2f958 --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,49 @@ +import typescriptPlugin from '@typescript-eslint/eslint-plugin'; +import typescriptParser from '@typescript-eslint/parser'; +import importPlugin from 'eslint-plugin-import'; +import prettierPlugin from 'eslint-plugin-prettier'; + +export default [ + { + files: ['**/*.ts'], + languageOptions: { + parser: typescriptParser, + }, + plugins: { + '@typescript-eslint': typescriptPlugin, + import: importPlugin, + prettier: prettierPlugin, + }, + rules: { + // General ESLint rules + 'no-console': 'warn', // Warn on console usage + 'no-debugger': 'error', // Disallow debugger + 'eqeqeq': ['error', 'always'], // Enforce strict equality + + // TypeScript-specific rules + '@typescript-eslint/no-explicit-any': 'warn', // Warn against using `any` type + '@typescript-eslint/no-empty-function': 'off', // Allow empty functions + + // Import plugin rules + 'import/order': [ + 'error', + { + groups: ['builtin', 'external', 'internal', 'parent', 'sibling', 'index', 'object', 'type'], + alphabetize: { order: 'asc', caseInsensitive: true }, + }, + ], + // Temporary disabled + 'import/no-unresolved': 'off', // Ensure imports can be resolved + 'import/newline-after-import': 'error', // Enforce newline after import statements + 'prettier/prettier': ['error', { + endOfLine: 'lf' // Use LF line endings consistently + }], // Ensure code is formatted according to Prettier rules + }, + }, + { + files: ['**/*.test.ts', '**/test/**/*.ts'], + rules: { + '@typescript-eslint/no-explicit-any': 'off', // Disable `any` type rule for tests + }, + }, +]; \ No newline at end of file diff --git a/src/assets/assets.ts b/src/assets/assets.ts index 6ad4e34..e2b75a6 100644 --- a/src/assets/assets.ts +++ b/src/assets/assets.ts @@ -1,9 +1,9 @@ // Basic assets utilities - simplified version export const registerTexture = (id: string, texture: any): void => { - // Implementation will be added with full assets system + // Implementation will be added with full assets system }; export const getTexture = (id: string): any => { - // Implementation will be added with full assets system - return null; -}; \ No newline at end of file + // Implementation will be added with full assets system + return null; +}; diff --git a/src/assets/index.ts b/src/assets/index.ts index f3faaad..a600e64 100644 --- a/src/assets/index.ts +++ b/src/assets/index.ts @@ -1 +1 @@ -export * as AssetsUtils from "./assets.js"; \ No newline at end of file +export * as AssetsUtils from './assets.js'; diff --git a/src/audio/audio.ts b/src/audio/audio.ts index 003c266..9ff7622 100644 --- a/src/audio/audio.ts +++ b/src/audio/audio.ts @@ -1,9 +1,9 @@ // Basic audio utilities - simplified version export const registerAudioBuffer = (id: string, audioBuffer: any): void => { - // Implementation will be added with full audio system + // Implementation will be added with full audio system }; export const getAudioBuffer = (id: string): any => { - // Implementation will be added with full audio system - return null; -}; \ No newline at end of file + // Implementation will be added with full audio system + return null; +}; diff --git a/src/audio/index.ts b/src/audio/index.ts index e235aca..944d0e4 100644 --- a/src/audio/index.ts +++ b/src/audio/index.ts @@ -1 +1 @@ -export * as AudioUtils from "./audio.js"; \ No newline at end of file +export * as AudioUtils from './audio.js'; diff --git a/src/callback-utils.ts b/src/callback-utils.ts index 02bae22..d39559e 100644 --- a/src/callback-utils.ts +++ b/src/callback-utils.ts @@ -1,72 +1,73 @@ export const CallLimits = { - NO_LIMIT: -1, - CALL_1_PER_SECONDS: 1000, - CALL_15_PER_SECONDS: 1000 / 15, - CALL_30_PER_SECONDS: 1000 / 30, - CALL_45_PER_SECONDS: 1000 / 45, - CALL_60_PER_SECONDS: 1000 / 60, - CALL_120_PER_SECONDS: 1000 / 120, + NO_LIMIT: -1, + CALL_1_PER_SECONDS: 1000, + CALL_15_PER_SECONDS: 1000 / 15, + CALL_30_PER_SECONDS: 1000 / 30, + CALL_45_PER_SECONDS: 1000 / 45, + CALL_60_PER_SECONDS: 1000 / 60, + CALL_120_PER_SECONDS: 1000 / 120, } as const; interface CallData { - lastUpdate: number; - callCount: number; + lastUpdate: number; + callCount: number; } interface CallWithReducerParams { - id: string; - callback: (param?: any) => void; - callLimit: number; - elapsed: number; - callbackParam?: any; - forceCallCount?: boolean; + id: string; + callback: (param?: any) => void; + callLimit: number; + elapsed: number; + callbackParam?: any; + forceCallCount?: boolean; } let callData: Record = {}; export const callWithReducer = ({ - id, - callback, - callLimit, - elapsed, - callbackParam, - forceCallCount = false, + id, + callback, + callLimit, + elapsed, + callbackParam, + forceCallCount = false, }: CallWithReducerParams): void => { - if (!elapsed) return; - if (!callData[id]) callData[id] = { lastUpdate: -1, callCount: 0 }; + if (!elapsed) return; + if (!callData[id]) callData[id] = { lastUpdate: -1, callCount: 0 }; - const call = () => { - if (callbackParam) callback(callbackParam); - else callback(); - }; + const call = () => { + if (callbackParam) callback(callbackParam); + else callback(); + }; - if (callLimit === CallLimits.NO_LIMIT) { - call(); - return; - } + if (callLimit === CallLimits.NO_LIMIT) { + call(); + return; + } - if (forceCallCount) { - const expectedCallCount = Math.floor(elapsed / (callLimit * 1000)); - while ( - callData[id].lastUpdate === -1 || - expectedCallCount > callData[id].callCount - ) { - call(); - callData[id].lastUpdate += callLimit; - callData[id].callCount++; - } - callData[id].lastUpdate = elapsed; - } else if ( - callData[id].lastUpdate === -1 || - elapsed - callData[id].lastUpdate >= callLimit + if (forceCallCount) { + const expectedCallCount = Math.floor(elapsed / (callLimit * 1000)); + while ( + callData[id].lastUpdate === -1 || + expectedCallCount > callData[id].callCount ) { - call(); - callData[id].lastUpdate = elapsed; + call(); + callData[id].lastUpdate += callLimit; + callData[id].callCount++; } + callData[id].lastUpdate = elapsed; + } else if ( + callData[id].lastUpdate === -1 || + elapsed - callData[id].lastUpdate >= callLimit + ) { + call(); + callData[id].lastUpdate = elapsed; + } }; -export const clearCallReducerData = (id: string): boolean => delete callData[id]; +export const clearCallReducerData = (id: string): boolean => + delete callData[id]; export const clearAllCallReducerData = (): void => { - callData = {}; -}; \ No newline at end of file + callData = {}; +}; diff --git a/src/dispose-utils.ts b/src/dispose-utils.ts index 535a4ef..0a255c0 100644 --- a/src/dispose-utils.ts +++ b/src/dispose-utils.ts @@ -1,33 +1,33 @@ import * as THREE from 'three'; export const disposeMaterials = ( - material: THREE.Material | Array + material: THREE.Material | Array ): void => { - if ((material as THREE.Material).isMaterial) { - const mat = material as THREE.Material; - (mat as any).map?.dispose(); - (mat as any).map = null; - mat.dispose(); - } else { - (material as Array).forEach(disposeMaterials); - } + if ((material as THREE.Material).isMaterial) { + const mat = material as THREE.Material; + (mat as any).map?.dispose(); + (mat as any).map = null; + mat.dispose(); + } else { + (material as Array).forEach(disposeMaterials); + } }; export const deepDispose = (container: THREE.Mesh): void => { - const { isMesh, material, geometry } = container; - if (isMesh) { - if (material) { - disposeMaterials(material); - (container as any).material = null; - } + const { isMesh, material, geometry } = container; + if (isMesh) { + if (material) { + disposeMaterials(material); + (container as any).material = null; + } - if (geometry) { - geometry.dispose(); - (container as any).geometry = null; - } - container.parent?.remove(container); - } else if ((container as any).children) { - (container as any).children.forEach(deepDispose); - container.parent?.remove(container); + if (geometry) { + geometry.dispose(); + (container as any).geometry = null; } -}; \ No newline at end of file + container.parent?.remove(container); + } else if ((container as any).children) { + (container as any).children.forEach(deepDispose); + container.parent?.remove(container); + } +}; diff --git a/src/geom-utils.ts b/src/geom-utils.ts index d251252..1d80fea 100644 --- a/src/geom-utils.ts +++ b/src/geom-utils.ts @@ -1,56 +1,56 @@ import * as THREE from 'three'; export const sign = ( - point1: THREE.Vector3, - point2: THREE.Vector3, - point3: THREE.Vector3 + point1: THREE.Vector3, + point2: THREE.Vector3, + point3: THREE.Vector3 ): number => - (point1.x - point3.x) * (point2.z - point3.z) - - (point2.x - point3.x) * (point1.z - point3.z); + (point1.x - point3.x) * (point2.z - point3.z) - + (point2.x - point3.x) * (point1.z - point3.z); export const isPointInATriangle = ( - point: THREE.Vector3, - trianglePointA: THREE.Vector3, - trianglePointB: THREE.Vector3, - trianglePointC: THREE.Vector3 + point: THREE.Vector3, + trianglePointA: THREE.Vector3, + trianglePointB: THREE.Vector3, + trianglePointC: THREE.Vector3 ): boolean => { - const d1 = sign(point, trianglePointA, trianglePointB); - const d2 = sign(point, trianglePointB, trianglePointC); - const d3 = sign(point, trianglePointC, trianglePointA); + const d1 = sign(point, trianglePointA, trianglePointB); + const d2 = sign(point, trianglePointB, trianglePointC); + const d3 = sign(point, trianglePointC, trianglePointA); - return !((d1 < 0 || d2 < 0 || d3 < 0) && (d1 > 0 || d2 > 0 || d3 > 0)); + return !((d1 < 0 || d2 < 0 || d3 < 0) && (d1 > 0 || d2 > 0 || d3 > 0)); }; export const yFromTriangle = ( - point: THREE.Vector3, - trianglePointA: THREE.Vector3, - trianglePointB: THREE.Vector3, - trianglePointC: THREE.Vector3 + point: THREE.Vector3, + trianglePointA: THREE.Vector3, + trianglePointB: THREE.Vector3, + trianglePointC: THREE.Vector3 ): number => { - const calc1 = - (trianglePointB.x - trianglePointA.x) * - (trianglePointC.y - trianglePointA.y) - - (trianglePointC.x - trianglePointA.x) * - (trianglePointB.y - trianglePointA.y); - const calc2 = - (trianglePointB.x - trianglePointA.x) * - (trianglePointC.z - trianglePointA.z) - - (trianglePointC.x - trianglePointA.x) * - (trianglePointB.z - trianglePointA.z); - const calc3 = - (trianglePointB.z - trianglePointA.z) * - (trianglePointC.y - trianglePointA.y) - - (trianglePointC.z - trianglePointA.z) * - (trianglePointB.y - trianglePointA.y); - const calc4 = - (trianglePointB.x - trianglePointA.x) * - (trianglePointC.z - trianglePointA.z) - - (trianglePointC.x - trianglePointA.x) * - (trianglePointB.z - trianglePointA.z); + const calc1 = + (trianglePointB.x - trianglePointA.x) * + (trianglePointC.y - trianglePointA.y) - + (trianglePointC.x - trianglePointA.x) * + (trianglePointB.y - trianglePointA.y); + const calc2 = + (trianglePointB.x - trianglePointA.x) * + (trianglePointC.z - trianglePointA.z) - + (trianglePointC.x - trianglePointA.x) * + (trianglePointB.z - trianglePointA.z); + const calc3 = + (trianglePointB.z - trianglePointA.z) * + (trianglePointC.y - trianglePointA.y) - + (trianglePointC.z - trianglePointA.z) * + (trianglePointB.y - trianglePointA.y); + const calc4 = + (trianglePointB.x - trianglePointA.x) * + (trianglePointC.z - trianglePointA.z) - + (trianglePointC.x - trianglePointA.x) * + (trianglePointB.z - trianglePointA.z); - return ( - trianglePointA.y + - (calc1 / calc2) * (point.z - trianglePointA.z) - - (calc3 / calc4) * (point.x - trianglePointA.x) - ); -}; \ No newline at end of file + return ( + trianglePointA.y + + (calc1 / calc2) * (point.z - trianglePointA.z) - + (calc3 / calc4) * (point.x - trianglePointA.x) + ); +}; diff --git a/src/index.ts b/src/index.ts index 05b379d..25589c9 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,7 +1,7 @@ -export * as CallbackUtils from "./callback-utils.js"; -export * as DisposeUtils from "./dispose-utils.js"; -export * as ObjectUtils from "./object-utils.js"; -export * as TimeUtils from "./time-utils.js"; -export * as TokenUtils from "./token.js"; -export * as Vector3Utils from "./vector3-utils.js"; -export * as GeomUtils from "./geom-utils.js"; \ No newline at end of file +export * as CallbackUtils from './callback-utils.js'; +export * as DisposeUtils from './dispose-utils.js'; +export * as ObjectUtils from './object-utils.js'; +export * as TimeUtils from './time-utils.js'; +export * as TokenUtils from './token.js'; +export * as Vector3Utils from './vector3-utils.js'; +export * as GeomUtils from './geom-utils.js'; diff --git a/src/js/newkrok/three-utils/assets/assets.js b/src/js/newkrok/three-utils/assets/assets.js index 1acf20d..e5667ef 100644 --- a/src/js/newkrok/three-utils/assets/assets.js +++ b/src/js/newkrok/three-utils/assets/assets.js @@ -1,14 +1,14 @@ -import * as THREE from "three"; +import * as THREE from 'three'; import { loadAudio, loadFBXModels, loadGLTFModels, loadTextures, -} from "./loaders.js"; +} from './loaders.js'; -import { clone } from "three/examples/jsm/utils/SkeletonUtils.js"; -import { deepDispose } from "../dispose-utils.js"; +import { clone } from 'three/examples/jsm/utils/SkeletonUtils.js'; +import { deepDispose } from '../dispose-utils.js'; const _fbxModels = {}; export const registerFBXModel = ({ id, fbxModel }) => diff --git a/src/js/newkrok/three-utils/assets/index.js b/src/js/newkrok/three-utils/assets/index.js index 3a65885..a600e64 100644 --- a/src/js/newkrok/three-utils/assets/index.js +++ b/src/js/newkrok/three-utils/assets/index.js @@ -1 +1 @@ -export * as AssetsUtils from "./assets.js"; +export * as AssetsUtils from './assets.js'; diff --git a/src/js/newkrok/three-utils/assets/loaders.js b/src/js/newkrok/three-utils/assets/loaders.js index 5667cf1..87ae024 100644 --- a/src/js/newkrok/three-utils/assets/loaders.js +++ b/src/js/newkrok/three-utils/assets/loaders.js @@ -1,7 +1,7 @@ -import * as THREE from "three"; +import * as THREE from 'three'; -import { FBXLoader } from "three/examples/jsm/loaders/FBXLoader.js"; -import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js"; +import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader.js'; +import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'; const gltfLoader = new GLTFLoader(); diff --git a/src/js/newkrok/three-utils/audio/audio.js b/src/js/newkrok/three-utils/audio/audio.js index b9c28ff..799bdc7 100644 --- a/src/js/newkrok/three-utils/audio/audio.js +++ b/src/js/newkrok/three-utils/audio/audio.js @@ -1,7 +1,7 @@ -import * as THREE from "three"; +import * as THREE from 'three'; -import { PositionalAudioHelper } from "three/examples/jsm/helpers/PositionalAudioHelper"; -import { getAudioBuffer } from "../assets/assets.js"; +import { PositionalAudioHelper } from 'three/examples/jsm/helpers/PositionalAudioHelper'; +import { getAudioBuffer } from '../assets/assets.js'; const defaultConfig = { loop: false, volume: 1, isMusic: false }; let audioConfig = {}; @@ -80,7 +80,7 @@ export const stopAudio = (cacheId) => { export const getAudioCache = (cacheId) => audioCache[cacheId] || { audio: null, - audioId: "", + audioId: '', container: null, lastPlayedTime: 0, }; diff --git a/src/js/newkrok/three-utils/audio/index.js b/src/js/newkrok/three-utils/audio/index.js index 68ab165..944d0e4 100644 --- a/src/js/newkrok/three-utils/audio/index.js +++ b/src/js/newkrok/three-utils/audio/index.js @@ -1 +1 @@ -export * as AudioUtils from './audio.js'; \ No newline at end of file +export * as AudioUtils from './audio.js'; diff --git a/src/js/newkrok/three-utils/index.js b/src/js/newkrok/three-utils/index.js index 10abe79..25589c9 100644 --- a/src/js/newkrok/three-utils/index.js +++ b/src/js/newkrok/three-utils/index.js @@ -1,7 +1,7 @@ -export * as CallbackUtils from "./callback-utils.js"; -export * as DisposeUtils from "./dispose-utils.js"; -export * as ObjectUtils from "./object-utils.js"; -export * as TimeUtils from "./time-utils.js"; -export * as TokenUtils from "./token.js"; -export * as Vector3Utils from "./vector3-utils.js"; -export * as GeomUtils from "./geom-utils.js"; +export * as CallbackUtils from './callback-utils.js'; +export * as DisposeUtils from './dispose-utils.js'; +export * as ObjectUtils from './object-utils.js'; +export * as TimeUtils from './time-utils.js'; +export * as TokenUtils from './token.js'; +export * as Vector3Utils from './vector3-utils.js'; +export * as GeomUtils from './geom-utils.js'; diff --git a/src/js/newkrok/three-utils/object-utils.js b/src/js/newkrok/three-utils/object-utils.js index 06cc966..c4d70a5 100644 --- a/src/js/newkrok/three-utils/object-utils.js +++ b/src/js/newkrok/three-utils/object-utils.js @@ -7,7 +7,7 @@ export const patchObject = ( Object.keys(objectA).forEach((key) => { if (!config.skippedProperties || !config.skippedProperties.includes(key)) { if ( - typeof objectA[key] === "object" && + typeof objectA[key] === 'object' && objectA[key] && objectB[key] && !Array.isArray(objectA[key]) @@ -18,8 +18,8 @@ export const patchObject = ( objectB[key] === 0 ? 0 : objectB[key] === false - ? false - : objectB[key] || objectA[key]; + ? false + : objectB[key] || objectA[key]; if (config.applyToFirstObject) objectA[key] = result[key]; } } @@ -38,7 +38,7 @@ export const deepMerge = ( ).forEach((key) => { if (!config.skippedProperties || !config.skippedProperties.includes(key)) { if ( - typeof objectA[key] === "object" && + typeof objectA[key] === 'object' && objectA[key] && objectB[key] && !Array.isArray(objectA[key]) @@ -49,8 +49,8 @@ export const deepMerge = ( objectB[key] === 0 ? 0 : objectB[key] === false - ? false - : objectB[key] || objectA[key]; + ? false + : objectB[key] || objectA[key]; if (config.applyToFirstObject) objectA[key] = result[key]; } } @@ -67,7 +67,7 @@ const getObjectDiff = ( Object.keys(objectA).forEach((key) => { if (!config.skippedProperties || !config.skippedProperties.includes(key)) { if ( - typeof objectA[key] === "object" && + typeof objectA[key] === 'object' && objectA[key] && objectB[key] && !Array.isArray(objectA[key]) diff --git a/src/js/newkrok/three-utils/time-utils.js b/src/js/newkrok/three-utils/time-utils.js index e0754c4..f3ccf9f 100644 --- a/src/js/newkrok/three-utils/time-utils.js +++ b/src/js/newkrok/three-utils/time-utils.js @@ -1,16 +1,16 @@ export const TimePattern = { - HH_MM_SS: "HH:MM:SS", - MM_SS: "MM:SS", - MM_SS_MS: "MM:SS.MS", + HH_MM_SS: 'HH:MM:SS', + MM_SS: 'MM:SS', + MM_SS_MS: 'MM:SS.MS', }; const patterns = [ - { pattern: "HH", routine: ({ hours }) => String(hours).padStart(2, "0") }, - { pattern: "MM", routine: ({ minutes }) => String(minutes).padStart(2, "0") }, - { pattern: "SS", routine: ({ seconds }) => String(seconds).padStart(2, "0") }, + { pattern: 'HH', routine: ({ hours }) => String(hours).padStart(2, '0') }, + { pattern: 'MM', routine: ({ minutes }) => String(minutes).padStart(2, '0') }, + { pattern: 'SS', routine: ({ seconds }) => String(seconds).padStart(2, '0') }, { - pattern: "MS", - routine: ({ milliseconds }) => String(milliseconds).padStart(3, "0"), + pattern: 'MS', + routine: ({ milliseconds }) => String(milliseconds).padStart(3, '0'), }, ]; diff --git a/src/object-utils.ts b/src/object-utils.ts index 48d0f4e..418fbb7 100644 --- a/src/object-utils.ts +++ b/src/object-utils.ts @@ -1,90 +1,113 @@ export type ObjectOperationConfig = { - skippedProperties?: Array; - applyToFirstObject?: boolean; + skippedProperties?: Array; + applyToFirstObject?: boolean; }; export const patchObject = ( - objectA: T, - objectB: V, - config: ObjectOperationConfig = { skippedProperties: [], applyToFirstObject: false } + objectA: T, + objectB: V, + config: ObjectOperationConfig = { + skippedProperties: [], + applyToFirstObject: false, + } ): T => { - const result = {} as any; - Object.keys(objectA as any).forEach((key) => { - if (!config.skippedProperties || !config.skippedProperties.includes(key)) { - if ( - typeof (objectA as any)[key] === "object" && - (objectA as any)[key] && - (objectB as any)[key] && - !Array.isArray((objectA as any)[key]) - ) { - result[key] = patchObject((objectA as any)[key], (objectB as any)[key], config); - } else { - result[key] = - (objectB as any)[key] === 0 - ? 0 - : (objectB as any)[key] === false - ? false - : (objectB as any)[key] || (objectA as any)[key]; - if (config.applyToFirstObject) (objectA as any)[key] = result[key]; - } - } - }); - return result; + const result = {} as any; + Object.keys(objectA as any).forEach((key) => { + if (!config.skippedProperties || !config.skippedProperties.includes(key)) { + if ( + typeof (objectA as any)[key] === 'object' && + (objectA as any)[key] && + (objectB as any)[key] && + !Array.isArray((objectA as any)[key]) + ) { + result[key] = patchObject( + (objectA as any)[key], + (objectB as any)[key], + config + ); + } else { + result[key] = + (objectB as any)[key] === 0 + ? 0 + : (objectB as any)[key] === false + ? false + : (objectB as any)[key] || (objectA as any)[key]; + if (config.applyToFirstObject) (objectA as any)[key] = result[key]; + } + } + }); + return result; }; export const deepMerge = ( - objectA: T, - objectB: V, - config: ObjectOperationConfig = { skippedProperties: [], applyToFirstObject: false } + objectA: T, + objectB: V, + config: ObjectOperationConfig = { + skippedProperties: [], + applyToFirstObject: false, + } ): T | V => { - const result = {} as any; - Array.from( - new Set([...Object.keys((objectA || {}) as any), ...Object.keys((objectB || {}) as any)]) - ).forEach((key) => { - if (!config.skippedProperties || !config.skippedProperties.includes(key)) { - if ( - typeof (objectA as any)?.[key] === "object" && - (objectA as any)?.[key] && - (objectB as any)?.[key] && - !Array.isArray((objectA as any)[key]) - ) { - result[key] = deepMerge((objectA as any)[key], (objectB as any)[key], config); - } else { - result[key] = - (objectB as any)?.[key] === 0 - ? 0 - : (objectB as any)?.[key] === false - ? false - : (objectB as any)?.[key] || (objectA as any)?.[key]; - if (config.applyToFirstObject) (objectA as any)[key] = result[key]; - } - } - }); - return result; + const result = {} as any; + Array.from( + new Set([ + ...Object.keys((objectA || {}) as any), + ...Object.keys((objectB || {}) as any), + ]) + ).forEach((key) => { + if (!config.skippedProperties || !config.skippedProperties.includes(key)) { + if ( + typeof (objectA as any)?.[key] === 'object' && + (objectA as any)?.[key] && + (objectB as any)?.[key] && + !Array.isArray((objectA as any)[key]) + ) { + result[key] = deepMerge( + (objectA as any)[key], + (objectB as any)[key], + config + ); + } else { + result[key] = + (objectB as any)?.[key] === 0 + ? 0 + : (objectB as any)?.[key] === false + ? false + : (objectB as any)?.[key] || (objectA as any)?.[key]; + if (config.applyToFirstObject) (objectA as any)[key] = result[key]; + } + } + }); + return result; }; export const getObjectDiff = ( - objectA: T, - objectB: V, - config: ObjectOperationConfig = { skippedProperties: [] } + objectA: T, + objectB: V, + config: ObjectOperationConfig = { skippedProperties: [] } ): Partial => { - const result = {} as any; - Object.keys(objectA as any).forEach((key) => { - if (!config.skippedProperties || !config.skippedProperties.includes(key)) { - if ( - typeof (objectA as any)[key] === "object" && - (objectA as any)[key] && - (objectB as any)[key] && - !Array.isArray((objectA as any)[key]) - ) { - const objectDiff = getObjectDiff((objectA as any)[key], (objectB as any)[key], config); - if (Object.keys(objectDiff).length > 0) result[key] = objectDiff; - } else { - const mergedValue = - (objectB as any)[key] === 0 ? 0 : (objectB as any)[key] || (objectA as any)[key]; - if (mergedValue !== (objectA as any)[key]) result[key] = mergedValue; - } - } - }); - return result; -}; \ No newline at end of file + const result = {} as any; + Object.keys(objectA as any).forEach((key) => { + if (!config.skippedProperties || !config.skippedProperties.includes(key)) { + if ( + typeof (objectA as any)[key] === 'object' && + (objectA as any)[key] && + (objectB as any)[key] && + !Array.isArray((objectA as any)[key]) + ) { + const objectDiff = getObjectDiff( + (objectA as any)[key], + (objectB as any)[key], + config + ); + if (Object.keys(objectDiff).length > 0) result[key] = objectDiff; + } else { + const mergedValue = + (objectB as any)[key] === 0 + ? 0 + : (objectB as any)[key] || (objectA as any)[key]; + if (mergedValue !== (objectA as any)[key]) result[key] = mergedValue; + } + } + }); + return result; +}; diff --git a/src/time-utils.ts b/src/time-utils.ts index a9213f3..d754757 100644 --- a/src/time-utils.ts +++ b/src/time-utils.ts @@ -1,43 +1,43 @@ export const TimePattern = { - HH_MM_SS: "HH:MM:SS", - MM_SS: "MM:SS", - MM_SS_MS: "MM:SS.MS", + HH_MM_SS: 'HH:MM:SS', + MM_SS: 'MM:SS', + MM_SS_MS: 'MM:SS.MS', } as const; interface TimeDetails { - hours: number; - minutes: number; - seconds: number; - milliseconds: number; + hours: number; + minutes: number; + seconds: number; + milliseconds: number; } interface PatternRule { - pattern: string; - routine: (timeDetails: TimeDetails) => string; + pattern: string; + routine: (timeDetails: TimeDetails) => string; } const patterns: PatternRule[] = [ - { pattern: "HH", routine: ({ hours }) => String(hours).padStart(2, "0") }, - { pattern: "MM", routine: ({ minutes }) => String(minutes).padStart(2, "0") }, - { pattern: "SS", routine: ({ seconds }) => String(seconds).padStart(2, "0") }, - { - pattern: "MS", - routine: ({ milliseconds }) => String(milliseconds).padStart(3, "0"), - }, + { pattern: 'HH', routine: ({ hours }) => String(hours).padStart(2, '0') }, + { pattern: 'MM', routine: ({ minutes }) => String(minutes).padStart(2, '0') }, + { pattern: 'SS', routine: ({ seconds }) => String(seconds).padStart(2, '0') }, + { + pattern: 'MS', + routine: ({ milliseconds }) => String(milliseconds).padStart(3, '0'), + }, ]; export const formatTime = (timeInMS: number, pattern: string): string => { - const milliseconds = Math.floor(timeInMS % 1000); - const seconds = Math.floor((timeInMS / 1000) % 60); - const minutes = Math.floor(Math.floor(timeInMS / 1000 / 60) % 60); - const hours = Math.floor((Math.floor(timeInMS / 1000 / 60) / 60) % 24); - const timeDetails: TimeDetails = { hours, minutes, seconds, milliseconds }; + const milliseconds = Math.floor(timeInMS % 1000); + const seconds = Math.floor((timeInMS / 1000) % 60); + const minutes = Math.floor(Math.floor(timeInMS / 1000 / 60) % 60); + const hours = Math.floor((Math.floor(timeInMS / 1000 / 60) / 60) % 24); + const timeDetails: TimeDetails = { hours, minutes, seconds, milliseconds }; - let result = pattern; - patterns.forEach( - ({ pattern: currentPattern, routine }) => - (result = result.replace(currentPattern, routine(timeDetails))) - ); + let result = pattern; + patterns.forEach( + ({ pattern: currentPattern, routine }) => + (result = result.replace(currentPattern, routine(timeDetails))) + ); - return result; -}; \ No newline at end of file + return result; +}; diff --git a/src/token.ts b/src/token.ts index 94f2335..bc95f7b 100644 --- a/src/token.ts +++ b/src/token.ts @@ -1,2 +1,2 @@ let uniqueId = 0; -export const getUniqueId = (): number => uniqueId++; \ No newline at end of file +export const getUniqueId = (): number => uniqueId++; diff --git a/src/vector3-utils.ts b/src/vector3-utils.ts index a1bace9..b0c0230 100644 --- a/src/vector3-utils.ts +++ b/src/vector3-utils.ts @@ -1,9 +1,9 @@ import * as THREE from 'three'; export const absVector3 = (vector: THREE.Vector3): THREE.Vector3 => { - vector.x = Math.abs(vector.x); - vector.y = Math.abs(vector.y); - vector.z = Math.abs(vector.z); + vector.x = Math.abs(vector.x); + vector.y = Math.abs(vector.y); + vector.z = Math.abs(vector.z); - return vector; -}; \ No newline at end of file + return vector; +}; diff --git a/webpack.config.js b/webpack.config.js index 1013308..04d4bbb 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -7,57 +7,57 @@ const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); export default { - entry: './dist/index.js', - output: { - path: path.resolve(__dirname, 'dist'), - filename: 'three-utils.min.js', - module: true, - library: { - type: 'module', - }, - }, - experiments: { - outputModule: true, - }, - mode: 'production', - resolve: { - extensions: ['.ts', '.js'], - mainFields: ['module', 'main'] - }, - module: { - rules: [ - { - test: /\.ts$/, - use: 'ts-loader', - exclude: /node_modules/, - }, - ], - }, - optimization: { - usedExports: true, - minimize: true, - minimizer: [ - new TerserPlugin({ - terserOptions: { - compress: { - drop_console: true, - }, - format: { - comments: false, - }, + entry: './dist/index.js', + output: { + path: path.resolve(__dirname, 'dist'), + filename: 'three-utils.min.js', + module: true, + library: { + type: 'module', }, - }), + }, + experiments: { + outputModule: true, + }, + mode: 'production', + resolve: { + extensions: ['.ts', '.js'], + mainFields: ['module', 'main'] + }, + module: { + rules: [ + { + test: /\.ts$/, + use: 'ts-loader', + exclude: /node_modules/, + }, + ], + }, + optimization: { + usedExports: true, + minimize: true, + minimizer: [ + new TerserPlugin({ + terserOptions: { + compress: { + drop_console: true, + }, + format: { + comments: false, + }, + }, + }), + ], + }, + plugins: [ + new BundleAnalyzerPlugin({ + analyzerMode: 'json', + reportFilename: 'bundle-report.json', + openAnalyzer: false, + sourceType: 'module', + }), ], - }, - plugins: [ - new BundleAnalyzerPlugin({ - analyzerMode: 'json', - reportFilename: 'bundle-report.json', - openAnalyzer: false, - sourceType: 'module', - }), - ], - externals: { - three: 'THREE' - }, + externals: { + three: 'THREE' + }, }; \ No newline at end of file From 44a72b36228d4e8b1d681c699b635ebd049f34dc Mon Sep 17 00:00:00 2001 From: Krisztian Somoracz Date: Thu, 16 Oct 2025 00:01:02 +0200 Subject: [PATCH 04/20] feat: add Jest testing framework with comprehensive test setup - Add jest.config.js with TypeScript and ESM support - Configure Babel for Jest with TypeScript preset - Create test infrastructure in src/__tests__ directory - Add unit tests for TokenUtils with incremental ID validation - Add comprehensive TimeUtils tests with various time patterns - Achieve 100% test coverage on tested modules - Configure coverage reporting with text and lcov formats - Enable ES module transformation for testing --- .prettierrc | 8 +- babel.config.json | 3 + coverage/lcov-report/base.css | 224 +++++++++++++++++++++ coverage/lcov-report/block-navigation.js | 87 ++++++++ coverage/lcov-report/favicon.png | Bin 0 -> 445 bytes coverage/lcov-report/index.html | 131 ++++++++++++ coverage/lcov-report/prettify.css | 1 + coverage/lcov-report/prettify.js | 2 + coverage/lcov-report/sort-arrow-sprite.png | Bin 0 -> 138 bytes coverage/lcov-report/sorter.js | 210 +++++++++++++++++++ coverage/lcov-report/time-utils.ts.html | 214 ++++++++++++++++++++ coverage/lcov-report/token.ts.html | 91 +++++++++ coverage/lcov.info | 50 +++++ eslint.config.mjs | 74 +++---- jest.config.js | 17 ++ src/__tests__/time-utils.test.ts | 34 ++++ src/__tests__/token.test.ts | 28 +++ 17 files changed, 1133 insertions(+), 41 deletions(-) create mode 100644 babel.config.json create mode 100644 coverage/lcov-report/base.css create mode 100644 coverage/lcov-report/block-navigation.js create mode 100644 coverage/lcov-report/favicon.png create mode 100644 coverage/lcov-report/index.html create mode 100644 coverage/lcov-report/prettify.css create mode 100644 coverage/lcov-report/prettify.js create mode 100644 coverage/lcov-report/sort-arrow-sprite.png create mode 100644 coverage/lcov-report/sorter.js create mode 100644 coverage/lcov-report/time-utils.ts.html create mode 100644 coverage/lcov-report/token.ts.html create mode 100644 coverage/lcov.info create mode 100644 jest.config.js create mode 100644 src/__tests__/time-utils.test.ts create mode 100644 src/__tests__/token.test.ts diff --git a/.prettierrc b/.prettierrc index c8b9c24..0205ecf 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1,6 +1,6 @@ { - "semi": true, - "singleQuote": true, - "tabWidth": 2, - "trailingComma": "es5" + "semi": true, + "singleQuote": true, + "tabWidth": 2, + "trailingComma": "es5" } \ No newline at end of file diff --git a/babel.config.json b/babel.config.json new file mode 100644 index 0000000..937768f --- /dev/null +++ b/babel.config.json @@ -0,0 +1,3 @@ +{ + "presets": ["@babel/preset-env", "@babel/preset-typescript"] +} \ No newline at end of file diff --git a/coverage/lcov-report/base.css b/coverage/lcov-report/base.css new file mode 100644 index 0000000..f418035 --- /dev/null +++ b/coverage/lcov-report/base.css @@ -0,0 +1,224 @@ +body, html { + margin:0; padding: 0; + height: 100%; +} +body { + font-family: Helvetica Neue, Helvetica, Arial; + font-size: 14px; + color:#333; +} +.small { font-size: 12px; } +*, *:after, *:before { + -webkit-box-sizing:border-box; + -moz-box-sizing:border-box; + box-sizing:border-box; + } +h1 { font-size: 20px; margin: 0;} +h2 { font-size: 14px; } +pre { + font: 12px/1.4 Consolas, "Liberation Mono", Menlo, Courier, monospace; + margin: 0; + padding: 0; + -moz-tab-size: 2; + -o-tab-size: 2; + tab-size: 2; +} +a { color:#0074D9; text-decoration:none; } +a:hover { text-decoration:underline; } +.strong { font-weight: bold; } +.space-top1 { padding: 10px 0 0 0; } +.pad2y { padding: 20px 0; } +.pad1y { padding: 10px 0; } +.pad2x { padding: 0 20px; } +.pad2 { padding: 20px; } +.pad1 { padding: 10px; } +.space-left2 { padding-left:55px; } +.space-right2 { padding-right:20px; } +.center { text-align:center; } +.clearfix { display:block; } +.clearfix:after { + content:''; + display:block; + height:0; + clear:both; + visibility:hidden; + } +.fl { float: left; } +@media only screen and (max-width:640px) { + .col3 { width:100%; max-width:100%; } + .hide-mobile { display:none!important; } +} + +.quiet { + color: #7f7f7f; + color: rgba(0,0,0,0.5); +} +.quiet a { opacity: 0.7; } + +.fraction { + font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; + font-size: 10px; + color: #555; + background: #E8E8E8; + padding: 4px 5px; + border-radius: 3px; + vertical-align: middle; +} + +div.path a:link, div.path a:visited { color: #333; } +table.coverage { + border-collapse: collapse; + margin: 10px 0 0 0; + padding: 0; +} + +table.coverage td { + margin: 0; + padding: 0; + vertical-align: top; +} +table.coverage td.line-count { + text-align: right; + padding: 0 5px 0 20px; +} +table.coverage td.line-coverage { + text-align: right; + padding-right: 10px; + min-width:20px; +} + +table.coverage td span.cline-any { + display: inline-block; + padding: 0 5px; + width: 100%; +} +.missing-if-branch { + display: inline-block; + margin-right: 5px; + border-radius: 3px; + position: relative; + padding: 0 4px; + background: #333; + color: yellow; +} + +.skip-if-branch { + display: none; + margin-right: 10px; + position: relative; + padding: 0 4px; + background: #ccc; + color: white; +} +.missing-if-branch .typ, .skip-if-branch .typ { + color: inherit !important; +} +.coverage-summary { + border-collapse: collapse; + width: 100%; +} +.coverage-summary tr { border-bottom: 1px solid #bbb; } +.keyline-all { border: 1px solid #ddd; } +.coverage-summary td, .coverage-summary th { padding: 10px; } +.coverage-summary tbody { border: 1px solid #bbb; } +.coverage-summary td { border-right: 1px solid #bbb; } +.coverage-summary td:last-child { border-right: none; } +.coverage-summary th { + text-align: left; + font-weight: normal; + white-space: nowrap; +} +.coverage-summary th.file { border-right: none !important; } +.coverage-summary th.pct { } +.coverage-summary th.pic, +.coverage-summary th.abs, +.coverage-summary td.pct, +.coverage-summary td.abs { text-align: right; } +.coverage-summary td.file { white-space: nowrap; } +.coverage-summary td.pic { min-width: 120px !important; } +.coverage-summary tfoot td { } + +.coverage-summary .sorter { + height: 10px; + width: 7px; + display: inline-block; + margin-left: 0.5em; + background: url(sort-arrow-sprite.png) no-repeat scroll 0 0 transparent; +} +.coverage-summary .sorted .sorter { + background-position: 0 -20px; +} +.coverage-summary .sorted-desc .sorter { + background-position: 0 -10px; +} +.status-line { height: 10px; } +/* yellow */ +.cbranch-no { background: yellow !important; color: #111; } +/* dark red */ +.red.solid, .status-line.low, .low .cover-fill { background:#C21F39 } +.low .chart { border:1px solid #C21F39 } +.highlighted, +.highlighted .cstat-no, .highlighted .fstat-no, .highlighted .cbranch-no{ + background: #C21F39 !important; +} +/* medium red */ +.cstat-no, .fstat-no, .cbranch-no, .cbranch-no { background:#F6C6CE } +/* light red */ +.low, .cline-no { background:#FCE1E5 } +/* light green */ +.high, .cline-yes { background:rgb(230,245,208) } +/* medium green */ +.cstat-yes { background:rgb(161,215,106) } +/* dark green */ +.status-line.high, .high .cover-fill { background:rgb(77,146,33) } +.high .chart { border:1px solid rgb(77,146,33) } +/* dark yellow (gold) */ +.status-line.medium, .medium .cover-fill { background: #f9cd0b; } +.medium .chart { border:1px solid #f9cd0b; } +/* light yellow */ +.medium { background: #fff4c2; } + +.cstat-skip { background: #ddd; color: #111; } +.fstat-skip { background: #ddd; color: #111 !important; } +.cbranch-skip { background: #ddd !important; color: #111; } + +span.cline-neutral { background: #eaeaea; } + +.coverage-summary td.empty { + opacity: .5; + padding-top: 4px; + padding-bottom: 4px; + line-height: 1; + color: #888; +} + +.cover-fill, .cover-empty { + display:inline-block; + height: 12px; +} +.chart { + line-height: 0; +} +.cover-empty { + background: white; +} +.cover-full { + border-right: none !important; +} +pre.prettyprint { + border: none !important; + padding: 0 !important; + margin: 0 !important; +} +.com { color: #999 !important; } +.ignore-none { color: #999; font-weight: normal; } + +.wrapper { + min-height: 100%; + height: auto !important; + height: 100%; + margin: 0 auto -48px; +} +.footer, .push { + height: 48px; +} diff --git a/coverage/lcov-report/block-navigation.js b/coverage/lcov-report/block-navigation.js new file mode 100644 index 0000000..530d1ed --- /dev/null +++ b/coverage/lcov-report/block-navigation.js @@ -0,0 +1,87 @@ +/* eslint-disable */ +var jumpToCode = (function init() { + // Classes of code we would like to highlight in the file view + var missingCoverageClasses = ['.cbranch-no', '.cstat-no', '.fstat-no']; + + // Elements to highlight in the file listing view + var fileListingElements = ['td.pct.low']; + + // We don't want to select elements that are direct descendants of another match + var notSelector = ':not(' + missingCoverageClasses.join('):not(') + ') > '; // becomes `:not(a):not(b) > ` + + // Selector that finds elements on the page to which we can jump + var selector = + fileListingElements.join(', ') + + ', ' + + notSelector + + missingCoverageClasses.join(', ' + notSelector); // becomes `:not(a):not(b) > a, :not(a):not(b) > b` + + // The NodeList of matching elements + var missingCoverageElements = document.querySelectorAll(selector); + + var currentIndex; + + function toggleClass(index) { + missingCoverageElements + .item(currentIndex) + .classList.remove('highlighted'); + missingCoverageElements.item(index).classList.add('highlighted'); + } + + function makeCurrent(index) { + toggleClass(index); + currentIndex = index; + missingCoverageElements.item(index).scrollIntoView({ + behavior: 'smooth', + block: 'center', + inline: 'center' + }); + } + + function goToPrevious() { + var nextIndex = 0; + if (typeof currentIndex !== 'number' || currentIndex === 0) { + nextIndex = missingCoverageElements.length - 1; + } else if (missingCoverageElements.length > 1) { + nextIndex = currentIndex - 1; + } + + makeCurrent(nextIndex); + } + + function goToNext() { + var nextIndex = 0; + + if ( + typeof currentIndex === 'number' && + currentIndex < missingCoverageElements.length - 1 + ) { + nextIndex = currentIndex + 1; + } + + makeCurrent(nextIndex); + } + + return function jump(event) { + if ( + document.getElementById('fileSearch') === document.activeElement && + document.activeElement != null + ) { + // if we're currently focused on the search input, we don't want to navigate + return; + } + + switch (event.which) { + case 78: // n + case 74: // j + goToNext(); + break; + case 66: // b + case 75: // k + case 80: // p + goToPrevious(); + break; + } + }; +})(); +window.addEventListener('keydown', jumpToCode); diff --git a/coverage/lcov-report/favicon.png b/coverage/lcov-report/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..c1525b811a167671e9de1fa78aab9f5c0b61cef7 GIT binary patch literal 445 zcmV;u0Yd(XP))rP{nL}Ln%S7`m{0DjX9TLF* zFCb$4Oi7vyLOydb!7n&^ItCzb-%BoB`=x@N2jll2Nj`kauio%aw_@fe&*}LqlFT43 z8doAAe))z_%=P%v^@JHp3Hjhj^6*Kr_h|g_Gr?ZAa&y>wxHE99Gk>A)2MplWz2xdG zy8VD2J|Uf#EAw*bo5O*PO_}X2Tob{%bUoO2G~T`@%S6qPyc}VkhV}UifBuRk>%5v( z)x7B{I~z*k<7dv#5tC+m{km(D087J4O%+<<;K|qwefb6@GSX45wCK}Sn*> + + + + Code coverage report for All files + + + + + + + + + +
+
+

All files

+
+ +
+ 100% + Statements + 19/19 +
+ + +
+ 100% + Branches + 0/0 +
+ + +
+ 100% + Functions + 7/7 +
+ + +
+ 100% + Lines + 18/18 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileStatementsBranchesFunctionsLines
time-utils.ts +
+
100%16/16100%0/0100%6/6100%16/16
token.ts +
+
100%3/3100%0/0100%1/1100%2/2
+
+
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/lcov-report/prettify.css b/coverage/lcov-report/prettify.css new file mode 100644 index 0000000..b317a7c --- /dev/null +++ b/coverage/lcov-report/prettify.css @@ -0,0 +1 @@ +.pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee} diff --git a/coverage/lcov-report/prettify.js b/coverage/lcov-report/prettify.js new file mode 100644 index 0000000..b322523 --- /dev/null +++ b/coverage/lcov-report/prettify.js @@ -0,0 +1,2 @@ +/* eslint-disable */ +window.PR_SHOULD_USE_CONTINUATION=true;(function(){var h=["break,continue,do,else,for,if,return,while"];var u=[h,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"];var p=[u,"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"];var l=[p,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"];var x=[p,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"];var R=[x,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"];var r="all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes";var w=[p,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"];var s="caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END";var I=[h,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"];var f=[h,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"];var H=[h,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"];var A=[l,R,w,s+I,f,H];var e=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/;var C="str";var z="kwd";var j="com";var O="typ";var G="lit";var L="pun";var F="pln";var m="tag";var E="dec";var J="src";var P="atn";var n="atv";var N="nocode";var M="(?:^^\\.?|[+-]|\\!|\\!=|\\!==|\\#|\\%|\\%=|&|&&|&&=|&=|\\(|\\*|\\*=|\\+=|\\,|\\-=|\\->|\\/|\\/=|:|::|\\;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|\\?|\\@|\\[|\\^|\\^=|\\^\\^|\\^\\^=|\\{|\\||\\|=|\\|\\||\\|\\|=|\\~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*";function k(Z){var ad=0;var S=false;var ac=false;for(var V=0,U=Z.length;V122)){if(!(al<65||ag>90)){af.push([Math.max(65,ag)|32,Math.min(al,90)|32])}if(!(al<97||ag>122)){af.push([Math.max(97,ag)&~32,Math.min(al,122)&~32])}}}}af.sort(function(av,au){return(av[0]-au[0])||(au[1]-av[1])});var ai=[];var ap=[NaN,NaN];for(var ar=0;arat[0]){if(at[1]+1>at[0]){an.push("-")}an.push(T(at[1]))}}an.push("]");return an.join("")}function W(al){var aj=al.source.match(new RegExp("(?:\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]|\\\\u[A-Fa-f0-9]{4}|\\\\x[A-Fa-f0-9]{2}|\\\\[0-9]+|\\\\[^ux0-9]|\\(\\?[:!=]|[\\(\\)\\^]|[^\\x5B\\x5C\\(\\)\\^]+)","g"));var ah=aj.length;var an=[];for(var ak=0,am=0;ak=2&&ai==="["){aj[ak]=X(ag)}else{if(ai!=="\\"){aj[ak]=ag.replace(/[a-zA-Z]/g,function(ao){var ap=ao.charCodeAt(0);return"["+String.fromCharCode(ap&~32,ap|32)+"]"})}}}}return aj.join("")}var aa=[];for(var V=0,U=Z.length;V=0;){S[ac.charAt(ae)]=Y}}var af=Y[1];var aa=""+af;if(!ag.hasOwnProperty(aa)){ah.push(af);ag[aa]=null}}ah.push(/[\0-\uffff]/);V=k(ah)})();var X=T.length;var W=function(ah){var Z=ah.sourceCode,Y=ah.basePos;var ad=[Y,F];var af=0;var an=Z.match(V)||[];var aj={};for(var ae=0,aq=an.length;ae=5&&"lang-"===ap.substring(0,5);if(am&&!(ai&&typeof ai[1]==="string")){am=false;ap=J}if(!am){aj[ag]=ap}}var ab=af;af+=ag.length;if(!am){ad.push(Y+ab,ap)}else{var al=ai[1];var ak=ag.indexOf(al);var ac=ak+al.length;if(ai[2]){ac=ag.length-ai[2].length;ak=ac-al.length}var ar=ap.substring(5);B(Y+ab,ag.substring(0,ak),W,ad);B(Y+ab+ak,al,q(ar,al),ad);B(Y+ab+ac,ag.substring(ac),W,ad)}}ah.decorations=ad};return W}function i(T){var W=[],S=[];if(T.tripleQuotedStrings){W.push([C,/^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,null,"'\""])}else{if(T.multiLineStrings){W.push([C,/^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,null,"'\"`"])}else{W.push([C,/^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,null,"\"'"])}}if(T.verbatimStrings){S.push([C,/^@\"(?:[^\"]|\"\")*(?:\"|$)/,null])}var Y=T.hashComments;if(Y){if(T.cStyleComments){if(Y>1){W.push([j,/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,null,"#"])}else{W.push([j,/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\r\n]*)/,null,"#"])}S.push([C,/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,null])}else{W.push([j,/^#[^\r\n]*/,null,"#"])}}if(T.cStyleComments){S.push([j,/^\/\/[^\r\n]*/,null]);S.push([j,/^\/\*[\s\S]*?(?:\*\/|$)/,null])}if(T.regexLiterals){var X=("/(?=[^/*])(?:[^/\\x5B\\x5C]|\\x5C[\\s\\S]|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+/");S.push(["lang-regex",new RegExp("^"+M+"("+X+")")])}var V=T.types;if(V){S.push([O,V])}var U=(""+T.keywords).replace(/^ | $/g,"");if(U.length){S.push([z,new RegExp("^(?:"+U.replace(/[\s,]+/g,"|")+")\\b"),null])}W.push([F,/^\s+/,null," \r\n\t\xA0"]);S.push([G,/^@[a-z_$][a-z_$@0-9]*/i,null],[O,/^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/,null],[F,/^[a-z_$][a-z_$@0-9]*/i,null],[G,new RegExp("^(?:0x[a-f0-9]+|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)(?:e[+\\-]?\\d+)?)[a-z]*","i"),null,"0123456789"],[F,/^\\[\s\S]?/,null],[L,/^.[^\s\w\.$@\'\"\`\/\#\\]*/,null]);return g(W,S)}var K=i({keywords:A,hashComments:true,cStyleComments:true,multiLineStrings:true,regexLiterals:true});function Q(V,ag){var U=/(?:^|\s)nocode(?:\s|$)/;var ab=/\r\n?|\n/;var ac=V.ownerDocument;var S;if(V.currentStyle){S=V.currentStyle.whiteSpace}else{if(window.getComputedStyle){S=ac.defaultView.getComputedStyle(V,null).getPropertyValue("white-space")}}var Z=S&&"pre"===S.substring(0,3);var af=ac.createElement("LI");while(V.firstChild){af.appendChild(V.firstChild)}var W=[af];function ae(al){switch(al.nodeType){case 1:if(U.test(al.className)){break}if("BR"===al.nodeName){ad(al);if(al.parentNode){al.parentNode.removeChild(al)}}else{for(var an=al.firstChild;an;an=an.nextSibling){ae(an)}}break;case 3:case 4:if(Z){var am=al.nodeValue;var aj=am.match(ab);if(aj){var ai=am.substring(0,aj.index);al.nodeValue=ai;var ah=am.substring(aj.index+aj[0].length);if(ah){var ak=al.parentNode;ak.insertBefore(ac.createTextNode(ah),al.nextSibling)}ad(al);if(!ai){al.parentNode.removeChild(al)}}}break}}function ad(ak){while(!ak.nextSibling){ak=ak.parentNode;if(!ak){return}}function ai(al,ar){var aq=ar?al.cloneNode(false):al;var ao=al.parentNode;if(ao){var ap=ai(ao,1);var an=al.nextSibling;ap.appendChild(aq);for(var am=an;am;am=an){an=am.nextSibling;ap.appendChild(am)}}return aq}var ah=ai(ak.nextSibling,0);for(var aj;(aj=ah.parentNode)&&aj.nodeType===1;){ah=aj}W.push(ah)}for(var Y=0;Y=S){ah+=2}if(V>=ap){Z+=2}}}var t={};function c(U,V){for(var S=V.length;--S>=0;){var T=V[S];if(!t.hasOwnProperty(T)){t[T]=U}else{if(window.console){console.warn("cannot override language handler %s",T)}}}}function q(T,S){if(!(T&&t.hasOwnProperty(T))){T=/^\s*]*(?:>|$)/],[j,/^<\!--[\s\S]*?(?:-\->|$)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],[L,/^(?:<[%?]|[%?]>)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),["default-markup","htm","html","mxml","xhtml","xml","xsl"]);c(g([[F,/^[\s]+/,null," \t\r\n"],[n,/^(?:\"[^\"]*\"?|\'[^\']*\'?)/,null,"\"'"]],[[m,/^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],[P,/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],[L,/^[=<>\/]+/],["lang-js",/^on\w+\s*=\s*\"([^\"]+)\"/i],["lang-js",/^on\w+\s*=\s*\'([^\']+)\'/i],["lang-js",/^on\w+\s*=\s*([^\"\'>\s]+)/i],["lang-css",/^style\s*=\s*\"([^\"]+)\"/i],["lang-css",/^style\s*=\s*\'([^\']+)\'/i],["lang-css",/^style\s*=\s*([^\"\'>\s]+)/i]]),["in.tag"]);c(g([],[[n,/^[\s\S]+/]]),["uq.val"]);c(i({keywords:l,hashComments:true,cStyleComments:true,types:e}),["c","cc","cpp","cxx","cyc","m"]);c(i({keywords:"null,true,false"}),["json"]);c(i({keywords:R,hashComments:true,cStyleComments:true,verbatimStrings:true,types:e}),["cs"]);c(i({keywords:x,cStyleComments:true}),["java"]);c(i({keywords:H,hashComments:true,multiLineStrings:true}),["bsh","csh","sh"]);c(i({keywords:I,hashComments:true,multiLineStrings:true,tripleQuotedStrings:true}),["cv","py"]);c(i({keywords:s,hashComments:true,multiLineStrings:true,regexLiterals:true}),["perl","pl","pm"]);c(i({keywords:f,hashComments:true,multiLineStrings:true,regexLiterals:true}),["rb"]);c(i({keywords:w,cStyleComments:true,regexLiterals:true}),["js"]);c(i({keywords:r,hashComments:3,cStyleComments:true,multilineStrings:true,tripleQuotedStrings:true,regexLiterals:true}),["coffee"]);c(g([],[[C,/^[\s\S]+/]]),["regex"]);function d(V){var U=V.langExtension;try{var S=a(V.sourceNode);var T=S.sourceCode;V.sourceCode=T;V.spans=S.spans;V.basePos=0;q(U,T)(V);D(V)}catch(W){if("console" in window){console.log(W&&W.stack?W.stack:W)}}}function y(W,V,U){var S=document.createElement("PRE");S.innerHTML=W;if(U){Q(S,U)}var T={langExtension:V,numberLines:U,sourceNode:S};d(T);return S.innerHTML}function b(ad){function Y(af){return document.getElementsByTagName(af)}var ac=[Y("pre"),Y("code"),Y("xmp")];var T=[];for(var aa=0;aa=0){var ah=ai.match(ab);var am;if(!ah&&(am=o(aj))&&"CODE"===am.tagName){ah=am.className.match(ab)}if(ah){ah=ah[1]}var al=false;for(var ak=aj.parentNode;ak;ak=ak.parentNode){if((ak.tagName==="pre"||ak.tagName==="code"||ak.tagName==="xmp")&&ak.className&&ak.className.indexOf("prettyprint")>=0){al=true;break}}if(!al){var af=aj.className.match(/\blinenums\b(?::(\d+))?/);af=af?af[1]&&af[1].length?+af[1]:true:false;if(af){Q(aj,af)}S={langExtension:ah,sourceNode:aj,numberLines:af};d(S)}}}if(X]*(?:>|$)/],[PR.PR_COMMENT,/^<\!--[\s\S]*?(?:-\->|$)/],[PR.PR_PUNCTUATION,/^(?:<[%?]|[%?]>)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-handlebars",/^]*type\s*=\s*['"]?text\/x-handlebars-template['"]?\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i],[PR.PR_DECLARATION,/^{{[#^>/]?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{&?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{{>?\s*[\w.][^}]*}}}/],[PR.PR_COMMENT,/^{{![^}]*}}/]]),["handlebars","hbs"]);PR.registerLangHandler(PR.createSimpleLexer([[PR.PR_PLAIN,/^[ \t\r\n\f]+/,null," \t\r\n\f"]],[[PR.PR_STRING,/^\"(?:[^\n\r\f\\\"]|\\(?:\r\n?|\n|\f)|\\[\s\S])*\"/,null],[PR.PR_STRING,/^\'(?:[^\n\r\f\\\']|\\(?:\r\n?|\n|\f)|\\[\s\S])*\'/,null],["lang-css-str",/^url\(([^\)\"\']*)\)/i],[PR.PR_KEYWORD,/^(?:url|rgb|\!important|@import|@page|@media|@charset|inherit)(?=[^\-\w]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|(?:\\[0-9a-f]+ ?))(?:[_a-z0-9\-]|\\(?:\\[0-9a-f]+ ?))*)\s*:/i],[PR.PR_COMMENT,/^\/\*[^*]*\*+(?:[^\/*][^*]*\*+)*\//],[PR.PR_COMMENT,/^(?:)/],[PR.PR_LITERAL,/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],[PR.PR_LITERAL,/^#(?:[0-9a-f]{3}){1,2}/i],[PR.PR_PLAIN,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i],[PR.PR_PUNCTUATION,/^[^\s\w\'\"]+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_KEYWORD,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_STRING,/^[^\)\"\']+/]]),["css-str"]); diff --git a/coverage/lcov-report/sort-arrow-sprite.png b/coverage/lcov-report/sort-arrow-sprite.png new file mode 100644 index 0000000000000000000000000000000000000000..6ed68316eb3f65dec9063332d2f69bf3093bbfab GIT binary patch literal 138 zcmeAS@N?(olHy`uVBq!ia0vp^>_9Bd!3HEZxJ@+%Qh}Z>jv*C{$p!i!8j}?a+@3A= zIAGwzjijN=FBi!|L1t?LM;Q;gkwn>2cAy-KV{dn nf0J1DIvEHQu*n~6U}x}qyky7vi4|9XhBJ7&`njxgN@xNA8m%nc literal 0 HcmV?d00001 diff --git a/coverage/lcov-report/sorter.js b/coverage/lcov-report/sorter.js new file mode 100644 index 0000000..4ed70ae --- /dev/null +++ b/coverage/lcov-report/sorter.js @@ -0,0 +1,210 @@ +/* eslint-disable */ +var addSorting = (function() { + 'use strict'; + var cols, + currentSort = { + index: 0, + desc: false + }; + + // returns the summary table element + function getTable() { + return document.querySelector('.coverage-summary'); + } + // returns the thead element of the summary table + function getTableHeader() { + return getTable().querySelector('thead tr'); + } + // returns the tbody element of the summary table + function getTableBody() { + return getTable().querySelector('tbody'); + } + // returns the th element for nth column + function getNthColumn(n) { + return getTableHeader().querySelectorAll('th')[n]; + } + + function onFilterInput() { + const searchValue = document.getElementById('fileSearch').value; + const rows = document.getElementsByTagName('tbody')[0].children; + + // Try to create a RegExp from the searchValue. If it fails (invalid regex), + // it will be treated as a plain text search + let searchRegex; + try { + searchRegex = new RegExp(searchValue, 'i'); // 'i' for case-insensitive + } catch (error) { + searchRegex = null; + } + + for (let i = 0; i < rows.length; i++) { + const row = rows[i]; + let isMatch = false; + + if (searchRegex) { + // If a valid regex was created, use it for matching + isMatch = searchRegex.test(row.textContent); + } else { + // Otherwise, fall back to the original plain text search + isMatch = row.textContent + .toLowerCase() + .includes(searchValue.toLowerCase()); + } + + row.style.display = isMatch ? '' : 'none'; + } + } + + // loads the search box + function addSearchBox() { + var template = document.getElementById('filterTemplate'); + var templateClone = template.content.cloneNode(true); + templateClone.getElementById('fileSearch').oninput = onFilterInput; + template.parentElement.appendChild(templateClone); + } + + // loads all columns + function loadColumns() { + var colNodes = getTableHeader().querySelectorAll('th'), + colNode, + cols = [], + col, + i; + + for (i = 0; i < colNodes.length; i += 1) { + colNode = colNodes[i]; + col = { + key: colNode.getAttribute('data-col'), + sortable: !colNode.getAttribute('data-nosort'), + type: colNode.getAttribute('data-type') || 'string' + }; + cols.push(col); + if (col.sortable) { + col.defaultDescSort = col.type === 'number'; + colNode.innerHTML = + colNode.innerHTML + ''; + } + } + return cols; + } + // attaches a data attribute to every tr element with an object + // of data values keyed by column name + function loadRowData(tableRow) { + var tableCols = tableRow.querySelectorAll('td'), + colNode, + col, + data = {}, + i, + val; + for (i = 0; i < tableCols.length; i += 1) { + colNode = tableCols[i]; + col = cols[i]; + val = colNode.getAttribute('data-value'); + if (col.type === 'number') { + val = Number(val); + } + data[col.key] = val; + } + return data; + } + // loads all row data + function loadData() { + var rows = getTableBody().querySelectorAll('tr'), + i; + + for (i = 0; i < rows.length; i += 1) { + rows[i].data = loadRowData(rows[i]); + } + } + // sorts the table using the data for the ith column + function sortByIndex(index, desc) { + var key = cols[index].key, + sorter = function(a, b) { + a = a.data[key]; + b = b.data[key]; + return a < b ? -1 : a > b ? 1 : 0; + }, + finalSorter = sorter, + tableBody = document.querySelector('.coverage-summary tbody'), + rowNodes = tableBody.querySelectorAll('tr'), + rows = [], + i; + + if (desc) { + finalSorter = function(a, b) { + return -1 * sorter(a, b); + }; + } + + for (i = 0; i < rowNodes.length; i += 1) { + rows.push(rowNodes[i]); + tableBody.removeChild(rowNodes[i]); + } + + rows.sort(finalSorter); + + for (i = 0; i < rows.length; i += 1) { + tableBody.appendChild(rows[i]); + } + } + // removes sort indicators for current column being sorted + function removeSortIndicators() { + var col = getNthColumn(currentSort.index), + cls = col.className; + + cls = cls.replace(/ sorted$/, '').replace(/ sorted-desc$/, ''); + col.className = cls; + } + // adds sort indicators for current column being sorted + function addSortIndicators() { + getNthColumn(currentSort.index).className += currentSort.desc + ? ' sorted-desc' + : ' sorted'; + } + // adds event listeners for all sorter widgets + function enableUI() { + var i, + el, + ithSorter = function ithSorter(i) { + var col = cols[i]; + + return function() { + var desc = col.defaultDescSort; + + if (currentSort.index === i) { + desc = !currentSort.desc; + } + sortByIndex(i, desc); + removeSortIndicators(); + currentSort.index = i; + currentSort.desc = desc; + addSortIndicators(); + }; + }; + for (i = 0; i < cols.length; i += 1) { + if (cols[i].sortable) { + // add the click event handler on the th so users + // dont have to click on those tiny arrows + el = getNthColumn(i).querySelector('.sorter').parentElement; + if (el.addEventListener) { + el.addEventListener('click', ithSorter(i)); + } else { + el.attachEvent('onclick', ithSorter(i)); + } + } + } + } + // adds sorting functionality to the UI + return function() { + if (!getTable()) { + return; + } + cols = loadColumns(); + loadData(); + addSearchBox(); + addSortIndicators(); + enableUI(); + }; +})(); + +window.addEventListener('load', addSorting); diff --git a/coverage/lcov-report/time-utils.ts.html b/coverage/lcov-report/time-utils.ts.html new file mode 100644 index 0000000..58709ca --- /dev/null +++ b/coverage/lcov-report/time-utils.ts.html @@ -0,0 +1,214 @@ + + + + + + Code coverage report for time-utils.ts + + + + + + + + + +
+
+

All files time-utils.ts

+
+ +
+ 100% + Statements + 16/16 +
+ + +
+ 100% + Branches + 0/0 +
+ + +
+ 100% + Functions + 6/6 +
+ + +
+ 100% + Lines + 16/16 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +441x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +5x +5x +5x +  +  +5x +  +  +  +1x +5x +5x +5x +5x +5x +  +5x +5x +  +20x +  +  +5x +  + 
export const TimePattern = {
+  HH_MM_SS: 'HH:MM:SS',
+  MM_SS: 'MM:SS',
+  MM_SS_MS: 'MM:SS.MS',
+} as const;
+ 
+interface TimeDetails {
+  hours: number;
+  minutes: number;
+  seconds: number;
+  milliseconds: number;
+}
+ 
+interface PatternRule {
+  pattern: string;
+  routine: (timeDetails: TimeDetails) => string;
+}
+ 
+const patterns: PatternRule[] = [
+  { pattern: 'HH', routine: ({ hours }) => String(hours).padStart(2, '0') },
+  { pattern: 'MM', routine: ({ minutes }) => String(minutes).padStart(2, '0') },
+  { pattern: 'SS', routine: ({ seconds }) => String(seconds).padStart(2, '0') },
+  {
+    pattern: 'MS',
+    routine: ({ milliseconds }) => String(milliseconds).padStart(3, '0'),
+  },
+];
+ 
+export const formatTime = (timeInMS: number, pattern: string): string => {
+  const milliseconds = Math.floor(timeInMS % 1000);
+  const seconds = Math.floor((timeInMS / 1000) % 60);
+  const minutes = Math.floor(Math.floor(timeInMS / 1000 / 60) % 60);
+  const hours = Math.floor((Math.floor(timeInMS / 1000 / 60) / 60) % 24);
+  const timeDetails: TimeDetails = { hours, minutes, seconds, milliseconds };
+ 
+  let result = pattern;
+  patterns.forEach(
+    ({ pattern: currentPattern, routine }) =>
+      (result = result.replace(currentPattern, routine(timeDetails)))
+  );
+ 
+  return result;
+};
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/lcov-report/token.ts.html b/coverage/lcov-report/token.ts.html new file mode 100644 index 0000000..f183751 --- /dev/null +++ b/coverage/lcov-report/token.ts.html @@ -0,0 +1,91 @@ + + + + + + Code coverage report for token.ts + + + + + + + + + +
+
+

All files token.ts

+
+ +
+ 100% + Statements + 3/3 +
+ + +
+ 100% + Branches + 0/0 +
+ + +
+ 100% + Functions + 1/1 +
+ + +
+ 100% + Lines + 2/2 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +31x +13x + 
let uniqueId = 0;
+export const getUniqueId = (): number => uniqueId++;
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/lcov.info b/coverage/lcov.info new file mode 100644 index 0000000..abb35df --- /dev/null +++ b/coverage/lcov.info @@ -0,0 +1,50 @@ +TN: +SF:src/time-utils.ts +FN:20,(anonymous_0) +FN:21,(anonymous_1) +FN:22,(anonymous_2) +FN:25,(anonymous_3) +FN:29,(anonymous_4) +FN:38,(anonymous_5) +FNF:6 +FNH:6 +FNDA:5,(anonymous_0) +FNDA:5,(anonymous_1) +FNDA:5,(anonymous_2) +FNDA:5,(anonymous_3) +FNDA:5,(anonymous_4) +FNDA:20,(anonymous_5) +DA:1,1 +DA:19,1 +DA:20,5 +DA:21,5 +DA:22,5 +DA:25,5 +DA:29,1 +DA:30,5 +DA:31,5 +DA:32,5 +DA:33,5 +DA:34,5 +DA:36,5 +DA:37,5 +DA:39,20 +DA:42,5 +LF:16 +LH:16 +BRF:0 +BRH:0 +end_of_record +TN: +SF:src/token.ts +FN:2,(anonymous_0) +FNF:1 +FNH:1 +FNDA:13,(anonymous_0) +DA:1,1 +DA:2,13 +LF:2 +LH:2 +BRF:0 +BRH:0 +end_of_record diff --git a/eslint.config.mjs b/eslint.config.mjs index eb2f958..db1fdd3 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -4,46 +4,46 @@ import importPlugin from 'eslint-plugin-import'; import prettierPlugin from 'eslint-plugin-prettier'; export default [ - { - files: ['**/*.ts'], - languageOptions: { - parser: typescriptParser, - }, - plugins: { - '@typescript-eslint': typescriptPlugin, - import: importPlugin, - prettier: prettierPlugin, - }, - rules: { - // General ESLint rules - 'no-console': 'warn', // Warn on console usage - 'no-debugger': 'error', // Disallow debugger - 'eqeqeq': ['error', 'always'], // Enforce strict equality + { + files: ['**/*.ts'], + languageOptions: { + parser: typescriptParser, + }, + plugins: { + '@typescript-eslint': typescriptPlugin, + import: importPlugin, + prettier: prettierPlugin, + }, + rules: { + // General ESLint rules + 'no-console': 'warn', // Warn on console usage + 'no-debugger': 'error', // Disallow debugger + 'eqeqeq': ['error', 'always'], // Enforce strict equality - // TypeScript-specific rules - '@typescript-eslint/no-explicit-any': 'warn', // Warn against using `any` type - '@typescript-eslint/no-empty-function': 'off', // Allow empty functions + // TypeScript-specific rules + '@typescript-eslint/no-explicit-any': 'warn', // Warn against using `any` type + '@typescript-eslint/no-empty-function': 'off', // Allow empty functions - // Import plugin rules - 'import/order': [ - 'error', - { - groups: ['builtin', 'external', 'internal', 'parent', 'sibling', 'index', 'object', 'type'], - alphabetize: { order: 'asc', caseInsensitive: true }, + // Import plugin rules + 'import/order': [ + 'error', + { + groups: ['builtin', 'external', 'internal', 'parent', 'sibling', 'index', 'object', 'type'], + alphabetize: { order: 'asc', caseInsensitive: true }, + }, + ], + // Temporary disabled + 'import/no-unresolved': 'off', // Ensure imports can be resolved + 'import/newline-after-import': 'error', // Enforce newline after import statements + 'prettier/prettier': ['error', { + endOfLine: 'lf' // Use LF line endings consistently + }], // Ensure code is formatted according to Prettier rules }, - ], - // Temporary disabled - 'import/no-unresolved': 'off', // Ensure imports can be resolved - 'import/newline-after-import': 'error', // Enforce newline after import statements - 'prettier/prettier': ['error', { - endOfLine: 'lf' // Use LF line endings consistently - }], // Ensure code is formatted according to Prettier rules }, - }, - { - files: ['**/*.test.ts', '**/test/**/*.ts'], - rules: { - '@typescript-eslint/no-explicit-any': 'off', // Disable `any` type rule for tests + { + files: ['**/*.test.ts', '**/test/**/*.ts'], + rules: { + '@typescript-eslint/no-explicit-any': 'off', // Disable `any` type rule for tests + }, }, - }, ]; \ No newline at end of file diff --git a/jest.config.js b/jest.config.js new file mode 100644 index 0000000..b3baa61 --- /dev/null +++ b/jest.config.js @@ -0,0 +1,17 @@ +export default { + preset: 'ts-jest/presets/default-esm', + testEnvironment: 'node', + extensionsToTreatAsEsm: ['.ts'], + transform: { + '^.+\\.m?[tj]sx?$': 'babel-jest', + }, + moduleNameMapper: { + '^(.+)\\.js$': '$1', + }, + transformIgnorePatterns: ['node_modules/(?!three)'], + roots: ['/src'], + moduleFileExtensions: ['ts', 'js'], + testMatch: ['**/__tests__/**/*.test.ts'], + collectCoverage: true, + coverageReporters: ['text', 'lcov'], +}; \ No newline at end of file diff --git a/src/__tests__/time-utils.test.ts b/src/__tests__/time-utils.test.ts new file mode 100644 index 0000000..3d7be9f --- /dev/null +++ b/src/__tests__/time-utils.test.ts @@ -0,0 +1,34 @@ +import { formatTime, TimePattern } from '../time-utils.js'; + +describe('TimeUtils', () => { + describe('formatTime', () => { + it('should format time correctly using HH_MM_SS pattern', () => { + const time = 3661000; // 1 hour, 1 minute, 1 second + const result = formatTime(time, TimePattern.HH_MM_SS); + expect(result).toBe('01:01:01'); + }); + + it('should format time correctly using MM_SS pattern', () => { + const time = 125000; // 2 minutes, 5 seconds + const result = formatTime(time, TimePattern.MM_SS); + expect(result).toBe('02:05'); + }); + + it('should format time correctly using MM_SS_MS pattern', () => { + const time = 125250; // 2 minutes, 5 seconds, 250 milliseconds + const result = formatTime(time, TimePattern.MM_SS_MS); + expect(result).toBe('02:05.250'); + }); + + it('should handle zero time', () => { + const result = formatTime(0, TimePattern.HH_MM_SS); + expect(result).toBe('00:00:00'); + }); + + it('should handle large values', () => { + const time = 3599999; // 59 minutes, 59 seconds, 999 milliseconds + const result = formatTime(time, TimePattern.HH_MM_SS); + expect(result).toBe('00:59:59'); + }); + }); +}); \ No newline at end of file diff --git a/src/__tests__/token.test.ts b/src/__tests__/token.test.ts new file mode 100644 index 0000000..d84eb68 --- /dev/null +++ b/src/__tests__/token.test.ts @@ -0,0 +1,28 @@ +import { getUniqueId } from '../token.js'; + +describe('TokenUtils', () => { + describe('getUniqueId', () => { + it('should return incremental unique IDs', () => { + const id1 = getUniqueId(); + const id2 = getUniqueId(); + const id3 = getUniqueId(); + + expect(typeof id1).toBe('number'); + expect(typeof id2).toBe('number'); + expect(typeof id3).toBe('number'); + + expect(id2).toBe(id1 + 1); + expect(id3).toBe(id2 + 1); + }); + + it('should return different IDs on each call', () => { + const ids = new Set(); + + for (let i = 0; i < 10; i++) { + ids.add(getUniqueId()); + } + + expect(ids.size).toBe(10); + }); + }); +}); \ No newline at end of file From 341e2014f18c43997143ab8557b3f8c451c6f7e2 Mon Sep 17 00:00:00 2001 From: Krisztian Somoracz Date: Thu, 16 Oct 2025 00:03:29 +0200 Subject: [PATCH 05/20] feat: complete CI/CD setup with Husky hooks and GitHub Actions - Add commitlint configuration for conventional commits - Set up Husky pre-commit hooks for linting and testing - Add commit-msg hook for commit message validation - Create GitHub Actions workflow for automated testing - Configure CI to run on master and v2 branches - Update .gitignore with comprehensive patterns - Enable automatic quality checks before commits - Ensure build verification in CI pipeline --- .github/workflows/test.yml | 25 +++++++++++++++ .gitignore | 55 ++++++++++++++++++++++++++++++++ .husky/commit-msg | 4 +++ .husky/pre-commit | 4 +++ babel.config.json | 5 ++- commitlint.config.cjs | 7 ++++ src/__tests__/time-utils.test.ts | 2 +- src/__tests__/token.test.ts | 4 +-- 8 files changed, 102 insertions(+), 4 deletions(-) create mode 100644 .github/workflows/test.yml create mode 100755 .husky/commit-msg create mode 100755 .husky/pre-commit create mode 100644 commitlint.config.cjs diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..1a72b39 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,25 @@ +name: Run Tests + +on: + push: + branches: + - master + - v2 + pull_request: + branches: + - master + - v2 + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: '20' + cache: 'npm' + - run: npm ci + - run: npm run lint + - run: npm run test + - run: npm run build \ No newline at end of file diff --git a/.gitignore b/.gitignore index c2658d7..b71b664 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,56 @@ +# Dependencies node_modules/ +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Build outputs - keep dist for npm publishing +# dist/ +build/ +*.tsbuildinfo + +# Testing +coverage/ +.nyc_output + +# Environment +.env +.env.local +.env.development.local +.env.test.local +.env.production.local + +# Editor +.vscode/ +.idea/ +*.swp +*.swo +*~ + +# OS +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes +ehthumbs.db +Thumbs.db + +# Logs +logs +*.log + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Webpack bundle analyzer +bundle-report.json diff --git a/.husky/commit-msg b/.husky/commit-msg new file mode 100755 index 0000000..2981178 --- /dev/null +++ b/.husky/commit-msg @@ -0,0 +1,4 @@ +#!/usr/bin/env sh +. "$(dirname -- "$0")/_/husky.sh" + +npx --no -- commitlint --edit ${1} \ No newline at end of file diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100755 index 0000000..2f2baa3 --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1,4 @@ +#!/usr/bin/env sh +. "$(dirname -- "$0")/_/husky.sh" + +npm run lint && npm run test \ No newline at end of file diff --git a/babel.config.json b/babel.config.json index 937768f..3e7174a 100644 --- a/babel.config.json +++ b/babel.config.json @@ -1,3 +1,6 @@ { - "presets": ["@babel/preset-env", "@babel/preset-typescript"] + "presets": [ + "@babel/preset-env", + "@babel/preset-typescript" + ] } \ No newline at end of file diff --git a/commitlint.config.cjs b/commitlint.config.cjs new file mode 100644 index 0000000..b7c07ea --- /dev/null +++ b/commitlint.config.cjs @@ -0,0 +1,7 @@ +// commitlint.config.js +module.exports = { + extends: ['@commitlint/config-conventional'], + rules: { + 'header-min-length': [2, 'always', 10], // level: error, applicable: always, value: 10 + }, +}; \ No newline at end of file diff --git a/src/__tests__/time-utils.test.ts b/src/__tests__/time-utils.test.ts index 3d7be9f..6fdf368 100644 --- a/src/__tests__/time-utils.test.ts +++ b/src/__tests__/time-utils.test.ts @@ -31,4 +31,4 @@ describe('TimeUtils', () => { expect(result).toBe('00:59:59'); }); }); -}); \ No newline at end of file +}); diff --git a/src/__tests__/token.test.ts b/src/__tests__/token.test.ts index d84eb68..6fcca0a 100644 --- a/src/__tests__/token.test.ts +++ b/src/__tests__/token.test.ts @@ -17,7 +17,7 @@ describe('TokenUtils', () => { it('should return different IDs on each call', () => { const ids = new Set(); - + for (let i = 0; i < 10; i++) { ids.add(getUniqueId()); } @@ -25,4 +25,4 @@ describe('TokenUtils', () => { expect(ids.size).toBe(10); }); }); -}); \ No newline at end of file +}); From d5a60dcb237bf87b9b54bab12371a4c935d30619 Mon Sep 17 00:00:00 2001 From: Krisztian Somoracz Date: Thu, 16 Oct 2025 00:05:42 +0200 Subject: [PATCH 06/20] refactor: remove coverage and bundle reports from git tracking - Remove coverage/ directory from version control - Remove dist/bundle-report.json from tracking - These files are now properly ignored by .gitignore - Generated files should not be committed to repository --- coverage/lcov-report/base.css | 224 --------------------- coverage/lcov-report/block-navigation.js | 87 -------- coverage/lcov-report/favicon.png | Bin 445 -> 0 bytes coverage/lcov-report/index.html | 131 ------------ coverage/lcov-report/prettify.css | 1 - coverage/lcov-report/prettify.js | 2 - coverage/lcov-report/sort-arrow-sprite.png | Bin 138 -> 0 bytes coverage/lcov-report/sorter.js | 210 ------------------- coverage/lcov-report/time-utils.ts.html | 214 -------------------- coverage/lcov-report/token.ts.html | 91 --------- coverage/lcov.info | 50 ----- dist/bundle-report.json | 1 - 12 files changed, 1011 deletions(-) delete mode 100644 coverage/lcov-report/base.css delete mode 100644 coverage/lcov-report/block-navigation.js delete mode 100644 coverage/lcov-report/favicon.png delete mode 100644 coverage/lcov-report/index.html delete mode 100644 coverage/lcov-report/prettify.css delete mode 100644 coverage/lcov-report/prettify.js delete mode 100644 coverage/lcov-report/sort-arrow-sprite.png delete mode 100644 coverage/lcov-report/sorter.js delete mode 100644 coverage/lcov-report/time-utils.ts.html delete mode 100644 coverage/lcov-report/token.ts.html delete mode 100644 coverage/lcov.info delete mode 100644 dist/bundle-report.json diff --git a/coverage/lcov-report/base.css b/coverage/lcov-report/base.css deleted file mode 100644 index f418035..0000000 --- a/coverage/lcov-report/base.css +++ /dev/null @@ -1,224 +0,0 @@ -body, html { - margin:0; padding: 0; - height: 100%; -} -body { - font-family: Helvetica Neue, Helvetica, Arial; - font-size: 14px; - color:#333; -} -.small { font-size: 12px; } -*, *:after, *:before { - -webkit-box-sizing:border-box; - -moz-box-sizing:border-box; - box-sizing:border-box; - } -h1 { font-size: 20px; margin: 0;} -h2 { font-size: 14px; } -pre { - font: 12px/1.4 Consolas, "Liberation Mono", Menlo, Courier, monospace; - margin: 0; - padding: 0; - -moz-tab-size: 2; - -o-tab-size: 2; - tab-size: 2; -} -a { color:#0074D9; text-decoration:none; } -a:hover { text-decoration:underline; } -.strong { font-weight: bold; } -.space-top1 { padding: 10px 0 0 0; } -.pad2y { padding: 20px 0; } -.pad1y { padding: 10px 0; } -.pad2x { padding: 0 20px; } -.pad2 { padding: 20px; } -.pad1 { padding: 10px; } -.space-left2 { padding-left:55px; } -.space-right2 { padding-right:20px; } -.center { text-align:center; } -.clearfix { display:block; } -.clearfix:after { - content:''; - display:block; - height:0; - clear:both; - visibility:hidden; - } -.fl { float: left; } -@media only screen and (max-width:640px) { - .col3 { width:100%; max-width:100%; } - .hide-mobile { display:none!important; } -} - -.quiet { - color: #7f7f7f; - color: rgba(0,0,0,0.5); -} -.quiet a { opacity: 0.7; } - -.fraction { - font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; - font-size: 10px; - color: #555; - background: #E8E8E8; - padding: 4px 5px; - border-radius: 3px; - vertical-align: middle; -} - -div.path a:link, div.path a:visited { color: #333; } -table.coverage { - border-collapse: collapse; - margin: 10px 0 0 0; - padding: 0; -} - -table.coverage td { - margin: 0; - padding: 0; - vertical-align: top; -} -table.coverage td.line-count { - text-align: right; - padding: 0 5px 0 20px; -} -table.coverage td.line-coverage { - text-align: right; - padding-right: 10px; - min-width:20px; -} - -table.coverage td span.cline-any { - display: inline-block; - padding: 0 5px; - width: 100%; -} -.missing-if-branch { - display: inline-block; - margin-right: 5px; - border-radius: 3px; - position: relative; - padding: 0 4px; - background: #333; - color: yellow; -} - -.skip-if-branch { - display: none; - margin-right: 10px; - position: relative; - padding: 0 4px; - background: #ccc; - color: white; -} -.missing-if-branch .typ, .skip-if-branch .typ { - color: inherit !important; -} -.coverage-summary { - border-collapse: collapse; - width: 100%; -} -.coverage-summary tr { border-bottom: 1px solid #bbb; } -.keyline-all { border: 1px solid #ddd; } -.coverage-summary td, .coverage-summary th { padding: 10px; } -.coverage-summary tbody { border: 1px solid #bbb; } -.coverage-summary td { border-right: 1px solid #bbb; } -.coverage-summary td:last-child { border-right: none; } -.coverage-summary th { - text-align: left; - font-weight: normal; - white-space: nowrap; -} -.coverage-summary th.file { border-right: none !important; } -.coverage-summary th.pct { } -.coverage-summary th.pic, -.coverage-summary th.abs, -.coverage-summary td.pct, -.coverage-summary td.abs { text-align: right; } -.coverage-summary td.file { white-space: nowrap; } -.coverage-summary td.pic { min-width: 120px !important; } -.coverage-summary tfoot td { } - -.coverage-summary .sorter { - height: 10px; - width: 7px; - display: inline-block; - margin-left: 0.5em; - background: url(sort-arrow-sprite.png) no-repeat scroll 0 0 transparent; -} -.coverage-summary .sorted .sorter { - background-position: 0 -20px; -} -.coverage-summary .sorted-desc .sorter { - background-position: 0 -10px; -} -.status-line { height: 10px; } -/* yellow */ -.cbranch-no { background: yellow !important; color: #111; } -/* dark red */ -.red.solid, .status-line.low, .low .cover-fill { background:#C21F39 } -.low .chart { border:1px solid #C21F39 } -.highlighted, -.highlighted .cstat-no, .highlighted .fstat-no, .highlighted .cbranch-no{ - background: #C21F39 !important; -} -/* medium red */ -.cstat-no, .fstat-no, .cbranch-no, .cbranch-no { background:#F6C6CE } -/* light red */ -.low, .cline-no { background:#FCE1E5 } -/* light green */ -.high, .cline-yes { background:rgb(230,245,208) } -/* medium green */ -.cstat-yes { background:rgb(161,215,106) } -/* dark green */ -.status-line.high, .high .cover-fill { background:rgb(77,146,33) } -.high .chart { border:1px solid rgb(77,146,33) } -/* dark yellow (gold) */ -.status-line.medium, .medium .cover-fill { background: #f9cd0b; } -.medium .chart { border:1px solid #f9cd0b; } -/* light yellow */ -.medium { background: #fff4c2; } - -.cstat-skip { background: #ddd; color: #111; } -.fstat-skip { background: #ddd; color: #111 !important; } -.cbranch-skip { background: #ddd !important; color: #111; } - -span.cline-neutral { background: #eaeaea; } - -.coverage-summary td.empty { - opacity: .5; - padding-top: 4px; - padding-bottom: 4px; - line-height: 1; - color: #888; -} - -.cover-fill, .cover-empty { - display:inline-block; - height: 12px; -} -.chart { - line-height: 0; -} -.cover-empty { - background: white; -} -.cover-full { - border-right: none !important; -} -pre.prettyprint { - border: none !important; - padding: 0 !important; - margin: 0 !important; -} -.com { color: #999 !important; } -.ignore-none { color: #999; font-weight: normal; } - -.wrapper { - min-height: 100%; - height: auto !important; - height: 100%; - margin: 0 auto -48px; -} -.footer, .push { - height: 48px; -} diff --git a/coverage/lcov-report/block-navigation.js b/coverage/lcov-report/block-navigation.js deleted file mode 100644 index 530d1ed..0000000 --- a/coverage/lcov-report/block-navigation.js +++ /dev/null @@ -1,87 +0,0 @@ -/* eslint-disable */ -var jumpToCode = (function init() { - // Classes of code we would like to highlight in the file view - var missingCoverageClasses = ['.cbranch-no', '.cstat-no', '.fstat-no']; - - // Elements to highlight in the file listing view - var fileListingElements = ['td.pct.low']; - - // We don't want to select elements that are direct descendants of another match - var notSelector = ':not(' + missingCoverageClasses.join('):not(') + ') > '; // becomes `:not(a):not(b) > ` - - // Selector that finds elements on the page to which we can jump - var selector = - fileListingElements.join(', ') + - ', ' + - notSelector + - missingCoverageClasses.join(', ' + notSelector); // becomes `:not(a):not(b) > a, :not(a):not(b) > b` - - // The NodeList of matching elements - var missingCoverageElements = document.querySelectorAll(selector); - - var currentIndex; - - function toggleClass(index) { - missingCoverageElements - .item(currentIndex) - .classList.remove('highlighted'); - missingCoverageElements.item(index).classList.add('highlighted'); - } - - function makeCurrent(index) { - toggleClass(index); - currentIndex = index; - missingCoverageElements.item(index).scrollIntoView({ - behavior: 'smooth', - block: 'center', - inline: 'center' - }); - } - - function goToPrevious() { - var nextIndex = 0; - if (typeof currentIndex !== 'number' || currentIndex === 0) { - nextIndex = missingCoverageElements.length - 1; - } else if (missingCoverageElements.length > 1) { - nextIndex = currentIndex - 1; - } - - makeCurrent(nextIndex); - } - - function goToNext() { - var nextIndex = 0; - - if ( - typeof currentIndex === 'number' && - currentIndex < missingCoverageElements.length - 1 - ) { - nextIndex = currentIndex + 1; - } - - makeCurrent(nextIndex); - } - - return function jump(event) { - if ( - document.getElementById('fileSearch') === document.activeElement && - document.activeElement != null - ) { - // if we're currently focused on the search input, we don't want to navigate - return; - } - - switch (event.which) { - case 78: // n - case 74: // j - goToNext(); - break; - case 66: // b - case 75: // k - case 80: // p - goToPrevious(); - break; - } - }; -})(); -window.addEventListener('keydown', jumpToCode); diff --git a/coverage/lcov-report/favicon.png b/coverage/lcov-report/favicon.png deleted file mode 100644 index c1525b811a167671e9de1fa78aab9f5c0b61cef7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 445 zcmV;u0Yd(XP))rP{nL}Ln%S7`m{0DjX9TLF* zFCb$4Oi7vyLOydb!7n&^ItCzb-%BoB`=x@N2jll2Nj`kauio%aw_@fe&*}LqlFT43 z8doAAe))z_%=P%v^@JHp3Hjhj^6*Kr_h|g_Gr?ZAa&y>wxHE99Gk>A)2MplWz2xdG zy8VD2J|Uf#EAw*bo5O*PO_}X2Tob{%bUoO2G~T`@%S6qPyc}VkhV}UifBuRk>%5v( z)x7B{I~z*k<7dv#5tC+m{km(D087J4O%+<<;K|qwefb6@GSX45wCK}Sn*> - - - - Code coverage report for All files - - - - - - - - - -
-
-

All files

-
- -
- 100% - Statements - 19/19 -
- - -
- 100% - Branches - 0/0 -
- - -
- 100% - Functions - 7/7 -
- - -
- 100% - Lines - 18/18 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
time-utils.ts -
-
100%16/16100%0/0100%6/6100%16/16
token.ts -
-
100%3/3100%0/0100%1/1100%2/2
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/prettify.css b/coverage/lcov-report/prettify.css deleted file mode 100644 index b317a7c..0000000 --- a/coverage/lcov-report/prettify.css +++ /dev/null @@ -1 +0,0 @@ -.pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee} diff --git a/coverage/lcov-report/prettify.js b/coverage/lcov-report/prettify.js deleted file mode 100644 index b322523..0000000 --- a/coverage/lcov-report/prettify.js +++ /dev/null @@ -1,2 +0,0 @@ -/* eslint-disable */ -window.PR_SHOULD_USE_CONTINUATION=true;(function(){var h=["break,continue,do,else,for,if,return,while"];var u=[h,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"];var p=[u,"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"];var l=[p,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"];var x=[p,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"];var R=[x,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"];var r="all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes";var w=[p,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"];var s="caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END";var I=[h,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"];var f=[h,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"];var H=[h,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"];var A=[l,R,w,s+I,f,H];var e=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/;var C="str";var z="kwd";var j="com";var O="typ";var G="lit";var L="pun";var F="pln";var m="tag";var E="dec";var J="src";var P="atn";var n="atv";var N="nocode";var M="(?:^^\\.?|[+-]|\\!|\\!=|\\!==|\\#|\\%|\\%=|&|&&|&&=|&=|\\(|\\*|\\*=|\\+=|\\,|\\-=|\\->|\\/|\\/=|:|::|\\;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|\\?|\\@|\\[|\\^|\\^=|\\^\\^|\\^\\^=|\\{|\\||\\|=|\\|\\||\\|\\|=|\\~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*";function k(Z){var ad=0;var S=false;var ac=false;for(var V=0,U=Z.length;V122)){if(!(al<65||ag>90)){af.push([Math.max(65,ag)|32,Math.min(al,90)|32])}if(!(al<97||ag>122)){af.push([Math.max(97,ag)&~32,Math.min(al,122)&~32])}}}}af.sort(function(av,au){return(av[0]-au[0])||(au[1]-av[1])});var ai=[];var ap=[NaN,NaN];for(var ar=0;arat[0]){if(at[1]+1>at[0]){an.push("-")}an.push(T(at[1]))}}an.push("]");return an.join("")}function W(al){var aj=al.source.match(new RegExp("(?:\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]|\\\\u[A-Fa-f0-9]{4}|\\\\x[A-Fa-f0-9]{2}|\\\\[0-9]+|\\\\[^ux0-9]|\\(\\?[:!=]|[\\(\\)\\^]|[^\\x5B\\x5C\\(\\)\\^]+)","g"));var ah=aj.length;var an=[];for(var ak=0,am=0;ak=2&&ai==="["){aj[ak]=X(ag)}else{if(ai!=="\\"){aj[ak]=ag.replace(/[a-zA-Z]/g,function(ao){var ap=ao.charCodeAt(0);return"["+String.fromCharCode(ap&~32,ap|32)+"]"})}}}}return aj.join("")}var aa=[];for(var V=0,U=Z.length;V=0;){S[ac.charAt(ae)]=Y}}var af=Y[1];var aa=""+af;if(!ag.hasOwnProperty(aa)){ah.push(af);ag[aa]=null}}ah.push(/[\0-\uffff]/);V=k(ah)})();var X=T.length;var W=function(ah){var Z=ah.sourceCode,Y=ah.basePos;var ad=[Y,F];var af=0;var an=Z.match(V)||[];var aj={};for(var ae=0,aq=an.length;ae=5&&"lang-"===ap.substring(0,5);if(am&&!(ai&&typeof ai[1]==="string")){am=false;ap=J}if(!am){aj[ag]=ap}}var ab=af;af+=ag.length;if(!am){ad.push(Y+ab,ap)}else{var al=ai[1];var ak=ag.indexOf(al);var ac=ak+al.length;if(ai[2]){ac=ag.length-ai[2].length;ak=ac-al.length}var ar=ap.substring(5);B(Y+ab,ag.substring(0,ak),W,ad);B(Y+ab+ak,al,q(ar,al),ad);B(Y+ab+ac,ag.substring(ac),W,ad)}}ah.decorations=ad};return W}function i(T){var W=[],S=[];if(T.tripleQuotedStrings){W.push([C,/^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,null,"'\""])}else{if(T.multiLineStrings){W.push([C,/^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,null,"'\"`"])}else{W.push([C,/^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,null,"\"'"])}}if(T.verbatimStrings){S.push([C,/^@\"(?:[^\"]|\"\")*(?:\"|$)/,null])}var Y=T.hashComments;if(Y){if(T.cStyleComments){if(Y>1){W.push([j,/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,null,"#"])}else{W.push([j,/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\r\n]*)/,null,"#"])}S.push([C,/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,null])}else{W.push([j,/^#[^\r\n]*/,null,"#"])}}if(T.cStyleComments){S.push([j,/^\/\/[^\r\n]*/,null]);S.push([j,/^\/\*[\s\S]*?(?:\*\/|$)/,null])}if(T.regexLiterals){var X=("/(?=[^/*])(?:[^/\\x5B\\x5C]|\\x5C[\\s\\S]|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+/");S.push(["lang-regex",new RegExp("^"+M+"("+X+")")])}var V=T.types;if(V){S.push([O,V])}var U=(""+T.keywords).replace(/^ | $/g,"");if(U.length){S.push([z,new RegExp("^(?:"+U.replace(/[\s,]+/g,"|")+")\\b"),null])}W.push([F,/^\s+/,null," \r\n\t\xA0"]);S.push([G,/^@[a-z_$][a-z_$@0-9]*/i,null],[O,/^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/,null],[F,/^[a-z_$][a-z_$@0-9]*/i,null],[G,new RegExp("^(?:0x[a-f0-9]+|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)(?:e[+\\-]?\\d+)?)[a-z]*","i"),null,"0123456789"],[F,/^\\[\s\S]?/,null],[L,/^.[^\s\w\.$@\'\"\`\/\#\\]*/,null]);return g(W,S)}var K=i({keywords:A,hashComments:true,cStyleComments:true,multiLineStrings:true,regexLiterals:true});function Q(V,ag){var U=/(?:^|\s)nocode(?:\s|$)/;var ab=/\r\n?|\n/;var ac=V.ownerDocument;var S;if(V.currentStyle){S=V.currentStyle.whiteSpace}else{if(window.getComputedStyle){S=ac.defaultView.getComputedStyle(V,null).getPropertyValue("white-space")}}var Z=S&&"pre"===S.substring(0,3);var af=ac.createElement("LI");while(V.firstChild){af.appendChild(V.firstChild)}var W=[af];function ae(al){switch(al.nodeType){case 1:if(U.test(al.className)){break}if("BR"===al.nodeName){ad(al);if(al.parentNode){al.parentNode.removeChild(al)}}else{for(var an=al.firstChild;an;an=an.nextSibling){ae(an)}}break;case 3:case 4:if(Z){var am=al.nodeValue;var aj=am.match(ab);if(aj){var ai=am.substring(0,aj.index);al.nodeValue=ai;var ah=am.substring(aj.index+aj[0].length);if(ah){var ak=al.parentNode;ak.insertBefore(ac.createTextNode(ah),al.nextSibling)}ad(al);if(!ai){al.parentNode.removeChild(al)}}}break}}function ad(ak){while(!ak.nextSibling){ak=ak.parentNode;if(!ak){return}}function ai(al,ar){var aq=ar?al.cloneNode(false):al;var ao=al.parentNode;if(ao){var ap=ai(ao,1);var an=al.nextSibling;ap.appendChild(aq);for(var am=an;am;am=an){an=am.nextSibling;ap.appendChild(am)}}return aq}var ah=ai(ak.nextSibling,0);for(var aj;(aj=ah.parentNode)&&aj.nodeType===1;){ah=aj}W.push(ah)}for(var Y=0;Y=S){ah+=2}if(V>=ap){Z+=2}}}var t={};function c(U,V){for(var S=V.length;--S>=0;){var T=V[S];if(!t.hasOwnProperty(T)){t[T]=U}else{if(window.console){console.warn("cannot override language handler %s",T)}}}}function q(T,S){if(!(T&&t.hasOwnProperty(T))){T=/^\s*]*(?:>|$)/],[j,/^<\!--[\s\S]*?(?:-\->|$)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],[L,/^(?:<[%?]|[%?]>)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),["default-markup","htm","html","mxml","xhtml","xml","xsl"]);c(g([[F,/^[\s]+/,null," \t\r\n"],[n,/^(?:\"[^\"]*\"?|\'[^\']*\'?)/,null,"\"'"]],[[m,/^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],[P,/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],[L,/^[=<>\/]+/],["lang-js",/^on\w+\s*=\s*\"([^\"]+)\"/i],["lang-js",/^on\w+\s*=\s*\'([^\']+)\'/i],["lang-js",/^on\w+\s*=\s*([^\"\'>\s]+)/i],["lang-css",/^style\s*=\s*\"([^\"]+)\"/i],["lang-css",/^style\s*=\s*\'([^\']+)\'/i],["lang-css",/^style\s*=\s*([^\"\'>\s]+)/i]]),["in.tag"]);c(g([],[[n,/^[\s\S]+/]]),["uq.val"]);c(i({keywords:l,hashComments:true,cStyleComments:true,types:e}),["c","cc","cpp","cxx","cyc","m"]);c(i({keywords:"null,true,false"}),["json"]);c(i({keywords:R,hashComments:true,cStyleComments:true,verbatimStrings:true,types:e}),["cs"]);c(i({keywords:x,cStyleComments:true}),["java"]);c(i({keywords:H,hashComments:true,multiLineStrings:true}),["bsh","csh","sh"]);c(i({keywords:I,hashComments:true,multiLineStrings:true,tripleQuotedStrings:true}),["cv","py"]);c(i({keywords:s,hashComments:true,multiLineStrings:true,regexLiterals:true}),["perl","pl","pm"]);c(i({keywords:f,hashComments:true,multiLineStrings:true,regexLiterals:true}),["rb"]);c(i({keywords:w,cStyleComments:true,regexLiterals:true}),["js"]);c(i({keywords:r,hashComments:3,cStyleComments:true,multilineStrings:true,tripleQuotedStrings:true,regexLiterals:true}),["coffee"]);c(g([],[[C,/^[\s\S]+/]]),["regex"]);function d(V){var U=V.langExtension;try{var S=a(V.sourceNode);var T=S.sourceCode;V.sourceCode=T;V.spans=S.spans;V.basePos=0;q(U,T)(V);D(V)}catch(W){if("console" in window){console.log(W&&W.stack?W.stack:W)}}}function y(W,V,U){var S=document.createElement("PRE");S.innerHTML=W;if(U){Q(S,U)}var T={langExtension:V,numberLines:U,sourceNode:S};d(T);return S.innerHTML}function b(ad){function Y(af){return document.getElementsByTagName(af)}var ac=[Y("pre"),Y("code"),Y("xmp")];var T=[];for(var aa=0;aa=0){var ah=ai.match(ab);var am;if(!ah&&(am=o(aj))&&"CODE"===am.tagName){ah=am.className.match(ab)}if(ah){ah=ah[1]}var al=false;for(var ak=aj.parentNode;ak;ak=ak.parentNode){if((ak.tagName==="pre"||ak.tagName==="code"||ak.tagName==="xmp")&&ak.className&&ak.className.indexOf("prettyprint")>=0){al=true;break}}if(!al){var af=aj.className.match(/\blinenums\b(?::(\d+))?/);af=af?af[1]&&af[1].length?+af[1]:true:false;if(af){Q(aj,af)}S={langExtension:ah,sourceNode:aj,numberLines:af};d(S)}}}if(X]*(?:>|$)/],[PR.PR_COMMENT,/^<\!--[\s\S]*?(?:-\->|$)/],[PR.PR_PUNCTUATION,/^(?:<[%?]|[%?]>)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-handlebars",/^]*type\s*=\s*['"]?text\/x-handlebars-template['"]?\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i],[PR.PR_DECLARATION,/^{{[#^>/]?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{&?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{{>?\s*[\w.][^}]*}}}/],[PR.PR_COMMENT,/^{{![^}]*}}/]]),["handlebars","hbs"]);PR.registerLangHandler(PR.createSimpleLexer([[PR.PR_PLAIN,/^[ \t\r\n\f]+/,null," \t\r\n\f"]],[[PR.PR_STRING,/^\"(?:[^\n\r\f\\\"]|\\(?:\r\n?|\n|\f)|\\[\s\S])*\"/,null],[PR.PR_STRING,/^\'(?:[^\n\r\f\\\']|\\(?:\r\n?|\n|\f)|\\[\s\S])*\'/,null],["lang-css-str",/^url\(([^\)\"\']*)\)/i],[PR.PR_KEYWORD,/^(?:url|rgb|\!important|@import|@page|@media|@charset|inherit)(?=[^\-\w]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|(?:\\[0-9a-f]+ ?))(?:[_a-z0-9\-]|\\(?:\\[0-9a-f]+ ?))*)\s*:/i],[PR.PR_COMMENT,/^\/\*[^*]*\*+(?:[^\/*][^*]*\*+)*\//],[PR.PR_COMMENT,/^(?:)/],[PR.PR_LITERAL,/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],[PR.PR_LITERAL,/^#(?:[0-9a-f]{3}){1,2}/i],[PR.PR_PLAIN,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i],[PR.PR_PUNCTUATION,/^[^\s\w\'\"]+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_KEYWORD,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_STRING,/^[^\)\"\']+/]]),["css-str"]); diff --git a/coverage/lcov-report/sort-arrow-sprite.png b/coverage/lcov-report/sort-arrow-sprite.png deleted file mode 100644 index 6ed68316eb3f65dec9063332d2f69bf3093bbfab..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 138 zcmeAS@N?(olHy`uVBq!ia0vp^>_9Bd!3HEZxJ@+%Qh}Z>jv*C{$p!i!8j}?a+@3A= zIAGwzjijN=FBi!|L1t?LM;Q;gkwn>2cAy-KV{dn nf0J1DIvEHQu*n~6U}x}qyky7vi4|9XhBJ7&`njxgN@xNA8m%nc diff --git a/coverage/lcov-report/sorter.js b/coverage/lcov-report/sorter.js deleted file mode 100644 index 4ed70ae..0000000 --- a/coverage/lcov-report/sorter.js +++ /dev/null @@ -1,210 +0,0 @@ -/* eslint-disable */ -var addSorting = (function() { - 'use strict'; - var cols, - currentSort = { - index: 0, - desc: false - }; - - // returns the summary table element - function getTable() { - return document.querySelector('.coverage-summary'); - } - // returns the thead element of the summary table - function getTableHeader() { - return getTable().querySelector('thead tr'); - } - // returns the tbody element of the summary table - function getTableBody() { - return getTable().querySelector('tbody'); - } - // returns the th element for nth column - function getNthColumn(n) { - return getTableHeader().querySelectorAll('th')[n]; - } - - function onFilterInput() { - const searchValue = document.getElementById('fileSearch').value; - const rows = document.getElementsByTagName('tbody')[0].children; - - // Try to create a RegExp from the searchValue. If it fails (invalid regex), - // it will be treated as a plain text search - let searchRegex; - try { - searchRegex = new RegExp(searchValue, 'i'); // 'i' for case-insensitive - } catch (error) { - searchRegex = null; - } - - for (let i = 0; i < rows.length; i++) { - const row = rows[i]; - let isMatch = false; - - if (searchRegex) { - // If a valid regex was created, use it for matching - isMatch = searchRegex.test(row.textContent); - } else { - // Otherwise, fall back to the original plain text search - isMatch = row.textContent - .toLowerCase() - .includes(searchValue.toLowerCase()); - } - - row.style.display = isMatch ? '' : 'none'; - } - } - - // loads the search box - function addSearchBox() { - var template = document.getElementById('filterTemplate'); - var templateClone = template.content.cloneNode(true); - templateClone.getElementById('fileSearch').oninput = onFilterInput; - template.parentElement.appendChild(templateClone); - } - - // loads all columns - function loadColumns() { - var colNodes = getTableHeader().querySelectorAll('th'), - colNode, - cols = [], - col, - i; - - for (i = 0; i < colNodes.length; i += 1) { - colNode = colNodes[i]; - col = { - key: colNode.getAttribute('data-col'), - sortable: !colNode.getAttribute('data-nosort'), - type: colNode.getAttribute('data-type') || 'string' - }; - cols.push(col); - if (col.sortable) { - col.defaultDescSort = col.type === 'number'; - colNode.innerHTML = - colNode.innerHTML + ''; - } - } - return cols; - } - // attaches a data attribute to every tr element with an object - // of data values keyed by column name - function loadRowData(tableRow) { - var tableCols = tableRow.querySelectorAll('td'), - colNode, - col, - data = {}, - i, - val; - for (i = 0; i < tableCols.length; i += 1) { - colNode = tableCols[i]; - col = cols[i]; - val = colNode.getAttribute('data-value'); - if (col.type === 'number') { - val = Number(val); - } - data[col.key] = val; - } - return data; - } - // loads all row data - function loadData() { - var rows = getTableBody().querySelectorAll('tr'), - i; - - for (i = 0; i < rows.length; i += 1) { - rows[i].data = loadRowData(rows[i]); - } - } - // sorts the table using the data for the ith column - function sortByIndex(index, desc) { - var key = cols[index].key, - sorter = function(a, b) { - a = a.data[key]; - b = b.data[key]; - return a < b ? -1 : a > b ? 1 : 0; - }, - finalSorter = sorter, - tableBody = document.querySelector('.coverage-summary tbody'), - rowNodes = tableBody.querySelectorAll('tr'), - rows = [], - i; - - if (desc) { - finalSorter = function(a, b) { - return -1 * sorter(a, b); - }; - } - - for (i = 0; i < rowNodes.length; i += 1) { - rows.push(rowNodes[i]); - tableBody.removeChild(rowNodes[i]); - } - - rows.sort(finalSorter); - - for (i = 0; i < rows.length; i += 1) { - tableBody.appendChild(rows[i]); - } - } - // removes sort indicators for current column being sorted - function removeSortIndicators() { - var col = getNthColumn(currentSort.index), - cls = col.className; - - cls = cls.replace(/ sorted$/, '').replace(/ sorted-desc$/, ''); - col.className = cls; - } - // adds sort indicators for current column being sorted - function addSortIndicators() { - getNthColumn(currentSort.index).className += currentSort.desc - ? ' sorted-desc' - : ' sorted'; - } - // adds event listeners for all sorter widgets - function enableUI() { - var i, - el, - ithSorter = function ithSorter(i) { - var col = cols[i]; - - return function() { - var desc = col.defaultDescSort; - - if (currentSort.index === i) { - desc = !currentSort.desc; - } - sortByIndex(i, desc); - removeSortIndicators(); - currentSort.index = i; - currentSort.desc = desc; - addSortIndicators(); - }; - }; - for (i = 0; i < cols.length; i += 1) { - if (cols[i].sortable) { - // add the click event handler on the th so users - // dont have to click on those tiny arrows - el = getNthColumn(i).querySelector('.sorter').parentElement; - if (el.addEventListener) { - el.addEventListener('click', ithSorter(i)); - } else { - el.attachEvent('onclick', ithSorter(i)); - } - } - } - } - // adds sorting functionality to the UI - return function() { - if (!getTable()) { - return; - } - cols = loadColumns(); - loadData(); - addSearchBox(); - addSortIndicators(); - enableUI(); - }; -})(); - -window.addEventListener('load', addSorting); diff --git a/coverage/lcov-report/time-utils.ts.html b/coverage/lcov-report/time-utils.ts.html deleted file mode 100644 index 58709ca..0000000 --- a/coverage/lcov-report/time-utils.ts.html +++ /dev/null @@ -1,214 +0,0 @@ - - - - - - Code coverage report for time-utils.ts - - - - - - - - - -
-
-

All files time-utils.ts

-
- -
- 100% - Statements - 16/16 -
- - -
- 100% - Branches - 0/0 -
- - -
- 100% - Functions - 6/6 -
- - -
- 100% - Lines - 16/16 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -441x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -5x -5x -5x -  -  -5x -  -  -  -1x -5x -5x -5x -5x -5x -  -5x -5x -  -20x -  -  -5x -  - 
export const TimePattern = {
-  HH_MM_SS: 'HH:MM:SS',
-  MM_SS: 'MM:SS',
-  MM_SS_MS: 'MM:SS.MS',
-} as const;
- 
-interface TimeDetails {
-  hours: number;
-  minutes: number;
-  seconds: number;
-  milliseconds: number;
-}
- 
-interface PatternRule {
-  pattern: string;
-  routine: (timeDetails: TimeDetails) => string;
-}
- 
-const patterns: PatternRule[] = [
-  { pattern: 'HH', routine: ({ hours }) => String(hours).padStart(2, '0') },
-  { pattern: 'MM', routine: ({ minutes }) => String(minutes).padStart(2, '0') },
-  { pattern: 'SS', routine: ({ seconds }) => String(seconds).padStart(2, '0') },
-  {
-    pattern: 'MS',
-    routine: ({ milliseconds }) => String(milliseconds).padStart(3, '0'),
-  },
-];
- 
-export const formatTime = (timeInMS: number, pattern: string): string => {
-  const milliseconds = Math.floor(timeInMS % 1000);
-  const seconds = Math.floor((timeInMS / 1000) % 60);
-  const minutes = Math.floor(Math.floor(timeInMS / 1000 / 60) % 60);
-  const hours = Math.floor((Math.floor(timeInMS / 1000 / 60) / 60) % 24);
-  const timeDetails: TimeDetails = { hours, minutes, seconds, milliseconds };
- 
-  let result = pattern;
-  patterns.forEach(
-    ({ pattern: currentPattern, routine }) =>
-      (result = result.replace(currentPattern, routine(timeDetails)))
-  );
- 
-  return result;
-};
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/token.ts.html b/coverage/lcov-report/token.ts.html deleted file mode 100644 index f183751..0000000 --- a/coverage/lcov-report/token.ts.html +++ /dev/null @@ -1,91 +0,0 @@ - - - - - - Code coverage report for token.ts - - - - - - - - - -
-
-

All files token.ts

-
- -
- 100% - Statements - 3/3 -
- - -
- 100% - Branches - 0/0 -
- - -
- 100% - Functions - 1/1 -
- - -
- 100% - Lines - 2/2 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -31x -13x - 
let uniqueId = 0;
-export const getUniqueId = (): number => uniqueId++;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov.info b/coverage/lcov.info deleted file mode 100644 index abb35df..0000000 --- a/coverage/lcov.info +++ /dev/null @@ -1,50 +0,0 @@ -TN: -SF:src/time-utils.ts -FN:20,(anonymous_0) -FN:21,(anonymous_1) -FN:22,(anonymous_2) -FN:25,(anonymous_3) -FN:29,(anonymous_4) -FN:38,(anonymous_5) -FNF:6 -FNH:6 -FNDA:5,(anonymous_0) -FNDA:5,(anonymous_1) -FNDA:5,(anonymous_2) -FNDA:5,(anonymous_3) -FNDA:5,(anonymous_4) -FNDA:20,(anonymous_5) -DA:1,1 -DA:19,1 -DA:20,5 -DA:21,5 -DA:22,5 -DA:25,5 -DA:29,1 -DA:30,5 -DA:31,5 -DA:32,5 -DA:33,5 -DA:34,5 -DA:36,5 -DA:37,5 -DA:39,20 -DA:42,5 -LF:16 -LH:16 -BRF:0 -BRH:0 -end_of_record -TN: -SF:src/token.ts -FN:2,(anonymous_0) -FNF:1 -FNH:1 -FNDA:13,(anonymous_0) -DA:1,1 -DA:2,13 -LF:2 -LH:2 -BRF:0 -BRH:0 -end_of_record diff --git a/dist/bundle-report.json b/dist/bundle-report.json deleted file mode 100644 index 6ba643d..0000000 --- a/dist/bundle-report.json +++ /dev/null @@ -1 +0,0 @@ -[{"label":"three-utils.min.js","isAsset":true,"statSize":8242,"groups":[{"label":"dist","path":"./dist","statSize":8242,"groups":[{"id":366,"label":"index.js + 7 modules (concatenated)","path":"./dist/index.js + 7 modules (concatenated)","statSize":8242,"parsedSize":0,"gzipSize":0,"concatenated":true,"groups":[{"label":"dist","path":"./dist/index.js + 7 modules (concatenated)/dist","statSize":8242,"groups":[{"id":null,"label":"index.js","path":"./dist/index.js + 7 modules (concatenated)/dist/index.js","statSize":342,"parsedSize":0,"gzipSize":0,"inaccurateSizes":true},{"id":null,"label":"callback-utils.js","path":"./dist/index.js + 7 modules (concatenated)/dist/callback-utils.js","statSize":1408,"parsedSize":0,"gzipSize":0,"inaccurateSizes":true},{"id":null,"label":"dispose-utils.js","path":"./dist/index.js + 7 modules (concatenated)/dist/dispose-utils.js","statSize":777,"parsedSize":0,"gzipSize":0,"inaccurateSizes":true},{"id":null,"label":"object-utils.js","path":"./dist/index.js + 7 modules (concatenated)/dist/object-utils.js","statSize":2889,"parsedSize":0,"gzipSize":0,"inaccurateSizes":true},{"id":null,"label":"time-utils.js","path":"./dist/index.js + 7 modules (concatenated)/dist/time-utils.js","statSize":1037,"parsedSize":0,"gzipSize":0,"inaccurateSizes":true},{"id":null,"label":"token.js","path":"./dist/index.js + 7 modules (concatenated)/dist/token.js","statSize":63,"parsedSize":0,"gzipSize":0,"inaccurateSizes":true},{"id":null,"label":"vector3-utils.js","path":"./dist/index.js + 7 modules (concatenated)/dist/vector3-utils.js","statSize":167,"parsedSize":0,"gzipSize":0,"inaccurateSizes":true},{"id":null,"label":"geom-utils.js","path":"./dist/index.js + 7 modules (concatenated)/dist/geom-utils.js","statSize":1559,"parsedSize":0,"gzipSize":0,"inaccurateSizes":true}],"parsedSize":0,"gzipSize":0,"inaccurateSizes":true}]}],"parsedSize":0,"gzipSize":0}],"isInitialByEntrypoint":{"main":true}}] \ No newline at end of file From 376a834e9e13693e3265128b11293fcaa3500a05 Mon Sep 17 00:00:00 2001 From: Krisztian Somoracz Date: Thu, 16 Oct 2025 00:06:24 +0200 Subject: [PATCH 07/20] fix: update Husky hooks to remove deprecated configuration - Remove deprecated husky.sh sourcing from hook files - Simplify hook scripts for Husky v9+ compatibility - Maintain pre-commit linting and testing functionality - Keep commit message validation with commitlint --- .husky/commit-msg | 3 --- .husky/pre-commit | 3 --- 2 files changed, 6 deletions(-) diff --git a/.husky/commit-msg b/.husky/commit-msg index 2981178..8fe1e0a 100755 --- a/.husky/commit-msg +++ b/.husky/commit-msg @@ -1,4 +1 @@ -#!/usr/bin/env sh -. "$(dirname -- "$0")/_/husky.sh" - npx --no -- commitlint --edit ${1} \ No newline at end of file diff --git a/.husky/pre-commit b/.husky/pre-commit index 2f2baa3..8c83e28 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1,4 +1 @@ -#!/usr/bin/env sh -. "$(dirname -- "$0")/_/husky.sh" - npm run lint && npm run test \ No newline at end of file From 2aea09f06961102ec678b88e4c7bc83a2086a924 Mon Sep 17 00:00:00 2001 From: Krisztian Somoracz Date: Thu, 16 Oct 2025 00:11:00 +0200 Subject: [PATCH 08/20] feat: finalize v2.0.0 release with documentation and publish config - Bump version to 2.0.0 reflecting major modernization - Add TypeDoc configuration for automatic documentation generation - Configure typedoc-plugin-markdown for enhanced docs - Create .npmignore to exclude development files from package - Add docs generation to prepublishOnly script - Update .gitignore to exclude generated documentation - Ensure clean package distribution with only essential files --- .gitignore | 3 +++ .npmignore | 66 +++++++++++++++++++++++++++++++++++++++++++++++ package-lock.json | 18 +++++++++++-- package.json | 6 +++-- typedoc.json | 11 ++++++++ 5 files changed, 100 insertions(+), 4 deletions(-) create mode 100644 .npmignore create mode 100644 typedoc.json diff --git a/.gitignore b/.gitignore index b71b664..cd10b09 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,9 @@ yarn-error.log* build/ *.tsbuildinfo +# Documentation (generated) +docs/ + # Testing coverage/ .nyc_output diff --git a/.npmignore b/.npmignore new file mode 100644 index 0000000..3db1404 --- /dev/null +++ b/.npmignore @@ -0,0 +1,66 @@ +# Development files +src/ +.github/ +.husky/ + +# Configuration files +tsconfig.json +webpack.config.js +jest.config.js +babel.config.json +eslint.config.mjs +.prettierrc +commitlint.config.cjs +typedoc.json + +# Test and coverage +src/__tests__/ +coverage/ +*.test.ts + +# Build artifacts (except dist/) +build/ +*.tsbuildinfo +bundle-report.json + +# Development dependencies +node_modules/ +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Editor and OS +.vscode/ +.idea/ +*.swp +*.swo +*~ +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes +ehthumbs.db +Thumbs.db + +# Environment +.env +.env.local +.env.development.local +.env.test.local +.env.production.local + +# Logs +logs +*.log + +# Optional caches +.npm +.eslintcache + +# Documentation (generated) +docs/ + +# Git +.git/ +.gitignore \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 67c2a9c..ce0076e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@newkrok/three-utils", - "version": "1.1.0", + "version": "2.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@newkrok/three-utils", - "version": "1.1.0", + "version": "2.0.0", "license": "MIT", "devDependencies": { "@babel/preset-env": "^7.26.0", @@ -33,6 +33,7 @@ "ts-loader": "^9.5.2", "ts-node": "^10.9.2", "typedoc": "^0.28.1", + "typedoc-plugin-markdown": "^4.2.12", "typescript": "^5.7.3", "webpack": "^5.97.1", "webpack-bundle-analyzer": "^4.10.2", @@ -12710,6 +12711,19 @@ "typescript": "5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x || 5.5.x || 5.6.x || 5.7.x || 5.8.x || 5.9.x" } }, + "node_modules/typedoc-plugin-markdown": { + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/typedoc-plugin-markdown/-/typedoc-plugin-markdown-4.9.0.tgz", + "integrity": "sha512-9Uu4WR9L7ZBgAl60N/h+jqmPxxvnC9nQAlnnO/OujtG2ubjnKTVUFY1XDhcMY+pCqlX3N2HsQM2QTYZIU9tJuw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "typedoc": "0.28.x" + } + }, "node_modules/typescript": { "version": "5.9.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", diff --git a/package.json b/package.json index 7de6287..da03320 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@newkrok/three-utils", - "version": "1.1.0", + "version": "2.0.0", "type": "module", "description": "Three.js-based utility library providing essential tools for THREE.js applications including assets loading, audio management, geometry utilities, and more.", "main": "./dist/index.js", @@ -55,7 +55,8 @@ "homepage": "https://github.com/NewKrok/three-utils#readme", "scripts": { "build": "rimraf dist && tsc && webpack --config webpack.config.js", - "prepublishOnly": "npm run build", + "docs": "typedoc", + "prepublishOnly": "npm run build && npm run docs", "test": "jest", "test:watch": "jest --watch", "lint": "eslint src", @@ -89,6 +90,7 @@ "ts-loader": "^9.5.2", "ts-node": "^10.9.2", "typedoc": "^0.28.1", + "typedoc-plugin-markdown": "^4.2.12", "typescript": "^5.7.3", "webpack": "^5.97.1", "webpack-bundle-analyzer": "^4.10.2", diff --git a/typedoc.json b/typedoc.json new file mode 100644 index 0000000..f85cd40 --- /dev/null +++ b/typedoc.json @@ -0,0 +1,11 @@ +{ + "entryPoints": ["src/index.ts"], + "out": "docs", + "excludePrivate": true, + "includeVersion": true, + "name": "@newkrok/three-utils", + "readme": "README.md", + "theme": "default", + "excludeExternals": true, + "plugin": ["typedoc-plugin-markdown"] +} \ No newline at end of file From 6f97fe8cc658011e9f5a3156a4f0fb0cb665aac4 Mon Sep 17 00:00:00 2001 From: Krisztian Somoracz Date: Thu, 16 Oct 2025 00:12:24 +0200 Subject: [PATCH 09/20] fix: clean up npm package by moving bundle report outside dist - Move webpack bundle report to project root instead of dist folder - Update .npmignore to exclude bundle-report.json from root - Reduce npm package size from 7.9kB to 7.5kB - Ensure only essential files are included in published package --- .npmignore | 1 + webpack.config.js | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.npmignore b/.npmignore index 3db1404..770d296 100644 --- a/.npmignore +++ b/.npmignore @@ -22,6 +22,7 @@ coverage/ build/ *.tsbuildinfo bundle-report.json +dist/bundle-report.json # Development dependencies node_modules/ diff --git a/webpack.config.js b/webpack.config.js index 04d4bbb..75e9de0 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -52,7 +52,7 @@ export default { plugins: [ new BundleAnalyzerPlugin({ analyzerMode: 'json', - reportFilename: 'bundle-report.json', + reportFilename: '../bundle-report.json', openAnalyzer: false, sourceType: 'module', }), From 594c344209b0a9225d0d45415a67f900cc3363dc Mon Sep 17 00:00:00 2001 From: Krisztian Somoracz Date: Thu, 16 Oct 2025 00:16:23 +0200 Subject: [PATCH 10/20] feat: add comprehensive GitHub Actions workflows for CI/CD - Add lint.yml for isolated linting on pull requests - Add bundle-size-check.yml for tracking bundle size changes - Add circular-dependencies.yml using madge for dependency analysis - Add publish-npm.yml for automated NPM publishing on releases - Add typedoc.yml for automated documentation deployment - Add codeql-analysis.yml for security vulnerability scanning - Update all workflows to use Node.js 20 and latest GitHub Actions - Configure proper permissions and caching for optimal performance --- .github/workflows/bundle-size-check.yml | 43 ++++++++++++++++++ .github/workflows/circular-dependencies.yml | 28 ++++++++++++ .github/workflows/codeql-analysis.yml | 39 +++++++++++++++++ .github/workflows/lint.yml | 23 ++++++++++ .github/workflows/publish-npm.yml | 35 +++++++++++++++ .github/workflows/typedoc.yml | 48 +++++++++++++++++++++ typedoc.json | 22 ++++++---- 7 files changed, 229 insertions(+), 9 deletions(-) create mode 100644 .github/workflows/bundle-size-check.yml create mode 100644 .github/workflows/circular-dependencies.yml create mode 100644 .github/workflows/codeql-analysis.yml create mode 100644 .github/workflows/lint.yml create mode 100644 .github/workflows/publish-npm.yml create mode 100644 .github/workflows/typedoc.yml diff --git a/.github/workflows/bundle-size-check.yml b/.github/workflows/bundle-size-check.yml new file mode 100644 index 0000000..4e11204 --- /dev/null +++ b/.github/workflows/bundle-size-check.yml @@ -0,0 +1,43 @@ +name: Bundle Size Check + +on: + pull_request: + branches: + - master + - v2 + +jobs: + analyze-bundle: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + cache: 'npm' + + - name: Install dependencies + run: npm ci + + - name: Build project + run: npm run build + + - name: Generate bundle report + run: | + cat bundle-report.json + + - name: Post bundle size comment + uses: marocchino/sticky-pull-request-comment@v2 + with: + token: ${{ secrets.GITHUB_TOKEN }} + header: bundle-size + message: | + ## Bundle Size Report + + ```json + $(cat bundle-report.json) + ``` \ No newline at end of file diff --git a/.github/workflows/circular-dependencies.yml b/.github/workflows/circular-dependencies.yml new file mode 100644 index 0000000..f91fde7 --- /dev/null +++ b/.github/workflows/circular-dependencies.yml @@ -0,0 +1,28 @@ +name: Circular Dependencies Testing + +on: + pull_request: + branches: + - master + - v2 + +jobs: + check-circular: + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: 'npm' + - name: Install dependencies + run: npm ci + - name: Check circular dependencies + run: npx madge --circular src \ No newline at end of file diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml new file mode 100644 index 0000000..2d92aa5 --- /dev/null +++ b/.github/workflows/codeql-analysis.yml @@ -0,0 +1,39 @@ +name: CodeQL Analysis + +on: + pull_request: + branches: + - master + - v2 + push: + branches: + - master + - v2 + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + + strategy: + matrix: + language: [ 'javascript' ] + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: ${{ matrix.language }} + + - name: Autobuild + uses: github/codeql-action/autobuild@v2 + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 \ No newline at end of file diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 0000000..d4947e1 --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,23 @@ +name: Lint Testing + +on: + pull_request: + branches: + - master + - v2 + +jobs: + lint: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: 'npm' + - name: Install dependencies + run: npm ci + - name: Run ESLint + run: npm run lint \ No newline at end of file diff --git a/.github/workflows/publish-npm.yml b/.github/workflows/publish-npm.yml new file mode 100644 index 0000000..9eef3e8 --- /dev/null +++ b/.github/workflows/publish-npm.yml @@ -0,0 +1,35 @@ +name: Publish Package to npm + +on: + release: + types: [published] # Trigger only when a release is published + +jobs: + build-and-publish: + runs-on: ubuntu-latest # Use the latest Ubuntu runner + permissions: + contents: read # Allow reading repository content + steps: + - name: Checkout code + uses: actions/checkout@v4 # Action to check out the repository code + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' # Updated Node.js version + registry-url: 'https://registry.npmjs.org/' # Point to the npm registry + cache: 'npm' + + - name: Install dependencies + run: npm ci # Use 'ci' for clean installs in CI + + - name: Run tests + run: npm test # Ensure tests pass before publishing + + - name: Build package + run: npm run build # Run your build script + + - name: Publish to npm + run: npm publish --access public # Publish with public access for scoped packages + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} # Use the secret token for authentication \ No newline at end of file diff --git a/.github/workflows/typedoc.yml b/.github/workflows/typedoc.yml new file mode 100644 index 0000000..2faab4d --- /dev/null +++ b/.github/workflows/typedoc.yml @@ -0,0 +1,48 @@ +name: Generate and Deploy Typedoc + +on: + push: + branches: + - master + - v2 + pull_request: + branches: + - master + - v2 + +jobs: + build: + runs-on: ubuntu-latest + permissions: + contents: read + pages: write + id-token: write + + steps: + - name: Check out repository + uses: actions/checkout@v4 + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: 'npm' + + - name: Install dependencies + run: npm ci + + - name: Generate Typedoc documentation + run: npm run docs + + - name: Create docs directory if not exists + run: mkdir -p docs + + - name: Disable Jekyll + run: echo "" > docs/.nojekyll + + - name: Deploy to GitHub Pages + if: github.ref == 'refs/heads/master' || github.ref == 'refs/heads/v2' + uses: peaceiris/actions-gh-pages@v3 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./docs \ No newline at end of file diff --git a/typedoc.json b/typedoc.json index f85cd40..603b7eb 100644 --- a/typedoc.json +++ b/typedoc.json @@ -1,11 +1,15 @@ { - "entryPoints": ["src/index.ts"], - "out": "docs", - "excludePrivate": true, - "includeVersion": true, - "name": "@newkrok/three-utils", - "readme": "README.md", - "theme": "default", - "excludeExternals": true, - "plugin": ["typedoc-plugin-markdown"] + "entryPoints": [ + "src/index.ts" + ], + "out": "docs", + "excludePrivate": true, + "includeVersion": true, + "name": "@newkrok/three-utils", + "readme": "README.md", + "theme": "default", + "excludeExternals": true, + "plugin": [ + "typedoc-plugin-markdown" + ] } \ No newline at end of file From 0c3b335b8b17394d6bfec6195204dc78d6827053 Mon Sep 17 00:00:00 2001 From: Krisztian Somoracz Date: Thu, 16 Oct 2025 21:19:13 +0200 Subject: [PATCH 11/20] fix: resolve GitHub Pages deployment permissions issue - Update TypeDoc workflow to use contents: write permission - Upgrade to peaceiris/actions-gh-pages@v4 for better compatibility - Add explicit user credentials for github-actions[bot] - Remove redundant Jekyll disable step (handled by action) - Enable proper GitHub Pages deployment from v2 and master branches --- .github/workflows/typedoc.yml | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/.github/workflows/typedoc.yml b/.github/workflows/typedoc.yml index 2faab4d..84f4b68 100644 --- a/.github/workflows/typedoc.yml +++ b/.github/workflows/typedoc.yml @@ -14,7 +14,7 @@ jobs: build: runs-on: ubuntu-latest permissions: - contents: read + contents: write pages: write id-token: write @@ -34,15 +34,12 @@ jobs: - name: Generate Typedoc documentation run: npm run docs - - name: Create docs directory if not exists - run: mkdir -p docs - - - name: Disable Jekyll - run: echo "" > docs/.nojekyll - - name: Deploy to GitHub Pages if: github.ref == 'refs/heads/master' || github.ref == 'refs/heads/v2' - uses: peaceiris/actions-gh-pages@v3 + uses: peaceiris/actions-gh-pages@v4 with: github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: ./docs \ No newline at end of file + publish_dir: ./docs + enable_jekyll: false + user_name: 'github-actions[bot]' + user_email: 'github-actions[bot]@users.noreply.github.com' \ No newline at end of file From 4dff0fd589d692696ccedf8eac424da2e11d38e0 Mon Sep 17 00:00:00 2001 From: Krisztian Somoracz Date: Thu, 16 Oct 2025 21:20:27 +0200 Subject: [PATCH 12/20] fix: optimize TypeDoc workflow for push events only - Remove pull_request trigger to avoid unnecessary docs generation - Focus on master and v2 branch deployments only - Reduce GitHub Actions usage while maintaining functionality --- .github/workflows/typedoc.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/typedoc.yml b/.github/workflows/typedoc.yml index 84f4b68..b828792 100644 --- a/.github/workflows/typedoc.yml +++ b/.github/workflows/typedoc.yml @@ -5,10 +5,6 @@ on: branches: - master - v2 - pull_request: - branches: - - master - - v2 jobs: build: From 1a272fdeec043de26e2ba522d538de872f96190d Mon Sep 17 00:00:00 2001 From: Krisztian Somoracz Date: Thu, 16 Oct 2025 21:31:10 +0200 Subject: [PATCH 13/20] docs: enhance README with comprehensive structure and examples - Add professional badges (GitHub Actions, NPM, Bundle Size) - Add detailed Features section with all utility modules - Add Live Demo section with 'Coming Soon' placeholder - Add comprehensive Installation section (NPM + CDN) - Add detailed Usage examples with multiple import patterns - Add modular import examples for tree-shaking - Add Asset/Audio module usage examples - Add Used In section referencing three-game project - Add Contributing and License sections - Follow structure similar to three-particles repository --- README.md | 122 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 117 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index f8809ff..7688e67 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,121 @@ # THREE Utils -THREE JS related utils +[![Run Tests](https://github.com/NewKrok/three-utils/actions/workflows/test.yml/badge.svg)](https://github.com/NewKrok/three-utils/actions/workflows/test.yml) +[![NPM Version](https://img.shields.io/npm/v/@newkrok/three-utils)](https://www.npmjs.com/package/@newkrok/three-utils) +[![NPM Downloads](https://img.shields.io/npm/dm/@newkrok/three-utils)](https://www.npmjs.com/package/@newkrok/three-utils) +[![Bundle Size](https://img.shields.io/bundlephobia/minzip/@newkrok/three-utils)](https://bundlephobia.com/package/@newkrok/three-utils) -Used in my ThreeJS projects: -- https://github.com/NewKrok/three-game +Three.js-based utility library providing essential tools for THREE.js applications including assets loading, audio management, geometry utilities, and more. -# Install -**npm install @newkrok/three-utils --save** +## Features + +• **Asset Management** - Streamlined loading and management of 3D models, textures, and other assets +• **Audio Integration** - Easy-to-use audio management for 3D environments +• **Geometry Utilities** - Helper functions for geometric calculations and operations +• **Object Utilities** - Deep object manipulation, merging, and comparison tools +• **Time Utilities** - Time formatting and management functions +• **Vector3 Utilities** - Enhanced Vector3 operations and calculations +• **Callback Utilities** - Advanced callback management and throttling +• **Dispose Utilities** - Memory management and cleanup helpers +• **Token Utilities** - Unique ID generation and token management +• **TypeScript Support** - Full TypeScript definitions included +• **Modular Exports** - Import only what you need for optimal bundle size + +## Live Demo & Examples + +🚀 **Coming Soon** - Interactive examples and live demonstrations + +## Installation + +### NPM + +```bash +npm install @newkrok/three-utils +``` + +### CDN (Browser) + +Include the script directly in your HTML: + +```html + + + +``` + +## Usage + +### Basic Import + +```typescript +import { + CallbackUtils, + DisposeUtils, + ObjectUtils, + TimeUtils, + TokenUtils, + Vector3Utils, + GeomUtils +} from '@newkrok/three-utils'; + +// Generate a unique ID +const uniqueId = TokenUtils.getUniqueId(); + +// Format time display +const formattedTime = TimeUtils.formatTime(65432); // "01:05" + +// Deep merge objects +const merged = ObjectUtils.deepMerge(obj1, obj2); + +// Vector3 operations +const absVector = Vector3Utils.absVector3(someVector); +``` + +### Modular Import + +```typescript +// Import specific modules only +import { CallbackUtils } from '@newkrok/three-utils'; +import { GeomUtils } from '@newkrok/three-utils'; + +// Use callback throttling +CallbackUtils.callWithReducer('myKey', myFunction, 16); // ~60fps + +// Check if point is in triangle +const isInside = GeomUtils.isPointInATriangle(point, triangle); +``` + +### Asset Loading + +```typescript +import { Assets } from '@newkrok/three-utils/assets'; + +// Load 3D models, textures, and other assets +// (See API documentation for detailed usage) +``` + +### Audio Management + +```typescript +import { Audio } from '@newkrok/three-utils/audio'; + +// Manage 3D audio in your Three.js scenes +// (See API documentation for detailed usage) +``` + +## Used In + +This utility library is actively used in various Three.js projects: +- [Three Game](https://github.com/NewKrok/three-game) - 3D game development framework + +## Documentation + +Automatically generated TypeDoc: [https://newkrok.github.io/three-utils/](https://newkrok.github.io/three-utils/) + +## Contributing + +Contributions are welcome! Please feel free to submit a Pull Request. + +## License + +MIT © [Istvan Krisztian Somoracz](https://github.com/NewKrok) From 4fbabdf847b9a5965bcbb1960977d84db768de4c Mon Sep 17 00:00:00 2001 From: Krisztian Somoracz Date: Thu, 16 Oct 2025 21:43:15 +0200 Subject: [PATCH 14/20] feat: convert audio system to typescript and integrate with assets - converted JavaScript audio implementation to TypeScript with proper types - added complete audio functionality (playAudio, stopAudio, volume controls) - implemented registerAudioBuffer and getAudioBuffer in assets.ts - added proper TypeScript interfaces for AudioConfig, PlayAudioParams, AudioCacheEntry - fixed module exports and imports for proper ES module resolution - integrated audio and assets modules into main exports - applied code formatting with prettier - build now completes successfully without errors --- dist/assets/assets.d.ts | 2 + dist/assets/assets.d.ts.map | 2 +- dist/assets/assets.js | 15 +++- dist/audio/audio.d.ts | 37 +++++++- dist/audio/audio.d.ts.map | 2 +- dist/audio/audio.js | 117 ++++++++++++++++++++++-- dist/index.d.ts | 2 + dist/index.d.ts.map | 2 +- dist/index.js | 2 + dist/three-utils.min.js | 2 +- src/assets/assets.ts | 21 ++++- src/audio/audio.ts | 175 ++++++++++++++++++++++++++++++++++-- src/index.ts | 2 + 13 files changed, 355 insertions(+), 26 deletions(-) diff --git a/dist/assets/assets.d.ts b/dist/assets/assets.d.ts index 5ddc9e9..001fd74 100644 --- a/dist/assets/assets.d.ts +++ b/dist/assets/assets.d.ts @@ -1,3 +1,5 @@ export declare const registerTexture: (id: string, texture: any) => void; export declare const getTexture: (id: string) => any; +export declare const registerAudioBuffer: (id: string, audioBuffer: AudioBuffer) => void; +export declare const getAudioBuffer: (id: string) => AudioBuffer | null; //# sourceMappingURL=assets.d.ts.map \ No newline at end of file diff --git a/dist/assets/assets.d.ts.map b/dist/assets/assets.d.ts.map index 75cc731..4d841a7 100644 --- a/dist/assets/assets.d.ts.map +++ b/dist/assets/assets.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"assets.d.ts","sourceRoot":"","sources":["../../src/assets/assets.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,eAAe,GAAI,IAAI,MAAM,EAAE,SAAS,GAAG,KAAG,IAE1D,CAAC;AAEF,eAAO,MAAM,UAAU,GAAI,IAAI,MAAM,KAAG,GAGvC,CAAC"} \ No newline at end of file +{"version":3,"file":"assets.d.ts","sourceRoot":"","sources":["../../src/assets/assets.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,eAAe,GAAI,IAAI,MAAM,EAAE,SAAS,GAAG,KAAG,IAE1D,CAAC;AAEF,eAAO,MAAM,UAAU,GAAI,IAAI,MAAM,KAAG,GAEvC,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAAI,IAAI,MAAM,EAAE,aAAa,WAAW,KAAG,IAE1E,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,IAAI,MAAM,KAAG,WAAW,GAAG,IAEzD,CAAC"} \ No newline at end of file diff --git a/dist/assets/assets.js b/dist/assets/assets.js index a9c6045..0317d97 100644 --- a/dist/assets/assets.js +++ b/dist/assets/assets.js @@ -1,8 +1,15 @@ -// Basic assets utilities - simplified version +// Assets registry for textures and audio buffers +const textureRegistry = new Map(); +const audioBufferRegistry = new Map(); export const registerTexture = (id, texture) => { - // Implementation will be added with full assets system + textureRegistry.set(id, texture); }; export const getTexture = (id) => { - // Implementation will be added with full assets system - return null; + return textureRegistry.get(id) || null; +}; +export const registerAudioBuffer = (id, audioBuffer) => { + audioBufferRegistry.set(id, audioBuffer); +}; +export const getAudioBuffer = (id) => { + return audioBufferRegistry.get(id) || null; }; diff --git a/dist/audio/audio.d.ts b/dist/audio/audio.d.ts index 46700fd..4ab48f7 100644 --- a/dist/audio/audio.d.ts +++ b/dist/audio/audio.d.ts @@ -1,3 +1,36 @@ -export declare const registerAudioBuffer: (id: string, audioBuffer: any) => void; -export declare const getAudioBuffer: (id: string) => any; +import * as THREE from 'three'; +interface AudioConfig { + loop?: boolean; + volume?: number; + isMusic?: boolean; +} +interface PlayAudioParams { + audioId: string; + position?: THREE.Vector3; + radius?: number; + scene?: THREE.Scene; + camera?: THREE.Camera; + cacheId?: string; +} +interface AudioCacheEntry { + audio: THREE.Audio | THREE.PositionalAudio; + audioId: string; + container?: THREE.Mesh; + lastPlayedTime: number; +} +export declare const setAudioConfig: (config: Record) => void; +export declare const playAudio: ({ audioId, position, radius, scene, camera, cacheId, }: PlayAudioParams) => void; +export declare const stopAudio: (cacheId: string) => void; +export declare const getAudioCache: (cacheId: string) => AudioCacheEntry; +export declare const setMasterVolume: (masterVolume: number) => void; +export declare const setMusicVolume: (musicVolume: number) => void; +export declare const setEffectsVolume: (effectsVolume: number) => void; +declare const AudioPlayer: { + playAudio: ({ audioId, position, radius, scene, camera, cacheId, }: PlayAudioParams) => void; + stopAudio: (cacheId: string) => void; + setMasterVolume: (masterVolume: number) => void; + setMusicVolume: (musicVolume: number) => void; + setEffectsVolume: (effectsVolume: number) => void; +}; +export default AudioPlayer; //# sourceMappingURL=audio.d.ts.map \ No newline at end of file diff --git a/dist/audio/audio.d.ts.map b/dist/audio/audio.d.ts.map index 784bf78..6aa51ce 100644 --- a/dist/audio/audio.d.ts.map +++ b/dist/audio/audio.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"audio.d.ts","sourceRoot":"","sources":["../../src/audio/audio.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,mBAAmB,GAAI,IAAI,MAAM,EAAE,aAAa,GAAG,KAAG,IAElE,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,IAAI,MAAM,KAAG,GAG3C,CAAC"} \ No newline at end of file +{"version":3,"file":"audio.d.ts","sourceRoot":"","sources":["../../src/audio/audio.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,UAAU,WAAW;IACnB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,UAAU,eAAe;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,KAAK,CAAC,OAAO,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC;IACpB,MAAM,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,UAAU,eAAe;IACvB,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,KAAK,CAAC,eAAe,CAAC;IACrD,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;CACxB;AAkBD,eAAO,MAAM,cAAc,GAAI,QAAQ,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,KAAG,IAEpE,CAAC;AAEF,eAAO,MAAM,SAAS,GAAI,wDAOvB,eAAe,KAAG,IA0DpB,CAAC;AAEF,eAAO,MAAM,SAAS,GAAI,SAAS,MAAM,KAAG,IAK3C,CAAC;AAEF,eAAO,MAAM,aAAa,GAAI,SAAS,MAAM,KAAG,eAO/C,CAAC;AAgBF,eAAO,MAAM,eAAe,GAAI,cAAc,MAAM,KAAG,IAGtD,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,aAAa,MAAM,KAAG,IAGpD,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAI,eAAe,MAAM,KAAG,IAGxD,CAAC;AAEF,QAAA,MAAM,WAAW;wEAzGd,eAAe,KAAG,IAAI;yBA4DU,MAAM,KAAG,IAAI;oCA8BF,MAAM,KAAG,IAAI;kCAKf,MAAM,KAAG,IAAI;sCAKT,MAAM,KAAG,IAAI;CAW5D,CAAC;AAEF,eAAe,WAAW,CAAC"} \ No newline at end of file diff --git a/dist/audio/audio.js b/dist/audio/audio.js index 744b005..31285db 100644 --- a/dist/audio/audio.js +++ b/dist/audio/audio.js @@ -1,8 +1,113 @@ -// Basic audio utilities - simplified version -export const registerAudioBuffer = (id, audioBuffer) => { - // Implementation will be added with full audio system +import * as THREE from 'three'; +import { PositionalAudioHelper } from 'three/examples/jsm/helpers/PositionalAudioHelper.js'; +import { getAudioBuffer } from '../assets/assets.js'; +const defaultConfig = { loop: false, volume: 1, isMusic: false }; +let audioConfig = {}; +const audioCache = {}; +const coreConfig = { + masterVolume: 1, + musicVolume: 1, + effectsVolume: 1, }; -export const getAudioBuffer = (id) => { - // Implementation will be added with full audio system - return null; +export const setAudioConfig = (config) => { + audioConfig = config; }; +export const playAudio = ({ audioId, position, radius = 1, scene, camera, cacheId, }) => { + const now = Date.now(); + let audio; + if (!cacheId || !audioCache[cacheId]) { + const audioBuffer = getAudioBuffer(audioId); + if (!audioBuffer) { + console.warn(`Audio buffer not found for ID: ${audioId}`); + return; + } + const { loop, volume, isMusic } = { + ...defaultConfig, + ...audioConfig[audioId], + }; + const listener = new THREE.AudioListener(); + let container; + if (position && scene && camera) { + audio = new THREE.PositionalAudio(listener); + audio.setRefDistance(radius); + const sphere = new THREE.SphereGeometry(radius, 32, 32); + container = new THREE.Mesh(sphere); + container.visible = false; + const helper = new PositionalAudioHelper(audio, radius); + audio.add(helper); + container.position.copy(position); + container.add(audio); + scene.add(container); + camera.add(listener); + } + else { + audio = new THREE.Audio(listener); + } + audio.setBuffer(audioBuffer); + audio.setLoop(loop || false); + audio.setVolume((volume || 1) * + coreConfig.masterVolume * + (isMusic ? coreConfig.musicVolume : coreConfig.effectsVolume)); + audioCache[cacheId || audioId] = { + audio, + audioId, + container, + lastPlayedTime: now, + }; + } + else { + const { audio: cachedAudio, container } = audioCache[cacheId]; + audio = cachedAudio; + if (audio.isPlaying) + audio.stop(); + if (container && position) + container.position.copy(position); + audioCache[cacheId].lastPlayedTime = now; + } + audio.play(); +}; +export const stopAudio = (cacheId) => { + const audioEntry = getAudioCache(cacheId); + if (audioEntry.audio && audioEntry.audio.isPlaying) { + audioEntry.audio.stop(); + } +}; +export const getAudioCache = (cacheId) => { + return audioCache[cacheId] || { + audio: null, + audioId: '', + container: undefined, + lastPlayedTime: 0, + }; +}; +const updateMusicVolumes = () => { + Object.keys(audioCache).forEach((key) => { + const { audio, audioId } = getAudioCache(key); + if (audio) { + const { volume, isMusic } = { ...defaultConfig, ...audioConfig[audioId] }; + audio.setVolume((volume || 1) * + coreConfig.masterVolume * + (isMusic ? coreConfig.musicVolume : coreConfig.effectsVolume)); + } + }); +}; +export const setMasterVolume = (masterVolume) => { + coreConfig.masterVolume = masterVolume; + updateMusicVolumes(); +}; +export const setMusicVolume = (musicVolume) => { + coreConfig.musicVolume = musicVolume; + updateMusicVolumes(); +}; +export const setEffectsVolume = (effectsVolume) => { + coreConfig.effectsVolume = effectsVolume; + updateMusicVolumes(); +}; +const AudioPlayer = { + playAudio, + stopAudio, + setMasterVolume, + setMusicVolume, + setEffectsVolume, +}; +export default AudioPlayer; diff --git a/dist/index.d.ts b/dist/index.d.ts index 606e4ed..c80cacf 100644 --- a/dist/index.d.ts +++ b/dist/index.d.ts @@ -5,4 +5,6 @@ export * as TimeUtils from './time-utils.js'; export * as TokenUtils from './token.js'; export * as Vector3Utils from './vector3-utils.js'; export * as GeomUtils from './geom-utils.js'; +export * from './assets/index.js'; +export * from './audio/index.js'; //# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/dist/index.d.ts.map b/dist/index.d.ts.map index 6744c9f..3966fc5 100644 --- a/dist/index.d.ts.map +++ b/dist/index.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,aAAa,MAAM,qBAAqB,CAAC;AACrD,OAAO,KAAK,YAAY,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,WAAW,MAAM,mBAAmB,CAAC;AACjD,OAAO,KAAK,SAAS,MAAM,iBAAiB,CAAC;AAC7C,OAAO,KAAK,UAAU,MAAM,YAAY,CAAC;AACzC,OAAO,KAAK,YAAY,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,SAAS,MAAM,iBAAiB,CAAC"} \ No newline at end of file +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,aAAa,MAAM,qBAAqB,CAAC;AACrD,OAAO,KAAK,YAAY,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,WAAW,MAAM,mBAAmB,CAAC;AACjD,OAAO,KAAK,SAAS,MAAM,iBAAiB,CAAC;AAC7C,OAAO,KAAK,UAAU,MAAM,YAAY,CAAC;AACzC,OAAO,KAAK,YAAY,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,SAAS,MAAM,iBAAiB,CAAC;AAC7C,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC"} \ No newline at end of file diff --git a/dist/index.js b/dist/index.js index 25589c9..c1c5641 100644 --- a/dist/index.js +++ b/dist/index.js @@ -5,3 +5,5 @@ export * as TimeUtils from './time-utils.js'; export * as TokenUtils from './token.js'; export * as Vector3Utils from './vector3-utils.js'; export * as GeomUtils from './geom-utils.js'; +export * from './assets/index.js'; +export * from './audio/index.js'; diff --git a/dist/three-utils.min.js b/dist/three-utils.min.js index c64b562..693337d 100644 --- a/dist/three-utils.min.js +++ b/dist/three-utils.min.js @@ -1 +1 @@ -var e={d:(t,r)=>{for(var a in r)e.o(r,a)&&!e.o(t,a)&&Object.defineProperty(t,a,{enumerable:!0,get:r[a]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r:e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})}},t={};e.r(t),e.d(t,{CallLimits:()=>p,callWithReducer:()=>c,clearAllCallReducerData:()=>S,clearCallReducerData:()=>d});var r={};e.r(r),e.d(r,{deepDispose:()=>u,disposeMaterials:()=>y});var a={};e.r(a),e.d(a,{deepMerge:()=>f,getObjectDiff:()=>b,patchObject:()=>M});var s={};e.r(s),e.d(s,{TimePattern:()=>_,formatTime:()=>h});var o={};e.r(o),e.d(o,{getUniqueId:()=>P});var l={};e.r(l),e.d(l,{absVector3:()=>x});var i={};e.r(i),e.d(i,{isPointInATriangle:()=>z,sign:()=>C,yFromTriangle:()=>j});const p={NO_LIMIT:-1,CALL_1_PER_SECONDS:1e3,CALL_15_PER_SECONDS:1e3/15,CALL_30_PER_SECONDS:1e3/30,CALL_45_PER_SECONDS:1e3/45,CALL_60_PER_SECONDS:1e3/60,CALL_120_PER_SECONDS:1e3/120};let n={};const c=({id:e,callback:t,callLimit:r,elapsed:a,callbackParam:s,forceCallCount:o=!1})=>{if(!a)return;n[e]||(n[e]={lastUpdate:-1,callCount:0});const l=()=>{s?t(s):t()};if(r!==p.NO_LIMIT)if(o){const t=Math.floor(a/(1e3*r));for(;-1===n[e].lastUpdate||t>n[e].callCount;)l(),n[e].lastUpdate+=r,n[e].callCount++;n[e].lastUpdate=a}else(-1===n[e].lastUpdate||a-n[e].lastUpdate>=r)&&(l(),n[e].lastUpdate=a);else l()},d=e=>delete n[e],S=()=>{n={}},y=e=>{if(e.isMaterial){const t=e;t.map?.dispose(),t.map=null,t.dispose()}else e.forEach(y)},u=e=>{const{isMesh:t,material:r,geometry:a}=e;t?(r&&(y(r),e.material=null),a&&(a.dispose(),e.geometry=null),e.parent?.remove(e)):e.children&&(e.children.forEach(u),e.parent?.remove(e))},M=(e,t,r={skippedProperties:[],applyToFirstObject:!1})=>{const a={};return Object.keys(e).forEach(s=>{r.skippedProperties&&r.skippedProperties.includes(s)||("object"==typeof e[s]&&e[s]&&t[s]&&!Array.isArray(e[s])?a[s]=M(e[s],t[s],r):(a[s]=0===t[s]?0:!1!==t[s]&&(t[s]||e[s]),r.applyToFirstObject&&(e[s]=a[s])))}),a},f=(e,t,r={skippedProperties:[],applyToFirstObject:!1})=>{const a={};return Array.from(new Set([...Object.keys(e||{}),...Object.keys(t||{})])).forEach(s=>{r.skippedProperties&&r.skippedProperties.includes(s)||("object"==typeof e?.[s]&&e?.[s]&&t?.[s]&&!Array.isArray(e[s])?a[s]=f(e[s],t[s],r):(a[s]=0===t?.[s]?0:!1!==t?.[s]&&(t?.[s]||e?.[s]),r.applyToFirstObject&&(e[s]=a[s])))}),a},b=(e,t,r={skippedProperties:[]})=>{const a={};return Object.keys(e).forEach(s=>{if(!r.skippedProperties||!r.skippedProperties.includes(s))if("object"==typeof e[s]&&e[s]&&t[s]&&!Array.isArray(e[s])){const o=b(e[s],t[s],r);Object.keys(o).length>0&&(a[s]=o)}else{const r=0===t[s]?0:t[s]||e[s];r!==e[s]&&(a[s]=r)}}),a},_={HH_MM_SS:"HH:MM:SS",MM_SS:"MM:SS",MM_SS_MS:"MM:SS.MS"},m=[{pattern:"HH",routine:({hours:e})=>String(e).padStart(2,"0")},{pattern:"MM",routine:({minutes:e})=>String(e).padStart(2,"0")},{pattern:"SS",routine:({seconds:e})=>String(e).padStart(2,"0")},{pattern:"MS",routine:({milliseconds:e})=>String(e).padStart(3,"0")}],h=(e,t)=>{const r=Math.floor(e%1e3),a=Math.floor(e/1e3%60),s=Math.floor(Math.floor(e/1e3/60)%60),o={hours:Math.floor(Math.floor(e/1e3/60)/60%24),minutes:s,seconds:a,milliseconds:r};let l=t;return m.forEach(({pattern:e,routine:t})=>l=l.replace(e,t(o))),l};let O=0;const P=()=>O++,x=e=>(e.x=Math.abs(e.x),e.y=Math.abs(e.y),e.z=Math.abs(e.z),e),C=(e,t,r)=>(e.x-r.x)*(t.z-r.z)-(t.x-r.x)*(e.z-r.z),z=(e,t,r,a)=>{const s=C(e,t,r),o=C(e,r,a),l=C(e,a,t);return!((s<0||o<0||l<0)&&(s>0||o>0||l>0))},j=(e,t,r,a)=>{const s=(r.x-t.x)*(a.y-t.y)-(a.x-t.x)*(r.y-t.y),o=(r.x-t.x)*(a.z-t.z)-(a.x-t.x)*(r.z-t.z),l=(r.z-t.z)*(a.y-t.y)-(a.z-t.z)*(r.y-t.y),i=(r.x-t.x)*(a.z-t.z)-(a.x-t.x)*(r.z-t.z);return t.y+s/o*(e.z-t.z)-l/i*(e.x-t.x)};export{t as CallbackUtils,r as DisposeUtils,i as GeomUtils,a as ObjectUtils,s as TimeUtils,o as TokenUtils,l as Vector3Utils}; \ No newline at end of file +import{Audio as e,AudioListener as t,BufferAttribute as s,BufferGeometry as o,Line as i,LineBasicMaterial as a,MathUtils as r,Mesh as l,PositionalAudio as n,SphereGeometry as c}from"THREE";var d={d:(e,t)=>{for(var s in t)d.o(t,s)&&!d.o(e,s)&&Object.defineProperty(e,s,{enumerable:!0,get:t[s]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r:e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})}},u={};d.r(u),d.d(u,{CallLimits:()=>A,callWithReducer:()=>O,clearAllCallReducerData:()=>_,clearCallReducerData:()=>P});var p={};d.r(p),d.d(p,{deepDispose:()=>x,disposeMaterials:()=>v});var m={};d.r(m),d.d(m,{deepMerge:()=>E,getObjectDiff:()=>T,patchObject:()=>C});var f={};d.r(f),d.d(f,{TimePattern:()=>V,formatTime:()=>z});var y={};d.r(y),d.d(y,{getUniqueId:()=>k});var M={};d.r(M),d.d(M,{absVector3:()=>U});var h={};d.r(h),d.d(h,{isPointInATriangle:()=>I,sign:()=>w,yFromTriangle:()=>D});var S={};d.r(S),d.d(S,{getAudioBuffer:()=>G,getTexture:()=>B,registerAudioBuffer:()=>F,registerTexture:()=>N});var g={};d.r(g),d.d(g,{default:()=>ie,getAudioCache:()=>$,playAudio:()=>K,setAudioConfig:()=>J,setEffectsVolume:()=>oe,setMasterVolume:()=>te,setMusicVolume:()=>se,stopAudio:()=>Q});const A={NO_LIMIT:-1,CALL_1_PER_SECONDS:1e3,CALL_15_PER_SECONDS:1e3/15,CALL_30_PER_SECONDS:1e3/30,CALL_45_PER_SECONDS:1e3/45,CALL_60_PER_SECONDS:1e3/60,CALL_120_PER_SECONDS:1e3/120};let b={};const O=({id:e,callback:t,callLimit:s,elapsed:o,callbackParam:i,forceCallCount:a=!1})=>{if(!o)return;b[e]||(b[e]={lastUpdate:-1,callCount:0});const r=()=>{i?t(i):t()};if(s!==A.NO_LIMIT)if(a){const t=Math.floor(o/(1e3*s));for(;-1===b[e].lastUpdate||t>b[e].callCount;)r(),b[e].lastUpdate+=s,b[e].callCount++;b[e].lastUpdate=o}else(-1===b[e].lastUpdate||o-b[e].lastUpdate>=s)&&(r(),b[e].lastUpdate=o);else r()},P=e=>delete b[e],_=()=>{b={}},v=e=>{if(e.isMaterial){const t=e;t.map?.dispose(),t.map=null,t.dispose()}else e.forEach(v)},x=e=>{const{isMesh:t,material:s,geometry:o}=e;t?(s&&(v(s),e.material=null),o&&(o.dispose(),e.geometry=null),e.parent?.remove(e)):e.children&&(e.children.forEach(x),e.parent?.remove(e))},C=(e,t,s={skippedProperties:[],applyToFirstObject:!1})=>{const o={};return Object.keys(e).forEach(i=>{s.skippedProperties&&s.skippedProperties.includes(i)||("object"==typeof e[i]&&e[i]&&t[i]&&!Array.isArray(e[i])?o[i]=C(e[i],t[i],s):(o[i]=0===t[i]?0:!1!==t[i]&&(t[i]||e[i]),s.applyToFirstObject&&(e[i]=o[i])))}),o},E=(e,t,s={skippedProperties:[],applyToFirstObject:!1})=>{const o={};return Array.from(new Set([...Object.keys(e||{}),...Object.keys(t||{})])).forEach(i=>{s.skippedProperties&&s.skippedProperties.includes(i)||("object"==typeof e?.[i]&&e?.[i]&&t?.[i]&&!Array.isArray(e[i])?o[i]=E(e[i],t[i],s):(o[i]=0===t?.[i]?0:!1!==t?.[i]&&(t?.[i]||e?.[i]),s.applyToFirstObject&&(e[i]=o[i])))}),o},T=(e,t,s={skippedProperties:[]})=>{const o={};return Object.keys(e).forEach(i=>{if(!s.skippedProperties||!s.skippedProperties.includes(i))if("object"==typeof e[i]&&e[i]&&t[i]&&!Array.isArray(e[i])){const a=T(e[i],t[i],s);Object.keys(a).length>0&&(o[i]=a)}else{const s=0===t[i]?0:t[i]||e[i];s!==e[i]&&(o[i]=s)}}),o},V={HH_MM_SS:"HH:MM:SS",MM_SS:"MM:SS",MM_SS_MS:"MM:SS.MS"},j=[{pattern:"HH",routine:({hours:e})=>String(e).padStart(2,"0")},{pattern:"MM",routine:({minutes:e})=>String(e).padStart(2,"0")},{pattern:"SS",routine:({seconds:e})=>String(e).padStart(2,"0")},{pattern:"MS",routine:({milliseconds:e})=>String(e).padStart(3,"0")}],z=(e,t)=>{const s=Math.floor(e%1e3),o=Math.floor(e/1e3%60),i=Math.floor(Math.floor(e/1e3/60)%60),a={hours:Math.floor(Math.floor(e/1e3/60)/60%24),minutes:i,seconds:o,milliseconds:s};let r=t;return j.forEach(({pattern:e,routine:t})=>r=r.replace(e,t(a))),r};let L=0;const k=()=>L++,U=e=>(e.x=Math.abs(e.x),e.y=Math.abs(e.y),e.z=Math.abs(e.z),e),w=(e,t,s)=>(e.x-s.x)*(t.z-s.z)-(t.x-s.x)*(e.z-s.z),I=(e,t,s,o)=>{const i=w(e,t,s),a=w(e,s,o),r=w(e,o,t);return!((i<0||a<0||r<0)&&(i>0||a>0||r>0))},D=(e,t,s,o)=>{const i=(s.x-t.x)*(o.y-t.y)-(o.x-t.x)*(s.y-t.y),a=(s.x-t.x)*(o.z-t.z)-(o.x-t.x)*(s.z-t.z),r=(s.z-t.z)*(o.y-t.y)-(o.z-t.z)*(s.y-t.y),l=(s.x-t.x)*(o.z-t.z)-(o.x-t.x)*(s.z-t.z);return t.y+i/a*(e.z-t.z)-r/l*(e.x-t.x)},R=new Map,H=new Map,N=(e,t)=>{R.set(e,t)},B=e=>R.get(e)||null,F=(e,t)=>{H.set(e,t)},G=e=>H.get(e)||null;class X extends i{constructor(e,t=1,i=16,r=2){const l=new o,n=new Float32Array(3*(3*(i+2*r)+3));l.setAttribute("position",new s(n,3));const c=new a({color:65280});super(l,[new a({color:16776960}),c]),this.audio=e,this.range=t,this.divisionsInnerAngle=i,this.divisionsOuterAngle=r,this.type="PositionalAudioHelper",this.update()}update(){const e=this.audio,t=this.range,s=this.divisionsInnerAngle,o=this.divisionsOuterAngle,i=r.degToRad(e.panner.coneInnerAngle),a=r.degToRad(e.panner.coneOuterAngle),l=i/2,n=a/2;let c,d,u=0,p=0;const m=this.geometry,f=m.attributes.position;function y(e,s,o,i){const a=(s-e)/o;for(f.setXYZ(u,0,0,0),p++,c=e;c{Z=e},K=({audioId:s,position:o,radius:i=1,scene:a,camera:r,cacheId:d})=>{const u=Date.now();let p;if(d&&q[d]){const{audio:e,container:t}=q[d];p=e,p.isPlaying&&p.stop(),t&&o&&t.position.copy(o),q[d].lastPlayedTime=u}else{const m=G(s);if(!m)return;const{loop:f,volume:y,isMusic:M}={...Y,...Z[s]},h=new t;let S;if(o&&a&&r){p=new n(h),p.setRefDistance(i);const e=new c(i,32,32);S=new l(e),S.visible=!1;const t=new X(p,i);p.add(t),S.position.copy(o),S.add(p),a.add(S),r.add(h)}else p=new e(h);p.setBuffer(m),p.setLoop(f||!1),p.setVolume((y||1)*W.masterVolume*(M?W.musicVolume:W.effectsVolume)),q[d||s]={audio:p,audioId:s,container:S,lastPlayedTime:u}}p.play()},Q=e=>{const t=$(e);t.audio&&t.audio.isPlaying&&t.audio.stop()},$=e=>q[e]||{audio:null,audioId:"",container:void 0,lastPlayedTime:0},ee=()=>{Object.keys(q).forEach(e=>{const{audio:t,audioId:s}=$(e);if(t){const{volume:e,isMusic:o}={...Y,...Z[s]};t.setVolume((e||1)*W.masterVolume*(o?W.musicVolume:W.effectsVolume))}})},te=e=>{W.masterVolume=e,ee()},se=e=>{W.musicVolume=e,ee()},oe=e=>{W.effectsVolume=e,ee()},ie={playAudio:K,stopAudio:Q,setMasterVolume:te,setMusicVolume:se,setEffectsVolume:oe};export{S as AssetsUtils,g as AudioUtils,u as CallbackUtils,p as DisposeUtils,h as GeomUtils,m as ObjectUtils,f as TimeUtils,y as TokenUtils,M as Vector3Utils}; \ No newline at end of file diff --git a/src/assets/assets.ts b/src/assets/assets.ts index e2b75a6..799e3ff 100644 --- a/src/assets/assets.ts +++ b/src/assets/assets.ts @@ -1,9 +1,22 @@ -// Basic assets utilities - simplified version +// Assets registry for textures and audio buffers +const textureRegistry = new Map(); +const audioBufferRegistry = new Map(); + export const registerTexture = (id: string, texture: any): void => { - // Implementation will be added with full assets system + textureRegistry.set(id, texture); }; export const getTexture = (id: string): any => { - // Implementation will be added with full assets system - return null; + return textureRegistry.get(id) || null; +}; + +export const registerAudioBuffer = ( + id: string, + audioBuffer: AudioBuffer +): void => { + audioBufferRegistry.set(id, audioBuffer); +}; + +export const getAudioBuffer = (id: string): AudioBuffer | null => { + return audioBufferRegistry.get(id) || null; }; diff --git a/src/audio/audio.ts b/src/audio/audio.ts index 9ff7622..09e2aed 100644 --- a/src/audio/audio.ts +++ b/src/audio/audio.ts @@ -1,9 +1,172 @@ -// Basic audio utilities - simplified version -export const registerAudioBuffer = (id: string, audioBuffer: any): void => { - // Implementation will be added with full audio system +import * as THREE from 'three'; +import { PositionalAudioHelper } from 'three/examples/jsm/helpers/PositionalAudioHelper.js'; +import { getAudioBuffer } from '../assets/assets.js'; + +interface AudioConfig { + loop?: boolean; + volume?: number; + isMusic?: boolean; +} + +interface PlayAudioParams { + audioId: string; + position?: THREE.Vector3; + radius?: number; + scene?: THREE.Scene; + camera?: THREE.Camera; + cacheId?: string; +} + +interface AudioCacheEntry { + audio: THREE.Audio | THREE.PositionalAudio; + audioId: string; + container?: THREE.Mesh; + lastPlayedTime: number; +} + +interface CoreConfig { + masterVolume: number; + musicVolume: number; + effectsVolume: number; +} + +const defaultConfig: AudioConfig = { loop: false, volume: 1, isMusic: false }; +let audioConfig: Record = {}; + +const audioCache: Record = {}; +const coreConfig: CoreConfig = { + masterVolume: 1, + musicVolume: 1, + effectsVolume: 1, +}; + +export const setAudioConfig = (config: Record): void => { + audioConfig = config; +}; + +export const playAudio = ({ + audioId, + position, + radius = 1, + scene, + camera, + cacheId, +}: PlayAudioParams): void => { + const now = Date.now(); + let audio: THREE.Audio | THREE.PositionalAudio; + + if (!cacheId || !audioCache[cacheId]) { + const audioBuffer = getAudioBuffer(audioId); + if (!audioBuffer) { + console.warn(`Audio buffer not found for ID: ${audioId}`); + return; + } + + const { loop, volume, isMusic } = { + ...defaultConfig, + ...audioConfig[audioId], + }; + + const listener = new THREE.AudioListener(); + let container: THREE.Mesh | undefined; + + if (position && scene && camera) { + audio = new THREE.PositionalAudio(listener); + (audio as THREE.PositionalAudio).setRefDistance(radius); + const sphere = new THREE.SphereGeometry(radius, 32, 32); + container = new THREE.Mesh(sphere); + container.visible = false; + const helper = new PositionalAudioHelper( + audio as THREE.PositionalAudio, + radius + ); + audio.add(helper); + container.position.copy(position); + container.add(audio); + scene.add(container); + camera.add(listener); + } else { + audio = new THREE.Audio(listener); + } + + audio.setBuffer(audioBuffer); + audio.setLoop(loop || false); + audio.setVolume( + (volume || 1) * + coreConfig.masterVolume * + (isMusic ? coreConfig.musicVolume : coreConfig.effectsVolume) + ); + + audioCache[cacheId || audioId] = { + audio, + audioId, + container, + lastPlayedTime: now, + }; + } else { + const { audio: cachedAudio, container } = audioCache[cacheId]; + audio = cachedAudio; + if (audio.isPlaying) audio.stop(); + if (container && position) container.position.copy(position); + audioCache[cacheId].lastPlayedTime = now; + } + + audio.play(); +}; + +export const stopAudio = (cacheId: string): void => { + const audioEntry = getAudioCache(cacheId); + if (audioEntry.audio && audioEntry.audio.isPlaying) { + audioEntry.audio.stop(); + } +}; + +export const getAudioCache = (cacheId: string): AudioCacheEntry => { + return ( + audioCache[cacheId] || { + audio: null as any, + audioId: '', + container: undefined, + lastPlayedTime: 0, + } + ); +}; + +const updateMusicVolumes = (): void => { + Object.keys(audioCache).forEach((key) => { + const { audio, audioId } = getAudioCache(key); + if (audio) { + const { volume, isMusic } = { ...defaultConfig, ...audioConfig[audioId] }; + audio.setVolume( + (volume || 1) * + coreConfig.masterVolume * + (isMusic ? coreConfig.musicVolume : coreConfig.effectsVolume) + ); + } + }); }; -export const getAudioBuffer = (id: string): any => { - // Implementation will be added with full audio system - return null; +export const setMasterVolume = (masterVolume: number): void => { + coreConfig.masterVolume = masterVolume; + updateMusicVolumes(); }; + +export const setMusicVolume = (musicVolume: number): void => { + coreConfig.musicVolume = musicVolume; + updateMusicVolumes(); +}; + +export const setEffectsVolume = (effectsVolume: number): void => { + coreConfig.effectsVolume = effectsVolume; + updateMusicVolumes(); +}; + +const AudioPlayer = { + playAudio, + stopAudio, + setMasterVolume, + setMusicVolume, + setEffectsVolume, +}; + +export default AudioPlayer; diff --git a/src/index.ts b/src/index.ts index 25589c9..c1c5641 100644 --- a/src/index.ts +++ b/src/index.ts @@ -5,3 +5,5 @@ export * as TimeUtils from './time-utils.js'; export * as TokenUtils from './token.js'; export * as Vector3Utils from './vector3-utils.js'; export * as GeomUtils from './geom-utils.js'; +export * from './assets/index.js'; +export * from './audio/index.js'; From 74322a039dc2df4e08bf290621bc6b44d7897ba4 Mon Sep 17 00:00:00 2001 From: Krisztian Somoracz Date: Thu, 16 Oct 2025 21:49:40 +0200 Subject: [PATCH 15/20] feat: convert complete assets system to typescript - converted JavaScript assets.js to TypeScript with comprehensive type definitions - created loaders.ts with proper TypeScript implementations for all asset types - added detailed interfaces for MaterialConfig, LoadAssetsParams, and asset entries - implemented complete asset registry system with proper THREE.js types - converted all register/get functions for FBX, GLTF, texture, and audio assets - added createMaterial and applyMaterialConfig functions with type safety - converted main loadAssets function with proper async/Promise handling - updated deepDispose function to handle THREE.Object3D types properly - fixed all module imports/exports for ES module compatibility - applied code formatting with prettier - build completes successfully with full TypeScript asset system --- dist/assets/assets.d.ts | 74 +++++- dist/assets/assets.d.ts.map | 2 +- dist/assets/assets.js | 221 ++++++++++++++++- dist/assets/loaders.d.ts | 24 ++ dist/assets/loaders.d.ts.map | 1 + dist/assets/loaders.js | 172 +++++++++++++ dist/audio/audio.d.ts.map | 2 +- dist/audio/audio.js | 4 +- dist/dispose-utils.d.ts | 2 +- dist/dispose-utils.d.ts.map | 2 +- dist/three-utils.min.js | 3 +- dist/three-utils.min.js.LICENSE.txt | 6 + src/assets/assets.ts | 372 +++++++++++++++++++++++++++- src/assets/loaders.ts | 310 +++++++++++++++++++++++ src/dispose-utils.ts | 4 +- 15 files changed, 1165 insertions(+), 34 deletions(-) create mode 100644 dist/assets/loaders.d.ts create mode 100644 dist/assets/loaders.d.ts.map create mode 100644 dist/assets/loaders.js create mode 100644 dist/three-utils.min.js.LICENSE.txt create mode 100644 src/assets/loaders.ts diff --git a/dist/assets/assets.d.ts b/dist/assets/assets.d.ts index 001fd74..e5376bc 100644 --- a/dist/assets/assets.d.ts +++ b/dist/assets/assets.d.ts @@ -1,5 +1,73 @@ -export declare const registerTexture: (id: string, texture: any) => void; -export declare const getTexture: (id: string) => any; -export declare const registerAudioBuffer: (id: string, audioBuffer: AudioBuffer) => void; +import * as THREE from 'three'; +import { GLTF } from 'three/examples/jsm/loaders/GLTFLoader.js'; +interface FBXModelEntry { + id: string; + fbxModel: THREE.Group; + material?: MaterialConfig | MaterialConfig[]; +} +interface MaterialConfig { + materialType?: new (params: any) => THREE.Material; + texture?: { + id: string; + flipY?: boolean; + }; + color?: number; + alphaTest?: number; +} +interface LoadAssetsParams { + textures: Array<{ + id: string; + url: string; + }>; + gltfModels: Array<{ + id: string; + url: string; + material?: MaterialConfig | MaterialConfig[]; + }>; + fbxModels: Array<{ + id: string; + url: string; + material?: MaterialConfig | MaterialConfig[]; + }>; + fbxSkeletonAnimations: Array<{ + id: string; + url: string; + }>; + audio: Array<{ + id: string; + url: string; + }>; + onProgress?: (progress: number) => void; + verbose?: boolean; +} +export declare const registerFBXModel: ({ id, fbxModel }: { + id: string; + fbxModel: THREE.Group; +}) => void; +export declare const getFBXModel: (id: string) => THREE.Group; +export declare const registerFBXSkeletonAnimation: ({ id, fbxModel }: { + id: string; + fbxModel: THREE.Group; +}) => void; +export declare const getFBXSkeletonAnimation: (id: string) => THREE.AnimationClip; +export declare const registerGLTFModel: ({ id, gltfModel }: { + id: string; + gltfModel: GLTF; +}) => void; +export declare const getGLTFModel: (id: string) => GLTF; +export declare const registerTexture: ({ id, texture }: { + id: string; + texture: THREE.Texture; +}) => void; +export declare const getTexture: (id: string) => THREE.Texture | null; +export declare const registerAudioBuffer: ({ id, audioBuffer }: { + id: string; + audioBuffer: AudioBuffer; +}) => void; export declare const getAudioBuffer: (id: string) => AudioBuffer | null; +export declare const disposeAssets: () => void; +export declare const loadAssets: ({ textures, gltfModels, fbxModels, fbxSkeletonAnimations, audio, onProgress, verbose, }: LoadAssetsParams) => Promise<{ + fbxModels: FBXModelEntry[]; +}>; +export {}; //# sourceMappingURL=assets.d.ts.map \ No newline at end of file diff --git a/dist/assets/assets.d.ts.map b/dist/assets/assets.d.ts.map index 4d841a7..545a572 100644 --- a/dist/assets/assets.d.ts.map +++ b/dist/assets/assets.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"assets.d.ts","sourceRoot":"","sources":["../../src/assets/assets.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,eAAe,GAAI,IAAI,MAAM,EAAE,SAAS,GAAG,KAAG,IAE1D,CAAC;AAEF,eAAO,MAAM,UAAU,GAAI,IAAI,MAAM,KAAG,GAEvC,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAAI,IAAI,MAAM,EAAE,aAAa,WAAW,KAAG,IAE1E,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,IAAI,MAAM,KAAG,WAAW,GAAG,IAEzD,CAAC"} \ No newline at end of file +{"version":3,"file":"assets.d.ts","sourceRoot":"","sources":["../../src/assets/assets.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EAAE,IAAI,EAAE,MAAM,0CAA0C,CAAC;AAUhE,UAAU,aAAa;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,KAAK,CAAC,KAAK,CAAC;IACtB,QAAQ,CAAC,EAAE,cAAc,GAAG,cAAc,EAAE,CAAC;CAC9C;AAkBD,UAAU,cAAc;IACtB,YAAY,CAAC,EAAE,KAAK,MAAM,EAAE,GAAG,KAAK,KAAK,CAAC,QAAQ,CAAC;IACnD,OAAO,CAAC,EAAE;QACR,EAAE,EAAE,MAAM,CAAC;QACX,KAAK,CAAC,EAAE,OAAO,CAAC;KACjB,CAAC;IACF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,UAAU,gBAAgB;IACxB,QAAQ,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC7C,UAAU,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,cAAc,GAAG,cAAc,EAAE,CAAA;KAAE,CAAC,CAAC;IAC7F,SAAS,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,cAAc,GAAG,cAAc,EAAE,CAAA;KAAE,CAAC,CAAC;IAC5F,qBAAqB,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC1D,KAAK,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC1C,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAUD,eAAO,MAAM,gBAAgB,GAAI,kBAAkB;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,KAAK,CAAC,KAAK,CAAA;CAAE,KAAG,IAE1F,CAAC;AAEF,eAAO,MAAM,WAAW,GAAI,IAAI,MAAM,KAAG,KAAK,CAAC,KAI9C,CAAC;AAGF,eAAO,MAAM,4BAA4B,GAAI,kBAAkB;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,KAAK,CAAC,KAAK,CAAA;CAAE,KAAG,IAEtG,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAAI,IAAI,MAAM,KAAG,KAAK,CAAC,aAE1D,CAAC;AAGF,eAAO,MAAM,iBAAiB,GAAI,mBAAmB;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,IAAI,CAAA;CAAE,KAAG,IAEtF,CAAC;AAEF,eAAO,MAAM,YAAY,GAAI,IAAI,MAAM,KAAG,IAEzC,CAAC;AAGF,eAAO,MAAM,eAAe,GAAI,iBAAiB;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,KAAK,CAAC,OAAO,CAAA;CAAE,KAAG,IAEzF,CAAC;AAEF,eAAO,MAAM,UAAU,GAAI,IAAI,MAAM,KAAG,KAAK,CAAC,OAAO,GAAG,IAEvD,CAAC;AAGF,eAAO,MAAM,mBAAmB,GAAI,qBAAqB;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,WAAW,CAAA;CAAE,KAAG,IAEnG,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,IAAI,MAAM,KAAG,WAAW,GAAG,IAEzD,CAAC;AAoDF,eAAO,MAAM,aAAa,QAAO,IAahC,CAAC;AAGF,eAAO,MAAM,UAAU,GAAI,yFAQxB,gBAAgB,KAAG,OAAO,CAAC;IAAE,SAAS,EAAE,aAAa,EAAE,CAAA;CAAE,CA0IxD,CAAC"} \ No newline at end of file diff --git a/dist/assets/assets.js b/dist/assets/assets.js index 0317d97..9e423d2 100644 --- a/dist/assets/assets.js +++ b/dist/assets/assets.js @@ -1,15 +1,218 @@ -// Assets registry for textures and audio buffers -const textureRegistry = new Map(); -const audioBufferRegistry = new Map(); -export const registerTexture = (id, texture) => { - textureRegistry.set(id, texture); +import * as THREE from 'three'; +import { clone } from 'three/examples/jsm/utils/SkeletonUtils.js'; +import { deepDispose } from '../dispose-utils.js'; +import { loadAudio, loadFBXModels, loadGLTFModels, loadTextures, } from './loaders.js'; +// Asset registries +const _fbxModels = {}; +const _gltfModels = {}; +const _textures = {}; +const _audioBuffers = {}; +const fbxSkeletonAnimations = {}; +// FBX Model functions +export const registerFBXModel = ({ id, fbxModel }) => { + _fbxModels[id] = fbxModel; +}; +export const getFBXModel = (id) => { + const clonedModel = clone(_fbxModels[id]); + clonedModel.animations = [..._fbxModels[id].animations]; + return clonedModel; +}; +// FBX Skeleton Animation functions +export const registerFBXSkeletonAnimation = ({ id, fbxModel }) => { + fbxSkeletonAnimations[id] = fbxModel.animations[0]; +}; +export const getFBXSkeletonAnimation = (id) => { + return fbxSkeletonAnimations[id]; +}; +// GLTF Model functions +export const registerGLTFModel = ({ id, gltfModel }) => { + _gltfModels[id] = gltfModel; +}; +export const getGLTFModel = (id) => { + return _gltfModels[id]; +}; +// Texture functions +export const registerTexture = ({ id, texture }) => { + _textures[id] = texture; }; export const getTexture = (id) => { - return textureRegistry.get(id) || null; + return _textures[id] || null; }; -export const registerAudioBuffer = (id, audioBuffer) => { - audioBufferRegistry.set(id, audioBuffer); +// Audio Buffer functions +export const registerAudioBuffer = ({ id, audioBuffer }) => { + _audioBuffers[id] = audioBuffer; }; export const getAudioBuffer = (id) => { - return audioBufferRegistry.get(id) || null; + return _audioBuffers[id] || null; +}; +// Material helper functions +const applyMaterialConfig = ({ material, materialConfig = { texture: { id: '' }, color: 0xffffff, alphaTest: 0.5 }, }) => { + if ('map' in material) { + material.map = materialConfig?.texture?.id + ? getTexture(materialConfig.texture.id) + : null; + } + if ('alphaTest' in material) { + material.alphaTest = materialConfig?.alphaTest || 0.5; + } + if ('color' in material) { + material.color = new THREE.Color(materialConfig?.color || 0xffffff); + } +}; +const createMaterial = (materialConfig = { + materialType: undefined, + texture: { id: '', flipY: true }, + color: 0xffffff, + alphaTest: 0.5, +}) => { + let material = null; + if (materialConfig instanceof Array) { + material = materialConfig.map((config) => createMaterial(config)); + } + else if (materialConfig.materialType) { + const map = materialConfig?.texture?.id + ? getTexture(materialConfig.texture.id) + : null; + if (map) { + map.flipY = materialConfig?.texture?.flipY ?? true; + } + material = new materialConfig.materialType({ + map, + alphaTest: materialConfig.alphaTest || 0.5, + color: new THREE.Color(materialConfig?.color || 0xffffff), + }); + } + return material; +}; +// Asset disposal +export const disposeAssets = () => { + Object.entries(_textures).forEach(([key, texture]) => { + texture.dispose(); + delete _textures[key]; + }); + Object.entries(_fbxModels).forEach(([key, fbxModel]) => { + deepDispose(fbxModel); + delete _fbxModels[key]; + }); + Object.entries(_gltfModels).forEach(([key, gltfModel]) => { + deepDispose(gltfModel.scene); + delete _gltfModels[key]; + }); }; +// Main asset loading function +export const loadAssets = ({ textures, gltfModels, fbxModels, fbxSkeletonAnimations, audio, onProgress, verbose = true, }) => new Promise((resolve) => { + const result = { fbxModels: [] }; + const assetCount = textures.length + + gltfModels.length + + fbxModels.length + + fbxSkeletonAnimations.length + + audio.length; + let loadedCount = 0; + const updateProgress = () => { + loadedCount++; + onProgress && onProgress(loadedCount / assetCount); + }; + loadTextures(textures, updateProgress) + .then((loadedTextures) => { + loadedTextures.forEach((element) => { + element.texture.colorSpace = THREE.SRGBColorSpace; + registerTexture(element); + }); + if (verbose) { + console.log(`Textures(${loadedTextures.length}) are loaded...`); + } + loadGLTFModels(gltfModels, updateProgress) + .then((loadedModels) => { + loadedModels.forEach((element) => { + const createdMaterial = createMaterial(element.material); + let textureIndex = 0; + element.gltfModel.scene.traverse((child) => { + if (child.isMesh) { + const mesh = child; + mesh.castShadow = true; + mesh.receiveShadow = true; + if (mesh.material instanceof Array) { + mesh.material = createdMaterial; + } + else { + mesh.material = + createdMaterial instanceof Array + ? createdMaterial[textureIndex] + : createdMaterial || mesh.material; + } + if (!createdMaterial && element.material) { + applyMaterialConfig({ + material: mesh.material, + materialConfig: element.material instanceof Array + ? element.material[textureIndex] + : element.material, + }); + } + textureIndex++; + } + }); + registerGLTFModel(element); + }); + if (verbose) { + console.log(`GLTF Models(${loadedModels.length}) are loaded...`); + } + loadFBXModels(fbxSkeletonAnimations, updateProgress) + .then((loadedAnimations) => { + loadedAnimations.forEach((element) => { + registerFBXSkeletonAnimation(element); + }); + if (verbose) { + console.log(`FBX Skeleton Animations(${loadedAnimations.length}) are loaded...`); + } + loadFBXModels(fbxModels, updateProgress) + .then((loadedModels) => { + loadedModels.forEach((element) => { + const createdMaterial = createMaterial(element.material); + let textureIndex = 0; + element.fbxModel.traverse((child) => { + if (child.isMesh) { + const mesh = child; + mesh.castShadow = true; + mesh.receiveShadow = true; + if (mesh.material instanceof Array) { + mesh.material = createdMaterial; + } + else { + mesh.material = + createdMaterial instanceof Array + ? createdMaterial[textureIndex] + : createdMaterial || mesh.material; + } + if (!createdMaterial && element.material) { + applyMaterialConfig({ + material: mesh.material, + materialConfig: element.material instanceof Array + ? element.material[textureIndex] + : element.material, + }); + } + textureIndex++; + } + }); + registerFBXModel(element); + }); + result.fbxModels = [...loadedModels]; + if (verbose) { + console.log(`FBX Models(${loadedModels.length}) are loaded...`); + } + loadAudio(audio, updateProgress) + .then((loadedAudio) => { + loadedAudio.forEach((element) => registerAudioBuffer(element)); + if (verbose) { + console.log(`Audio files(${loadedAudio.length}) are loaded...`); + } + resolve(result); + }) + .catch((error) => console.error(`Fatal error during Audio files preloader phase: ${error}`)); + }) + .catch((error) => console.error(`Fatal error during FBX model preloader phase: ${error}`)); + }); + }); + }) + .catch((error) => console.error(`Fatal error during texture preloader phase: ${error}`)); +}); diff --git a/dist/assets/loaders.d.ts b/dist/assets/loaders.d.ts new file mode 100644 index 0000000..37d2054 --- /dev/null +++ b/dist/assets/loaders.d.ts @@ -0,0 +1,24 @@ +import * as THREE from 'three'; +import { GLTF } from 'three/examples/jsm/loaders/GLTFLoader.js'; +interface AssetLoadItem { + id: string; + url: string; +} +interface FBXModelResult extends AssetLoadItem { + fbxModel: THREE.Group; +} +interface GLTFModelResult extends AssetLoadItem { + gltfModel: GLTF; +} +interface TextureResult extends AssetLoadItem { + texture: THREE.Texture; +} +interface AudioResult extends AssetLoadItem { + audioBuffer: AudioBuffer; +} +export declare const loadGLTFModels: (list: AssetLoadItem[], onProgress: () => void) => Promise; +export declare const loadFBXModels: (list: AssetLoadItem[], onProgress: () => void) => Promise; +export declare const loadTextures: (list: AssetLoadItem[], onProgress: () => void) => Promise; +export declare const loadAudio: (list: AssetLoadItem[], onProgress: () => void) => Promise; +export {}; +//# sourceMappingURL=loaders.d.ts.map \ No newline at end of file diff --git a/dist/assets/loaders.d.ts.map b/dist/assets/loaders.d.ts.map new file mode 100644 index 0000000..d53c7c0 --- /dev/null +++ b/dist/assets/loaders.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"loaders.d.ts","sourceRoot":"","sources":["../../src/assets/loaders.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EAAc,IAAI,EAAE,MAAM,0CAA0C,CAAC;AAQ5E,UAAU,aAAa;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;CACb;AAED,UAAU,cAAe,SAAQ,aAAa;IAC5C,QAAQ,EAAE,KAAK,CAAC,KAAK,CAAC;CACvB;AAED,UAAU,eAAgB,SAAQ,aAAa;IAC7C,SAAS,EAAE,IAAI,CAAC;CACjB;AAED,UAAU,aAAc,SAAQ,aAAa;IAC3C,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC;CACxB;AAED,UAAU,WAAY,SAAQ,aAAa;IACzC,WAAW,EAAE,WAAW,CAAC;CAC1B;AAuHD,eAAO,MAAM,cAAc,GACzB,MAAM,aAAa,EAAE,EACrB,YAAY,MAAM,IAAI,KACrB,OAAO,CAAC,eAAe,EAAE,CAiB3B,CAAC;AAEF,eAAO,MAAM,aAAa,GACxB,MAAM,aAAa,EAAE,EACrB,YAAY,MAAM,IAAI,KACrB,OAAO,CAAC,cAAc,EAAE,CAwC1B,CAAC;AAEF,eAAO,MAAM,YAAY,GACvB,MAAM,aAAa,EAAE,EACrB,YAAY,MAAM,IAAI,KACrB,OAAO,CAAC,aAAa,EAAE,CA2CzB,CAAC;AAEF,eAAO,MAAM,SAAS,GACpB,MAAM,aAAa,EAAE,EACrB,YAAY,MAAM,IAAI,KACrB,OAAO,CAAC,WAAW,EAAE,CAwCvB,CAAC"} \ No newline at end of file diff --git a/dist/assets/loaders.js b/dist/assets/loaders.js new file mode 100644 index 0000000..7ca9860 --- /dev/null +++ b/dist/assets/loaders.js @@ -0,0 +1,172 @@ +import * as THREE from 'three'; +import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader.js'; +import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'; +// Loader instances +const gltfLoader = new GLTFLoader(); +const fbxLoaders = Array.from({ length: 3 }, () => ({ + loader: new FBXLoader(), + isUsed: false, +})); +let fbxLoaderQueue = []; +const textureLoaders = Array.from({ length: 3 }, () => ({ + loader: new THREE.TextureLoader(), + isUsed: false, +})); +let textureLoaderQueue = []; +const audioLoaders = Array.from({ length: 3 }, () => ({ + loader: new THREE.AudioLoader(), + isUsed: false, +})); +let audioLoaderQueue = []; +// Loader getter functions +const getFBXLoader = (onComplete) => getLoader(onComplete, fbxLoaders, fbxLoaderQueue); +const getTextureLoader = (onComplete) => getLoader(onComplete, textureLoaders, textureLoaderQueue); +const getAudioLoader = (onComplete) => getLoader(onComplete, audioLoaders, audioLoaderQueue); +const getLoader = (onComplete, loaders, loaderQueue) => { + const loader = loaders.find((entry) => !entry.isUsed); + if (loader) { + loader.isUsed = true; + onComplete(loader.loader); + } + else { + loaderQueue.push((availableLoader) => { + onComplete(availableLoader.loader); + availableLoader.isUsed = true; + }); + } +}; +// Loader release functions +const releaseFBXLoader = (loader) => releaseLoader(loader, fbxLoaders, fbxLoaderQueue); +const releaseTextureLoader = (loader) => releaseLoader(loader, textureLoaders, textureLoaderQueue); +const releaseAudioLoader = (loader) => releaseLoader(loader, audioLoaders, audioLoaderQueue); +const releaseLoader = (loader, loaders, loaderQueue) => { + const loaderObject = loaders.find((entry) => entry.loader === loader); + if (loaderObject) { + if (loaderQueue.length > 0) { + const callback = loaderQueue.shift(); + if (callback) { + callback(loaderObject); + } + } + else { + loaderObject.isUsed = false; + } + } +}; +// GLTF Model loading +const loadGLTFModelRoutine = ({ list, onElementLoaded, onComplete, onError, }) => { + if (list.length > 0) { + const { url } = list[0]; + gltfLoader.load(url, ({ scene, animations }) => { + onElementLoaded({ + ...list[0], + gltfModel: { scene, animations }, + }); + list.shift(); + loadGLTFModelRoutine({ list, onElementLoaded, onComplete, onError }); + }, undefined, (error) => onError(String(error))); + } + else { + onComplete(); + } +}; +export const loadGLTFModels = (list, onProgress) => { + const elements = []; + const onElementLoaded = (element) => { + elements.push(element); + onProgress(); + }; + const promise = new Promise((resolve, reject) => { + loadGLTFModelRoutine({ + list: [...list], // Create a copy to avoid modifying the original + onElementLoaded, + onComplete: () => resolve(elements), + onError: (error) => reject(new Error(`Something wrong happened: ${error}`)), + }); + }); + return promise; +}; +export const loadFBXModels = (list, onProgress) => { + const elements = []; + const onElementLoaded = (element) => { + elements.push(element); + onProgress(); + }; + const promise = new Promise((resolve, reject) => { + if (list.length > 0) { + const listCopy = [...list]; // Create a copy to avoid modifying the original + while (listCopy.length > 0) { + const { url, id } = listCopy[0]; + const current = listCopy[0]; + listCopy.shift(); + getFBXLoader((fbxLoader) => fbxLoader.load(url, (fbxModel) => { + onElementLoaded({ ...current, id, fbxModel }); + releaseFBXLoader(fbxLoader); + if (!fbxLoaders.some((entry) => entry.isUsed)) { + resolve(elements); + } + }, undefined, (error) => reject(new Error(`Something wrong happened with an FBX model: ${id}, url: ${url}, error: ${error}`)))); + } + } + else { + resolve([]); + } + }); + return promise; +}; +export const loadTextures = (list, onProgress) => { + const elements = []; + const onElementLoaded = (element) => { + elements.push(element); + onProgress(); + }; + const promise = new Promise((resolve, reject) => { + if (list.length > 0) { + const listCopy = [...list]; // Create a copy to avoid modifying the original + while (listCopy.length > 0) { + const { url, id } = listCopy[0]; + listCopy.shift(); + getTextureLoader((textureLoader) => textureLoader.load(url, (texture) => { + texture.wrapS = THREE.RepeatWrapping; + texture.wrapT = THREE.RepeatWrapping; + onElementLoaded({ id, url, texture }); + releaseTextureLoader(textureLoader); + if (!textureLoaders.some((entry) => entry.isUsed)) { + resolve(elements); + } + }, undefined, (error) => reject(new Error(`Something wrong happened with a texture: ${id}, url: ${url}, error: ${error}`)))); + } + } + else { + resolve([]); + } + }); + return promise; +}; +export const loadAudio = (list, onProgress) => { + const elements = []; + const onElementLoaded = (element) => { + elements.push(element); + onProgress(); + }; + const promise = new Promise((resolve, reject) => { + if (list.length > 0) { + const listCopy = [...list]; // Create a copy to avoid modifying the original + while (listCopy.length > 0) { + const { url, id } = listCopy[0]; + listCopy.shift(); + getAudioLoader((audioLoader) => audioLoader.load(url, (audioBuffer) => { + onElementLoaded({ id, url, audioBuffer }); + releaseAudioLoader(audioLoader); + if (!audioLoaders.some((entry) => entry.isUsed)) { + resolve(elements); + } + }, undefined, (error) => reject(new Error(`Something wrong happened with an audio: ${id}, url: ${url}, error: ${error}`)))); + } + } + else { + resolve([]); + } + }); + return promise; +}; diff --git a/dist/audio/audio.d.ts.map b/dist/audio/audio.d.ts.map index 6aa51ce..ac671ff 100644 --- a/dist/audio/audio.d.ts.map +++ b/dist/audio/audio.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"audio.d.ts","sourceRoot":"","sources":["../../src/audio/audio.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,UAAU,WAAW;IACnB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,UAAU,eAAe;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,KAAK,CAAC,OAAO,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC;IACpB,MAAM,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,UAAU,eAAe;IACvB,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,KAAK,CAAC,eAAe,CAAC;IACrD,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;CACxB;AAkBD,eAAO,MAAM,cAAc,GAAI,QAAQ,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,KAAG,IAEpE,CAAC;AAEF,eAAO,MAAM,SAAS,GAAI,wDAOvB,eAAe,KAAG,IA0DpB,CAAC;AAEF,eAAO,MAAM,SAAS,GAAI,SAAS,MAAM,KAAG,IAK3C,CAAC;AAEF,eAAO,MAAM,aAAa,GAAI,SAAS,MAAM,KAAG,eAO/C,CAAC;AAgBF,eAAO,MAAM,eAAe,GAAI,cAAc,MAAM,KAAG,IAGtD,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,aAAa,MAAM,KAAG,IAGpD,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAI,eAAe,MAAM,KAAG,IAGxD,CAAC;AAEF,QAAA,MAAM,WAAW;wEAzGd,eAAe,KAAG,IAAI;yBA4DU,MAAM,KAAG,IAAI;oCA8BF,MAAM,KAAG,IAAI;kCAKf,MAAM,KAAG,IAAI;sCAKT,MAAM,KAAG,IAAI;CAW5D,CAAC;AAEF,eAAe,WAAW,CAAC"} \ No newline at end of file +{"version":3,"file":"audio.d.ts","sourceRoot":"","sources":["../../src/audio/audio.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,UAAU,WAAW;IACnB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,UAAU,eAAe;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,KAAK,CAAC,OAAO,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC;IACpB,MAAM,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,UAAU,eAAe;IACvB,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,KAAK,CAAC,eAAe,CAAC;IACrD,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;CACxB;AAkBD,eAAO,MAAM,cAAc,GAAI,QAAQ,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,KAAG,IAEpE,CAAC;AAEF,eAAO,MAAM,SAAS,GAAI,wDAOvB,eAAe,KAAG,IA6DpB,CAAC;AAEF,eAAO,MAAM,SAAS,GAAI,SAAS,MAAM,KAAG,IAK3C,CAAC;AAEF,eAAO,MAAM,aAAa,GAAI,SAAS,MAAM,KAAG,eAS/C,CAAC;AAgBF,eAAO,MAAM,eAAe,GAAI,cAAc,MAAM,KAAG,IAGtD,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,aAAa,MAAM,KAAG,IAGpD,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAI,eAAe,MAAM,KAAG,IAGxD,CAAC;AAEF,QAAA,MAAM,WAAW;wEA9Gd,eAAe,KAAG,IAAI;yBA+DU,MAAM,KAAG,IAAI;oCAgCF,MAAM,KAAG,IAAI;kCAKf,MAAM,KAAG,IAAI;sCAKT,MAAM,KAAG,IAAI;CAW5D,CAAC;AAEF,eAAe,WAAW,CAAC"} \ No newline at end of file diff --git a/dist/audio/audio.js b/dist/audio/audio.js index 31285db..8af930f 100644 --- a/dist/audio/audio.js +++ b/dist/audio/audio.js @@ -73,12 +73,12 @@ export const stopAudio = (cacheId) => { } }; export const getAudioCache = (cacheId) => { - return audioCache[cacheId] || { + return (audioCache[cacheId] || { audio: null, audioId: '', container: undefined, lastPlayedTime: 0, - }; + }); }; const updateMusicVolumes = () => { Object.keys(audioCache).forEach((key) => { diff --git a/dist/dispose-utils.d.ts b/dist/dispose-utils.d.ts index 5547770..0f7582f 100644 --- a/dist/dispose-utils.d.ts +++ b/dist/dispose-utils.d.ts @@ -1,4 +1,4 @@ import * as THREE from 'three'; export declare const disposeMaterials: (material: THREE.Material | Array) => void; -export declare const deepDispose: (container: THREE.Mesh) => void; +export declare const deepDispose: (container: THREE.Object3D) => void; //# sourceMappingURL=dispose-utils.d.ts.map \ No newline at end of file diff --git a/dist/dispose-utils.d.ts.map b/dist/dispose-utils.d.ts.map index c4eb0c7..408b2be 100644 --- a/dist/dispose-utils.d.ts.map +++ b/dist/dispose-utils.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"dispose-utils.d.ts","sourceRoot":"","sources":["../src/dispose-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,eAAO,MAAM,gBAAgB,GAC3B,UAAU,KAAK,CAAC,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,KAC/C,IASF,CAAC;AAEF,eAAO,MAAM,WAAW,GAAI,WAAW,KAAK,CAAC,IAAI,KAAG,IAiBnD,CAAC"} \ No newline at end of file +{"version":3,"file":"dispose-utils.d.ts","sourceRoot":"","sources":["../src/dispose-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,eAAO,MAAM,gBAAgB,GAC3B,UAAU,KAAK,CAAC,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,KAC/C,IASF,CAAC;AAEF,eAAO,MAAM,WAAW,GAAI,WAAW,KAAK,CAAC,QAAQ,KAAG,IAiBvD,CAAC"} \ No newline at end of file diff --git a/dist/three-utils.min.js b/dist/three-utils.min.js index 693337d..d6ff931 100644 --- a/dist/three-utils.min.js +++ b/dist/three-utils.min.js @@ -1 +1,2 @@ -import{Audio as e,AudioListener as t,BufferAttribute as s,BufferGeometry as o,Line as i,LineBasicMaterial as a,MathUtils as r,Mesh as l,PositionalAudio as n,SphereGeometry as c}from"THREE";var d={d:(e,t)=>{for(var s in t)d.o(t,s)&&!d.o(e,s)&&Object.defineProperty(e,s,{enumerable:!0,get:t[s]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r:e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})}},u={};d.r(u),d.d(u,{CallLimits:()=>A,callWithReducer:()=>O,clearAllCallReducerData:()=>_,clearCallReducerData:()=>P});var p={};d.r(p),d.d(p,{deepDispose:()=>x,disposeMaterials:()=>v});var m={};d.r(m),d.d(m,{deepMerge:()=>E,getObjectDiff:()=>T,patchObject:()=>C});var f={};d.r(f),d.d(f,{TimePattern:()=>V,formatTime:()=>z});var y={};d.r(y),d.d(y,{getUniqueId:()=>k});var M={};d.r(M),d.d(M,{absVector3:()=>U});var h={};d.r(h),d.d(h,{isPointInATriangle:()=>I,sign:()=>w,yFromTriangle:()=>D});var S={};d.r(S),d.d(S,{getAudioBuffer:()=>G,getTexture:()=>B,registerAudioBuffer:()=>F,registerTexture:()=>N});var g={};d.r(g),d.d(g,{default:()=>ie,getAudioCache:()=>$,playAudio:()=>K,setAudioConfig:()=>J,setEffectsVolume:()=>oe,setMasterVolume:()=>te,setMusicVolume:()=>se,stopAudio:()=>Q});const A={NO_LIMIT:-1,CALL_1_PER_SECONDS:1e3,CALL_15_PER_SECONDS:1e3/15,CALL_30_PER_SECONDS:1e3/30,CALL_45_PER_SECONDS:1e3/45,CALL_60_PER_SECONDS:1e3/60,CALL_120_PER_SECONDS:1e3/120};let b={};const O=({id:e,callback:t,callLimit:s,elapsed:o,callbackParam:i,forceCallCount:a=!1})=>{if(!o)return;b[e]||(b[e]={lastUpdate:-1,callCount:0});const r=()=>{i?t(i):t()};if(s!==A.NO_LIMIT)if(a){const t=Math.floor(o/(1e3*s));for(;-1===b[e].lastUpdate||t>b[e].callCount;)r(),b[e].lastUpdate+=s,b[e].callCount++;b[e].lastUpdate=o}else(-1===b[e].lastUpdate||o-b[e].lastUpdate>=s)&&(r(),b[e].lastUpdate=o);else r()},P=e=>delete b[e],_=()=>{b={}},v=e=>{if(e.isMaterial){const t=e;t.map?.dispose(),t.map=null,t.dispose()}else e.forEach(v)},x=e=>{const{isMesh:t,material:s,geometry:o}=e;t?(s&&(v(s),e.material=null),o&&(o.dispose(),e.geometry=null),e.parent?.remove(e)):e.children&&(e.children.forEach(x),e.parent?.remove(e))},C=(e,t,s={skippedProperties:[],applyToFirstObject:!1})=>{const o={};return Object.keys(e).forEach(i=>{s.skippedProperties&&s.skippedProperties.includes(i)||("object"==typeof e[i]&&e[i]&&t[i]&&!Array.isArray(e[i])?o[i]=C(e[i],t[i],s):(o[i]=0===t[i]?0:!1!==t[i]&&(t[i]||e[i]),s.applyToFirstObject&&(e[i]=o[i])))}),o},E=(e,t,s={skippedProperties:[],applyToFirstObject:!1})=>{const o={};return Array.from(new Set([...Object.keys(e||{}),...Object.keys(t||{})])).forEach(i=>{s.skippedProperties&&s.skippedProperties.includes(i)||("object"==typeof e?.[i]&&e?.[i]&&t?.[i]&&!Array.isArray(e[i])?o[i]=E(e[i],t[i],s):(o[i]=0===t?.[i]?0:!1!==t?.[i]&&(t?.[i]||e?.[i]),s.applyToFirstObject&&(e[i]=o[i])))}),o},T=(e,t,s={skippedProperties:[]})=>{const o={};return Object.keys(e).forEach(i=>{if(!s.skippedProperties||!s.skippedProperties.includes(i))if("object"==typeof e[i]&&e[i]&&t[i]&&!Array.isArray(e[i])){const a=T(e[i],t[i],s);Object.keys(a).length>0&&(o[i]=a)}else{const s=0===t[i]?0:t[i]||e[i];s!==e[i]&&(o[i]=s)}}),o},V={HH_MM_SS:"HH:MM:SS",MM_SS:"MM:SS",MM_SS_MS:"MM:SS.MS"},j=[{pattern:"HH",routine:({hours:e})=>String(e).padStart(2,"0")},{pattern:"MM",routine:({minutes:e})=>String(e).padStart(2,"0")},{pattern:"SS",routine:({seconds:e})=>String(e).padStart(2,"0")},{pattern:"MS",routine:({milliseconds:e})=>String(e).padStart(3,"0")}],z=(e,t)=>{const s=Math.floor(e%1e3),o=Math.floor(e/1e3%60),i=Math.floor(Math.floor(e/1e3/60)%60),a={hours:Math.floor(Math.floor(e/1e3/60)/60%24),minutes:i,seconds:o,milliseconds:s};let r=t;return j.forEach(({pattern:e,routine:t})=>r=r.replace(e,t(a))),r};let L=0;const k=()=>L++,U=e=>(e.x=Math.abs(e.x),e.y=Math.abs(e.y),e.z=Math.abs(e.z),e),w=(e,t,s)=>(e.x-s.x)*(t.z-s.z)-(t.x-s.x)*(e.z-s.z),I=(e,t,s,o)=>{const i=w(e,t,s),a=w(e,s,o),r=w(e,o,t);return!((i<0||a<0||r<0)&&(i>0||a>0||r>0))},D=(e,t,s,o)=>{const i=(s.x-t.x)*(o.y-t.y)-(o.x-t.x)*(s.y-t.y),a=(s.x-t.x)*(o.z-t.z)-(o.x-t.x)*(s.z-t.z),r=(s.z-t.z)*(o.y-t.y)-(o.z-t.z)*(s.y-t.y),l=(s.x-t.x)*(o.z-t.z)-(o.x-t.x)*(s.z-t.z);return t.y+i/a*(e.z-t.z)-r/l*(e.x-t.x)},R=new Map,H=new Map,N=(e,t)=>{R.set(e,t)},B=e=>R.get(e)||null,F=(e,t)=>{H.set(e,t)},G=e=>H.get(e)||null;class X extends i{constructor(e,t=1,i=16,r=2){const l=new o,n=new Float32Array(3*(3*(i+2*r)+3));l.setAttribute("position",new s(n,3));const c=new a({color:65280});super(l,[new a({color:16776960}),c]),this.audio=e,this.range=t,this.divisionsInnerAngle=i,this.divisionsOuterAngle=r,this.type="PositionalAudioHelper",this.update()}update(){const e=this.audio,t=this.range,s=this.divisionsInnerAngle,o=this.divisionsOuterAngle,i=r.degToRad(e.panner.coneInnerAngle),a=r.degToRad(e.panner.coneOuterAngle),l=i/2,n=a/2;let c,d,u=0,p=0;const m=this.geometry,f=m.attributes.position;function y(e,s,o,i){const a=(s-e)/o;for(f.setXYZ(u,0,0,0),p++,c=e;c{Z=e},K=({audioId:s,position:o,radius:i=1,scene:a,camera:r,cacheId:d})=>{const u=Date.now();let p;if(d&&q[d]){const{audio:e,container:t}=q[d];p=e,p.isPlaying&&p.stop(),t&&o&&t.position.copy(o),q[d].lastPlayedTime=u}else{const m=G(s);if(!m)return;const{loop:f,volume:y,isMusic:M}={...Y,...Z[s]},h=new t;let S;if(o&&a&&r){p=new n(h),p.setRefDistance(i);const e=new c(i,32,32);S=new l(e),S.visible=!1;const t=new X(p,i);p.add(t),S.position.copy(o),S.add(p),a.add(S),r.add(h)}else p=new e(h);p.setBuffer(m),p.setLoop(f||!1),p.setVolume((y||1)*W.masterVolume*(M?W.musicVolume:W.effectsVolume)),q[d||s]={audio:p,audioId:s,container:S,lastPlayedTime:u}}p.play()},Q=e=>{const t=$(e);t.audio&&t.audio.isPlaying&&t.audio.stop()},$=e=>q[e]||{audio:null,audioId:"",container:void 0,lastPlayedTime:0},ee=()=>{Object.keys(q).forEach(e=>{const{audio:t,audioId:s}=$(e);if(t){const{volume:e,isMusic:o}={...Y,...Z[s]};t.setVolume((e||1)*W.masterVolume*(o?W.musicVolume:W.effectsVolume))}})},te=e=>{W.masterVolume=e,ee()},se=e=>{W.musicVolume=e,ee()},oe=e=>{W.effectsVolume=e,ee()},ie={playAudio:K,stopAudio:Q,setMasterVolume:te,setMusicVolume:se,setEffectsVolume:oe};export{S as AssetsUtils,g as AudioUtils,u as CallbackUtils,p as DisposeUtils,h as GeomUtils,m as ObjectUtils,f as TimeUtils,y as TokenUtils,M as Vector3Utils}; \ No newline at end of file +/*! For license information please see three-utils.min.js.LICENSE.txt */ +import{AmbientLight as e,AnimationClip as t,Audio as n,AudioListener as s,AudioLoader as r,Bone as o,Box3 as i,BufferAttribute as a,BufferGeometry as c,ClampToEdgeWrapping as l,Color as u,ColorManagement as h,Curve as p,DirectionalLight as d,DoubleSide as f,EquirectangularReflectionMapping as m,Euler as g,FileLoader as v,Float32BufferAttribute as y,FrontSide as T,Group as x,ImageBitmapLoader as w,InstancedBufferAttribute as A,InstancedMesh as b,InterleavedBuffer as I,InterleavedBufferAttribute as R,Interpolant as M,InterpolateDiscrete as S,InterpolateLinear as E,Line as _,LineBasicMaterial as N,LineLoop as L,LineSegments as P,LinearFilter as C,LinearMipmapLinearFilter as O,LinearMipmapNearestFilter as k,LinearSRGBColorSpace as D,Loader as F,LoaderUtils as U,Material as j,MathUtils as H,Matrix3 as B,Matrix4 as V,Mesh as G,MeshBasicMaterial as z,MeshLambertMaterial as K,MeshPhongMaterial as X,MeshPhysicalMaterial as W,MeshStandardMaterial as q,MirroredRepeatWrapping as Y,NearestFilter as $,NearestMipmapLinearFilter as Z,NearestMipmapNearestFilter as J,NumberKeyframeTrack as Q,Object3D as ee,OrthographicCamera as te,PerspectiveCamera as ne,PointLight as se,Points as re,PointsMaterial as oe,PositionalAudio as ie,PropertyBinding as ae,Quaternion as ce,QuaternionKeyframeTrack as le,RepeatWrapping as ue,SRGBColorSpace as he,ShapeUtils as pe,Skeleton as de,SkinnedMesh as fe,Sphere as me,SphereGeometry as ge,SpotLight as ve,Texture as ye,TextureLoader as Te,TriangleFanDrawMode as xe,TriangleStripDrawMode as we,TrianglesDrawMode as Ae,Uint16BufferAttribute as be,Vector2 as Ie,Vector3 as Re,Vector4 as Me,VectorKeyframeTrack as Se}from"THREE";var Ee={d:(e,t)=>{for(var n in t)Ee.o(t,n)&&!Ee.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r:e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})}},_e={};Ee.r(_e),Ee.d(_e,{CallLimits:()=>Ue,callWithReducer:()=>He,clearAllCallReducerData:()=>Ve,clearCallReducerData:()=>Be});var Ne={};Ee.r(Ne),Ee.d(Ne,{deepDispose:()=>ze,disposeMaterials:()=>Ge});var Le={};Ee.r(Le),Ee.d(Le,{deepMerge:()=>Xe,getObjectDiff:()=>We,patchObject:()=>Ke});var Pe={};Ee.r(Pe),Ee.d(Pe,{TimePattern:()=>qe,formatTime:()=>$e});var Ce={};Ee.r(Ce),Ee.d(Ce,{getUniqueId:()=>Je});var Oe={};Ee.r(Oe),Ee.d(Oe,{absVector3:()=>Qe});var ke={};Ee.r(ke),Ee.d(ke,{isPointInATriangle:()=>tt,sign:()=>et,yFromTriangle:()=>nt});var De={};Ee.r(De),Ee.d(De,{disposeAssets:()=>js,getAudioBuffer:()=>Ds,getFBXModel:()=>Es,getFBXSkeletonAnimation:()=>Ns,getGLTFModel:()=>Ps,getTexture:()=>Os,loadAssets:()=>Hs,registerAudioBuffer:()=>ks,registerFBXModel:()=>Ss,registerFBXSkeletonAnimation:()=>_s,registerGLTFModel:()=>Ls,registerTexture:()=>Cs});var Fe={};Ee.r(Fe),Ee.d(Fe,{default:()=>er,getAudioCache:()=>Ys,playAudio:()=>Ws,setAudioConfig:()=>Xs,setEffectsVolume:()=>Qs,setMasterVolume:()=>Zs,setMusicVolume:()=>Js,stopAudio:()=>qs});const Ue={NO_LIMIT:-1,CALL_1_PER_SECONDS:1e3,CALL_15_PER_SECONDS:1e3/15,CALL_30_PER_SECONDS:1e3/30,CALL_45_PER_SECONDS:1e3/45,CALL_60_PER_SECONDS:1e3/60,CALL_120_PER_SECONDS:1e3/120};let je={};const He=({id:e,callback:t,callLimit:n,elapsed:s,callbackParam:r,forceCallCount:o=!1})=>{if(!s)return;je[e]||(je[e]={lastUpdate:-1,callCount:0});const i=()=>{r?t(r):t()};if(n!==Ue.NO_LIMIT)if(o){const t=Math.floor(s/(1e3*n));for(;-1===je[e].lastUpdate||t>je[e].callCount;)i(),je[e].lastUpdate+=n,je[e].callCount++;je[e].lastUpdate=s}else(-1===je[e].lastUpdate||s-je[e].lastUpdate>=n)&&(i(),je[e].lastUpdate=s);else i()},Be=e=>delete je[e],Ve=()=>{je={}},Ge=e=>{if(e.isMaterial){const t=e;t.map?.dispose(),t.map=null,t.dispose()}else e.forEach(Ge)},ze=e=>{const{isMesh:t,material:n,geometry:s}=e;t?(n&&(Ge(n),e.material=null),s&&(s.dispose(),e.geometry=null),e.parent?.remove(e)):e.children&&(e.children.forEach(ze),e.parent?.remove(e))},Ke=(e,t,n={skippedProperties:[],applyToFirstObject:!1})=>{const s={};return Object.keys(e).forEach(r=>{n.skippedProperties&&n.skippedProperties.includes(r)||("object"==typeof e[r]&&e[r]&&t[r]&&!Array.isArray(e[r])?s[r]=Ke(e[r],t[r],n):(s[r]=0===t[r]?0:!1!==t[r]&&(t[r]||e[r]),n.applyToFirstObject&&(e[r]=s[r])))}),s},Xe=(e,t,n={skippedProperties:[],applyToFirstObject:!1})=>{const s={};return Array.from(new Set([...Object.keys(e||{}),...Object.keys(t||{})])).forEach(r=>{n.skippedProperties&&n.skippedProperties.includes(r)||("object"==typeof e?.[r]&&e?.[r]&&t?.[r]&&!Array.isArray(e[r])?s[r]=Xe(e[r],t[r],n):(s[r]=0===t?.[r]?0:!1!==t?.[r]&&(t?.[r]||e?.[r]),n.applyToFirstObject&&(e[r]=s[r])))}),s},We=(e,t,n={skippedProperties:[]})=>{const s={};return Object.keys(e).forEach(r=>{if(!n.skippedProperties||!n.skippedProperties.includes(r))if("object"==typeof e[r]&&e[r]&&t[r]&&!Array.isArray(e[r])){const o=We(e[r],t[r],n);Object.keys(o).length>0&&(s[r]=o)}else{const n=0===t[r]?0:t[r]||e[r];n!==e[r]&&(s[r]=n)}}),s},qe={HH_MM_SS:"HH:MM:SS",MM_SS:"MM:SS",MM_SS_MS:"MM:SS.MS"},Ye=[{pattern:"HH",routine:({hours:e})=>String(e).padStart(2,"0")},{pattern:"MM",routine:({minutes:e})=>String(e).padStart(2,"0")},{pattern:"SS",routine:({seconds:e})=>String(e).padStart(2,"0")},{pattern:"MS",routine:({milliseconds:e})=>String(e).padStart(3,"0")}],$e=(e,t)=>{const n=Math.floor(e%1e3),s=Math.floor(e/1e3%60),r=Math.floor(Math.floor(e/1e3/60)%60),o={hours:Math.floor(Math.floor(e/1e3/60)/60%24),minutes:r,seconds:s,milliseconds:n};let i=t;return Ye.forEach(({pattern:e,routine:t})=>i=i.replace(e,t(o))),i};let Ze=0;const Je=()=>Ze++,Qe=e=>(e.x=Math.abs(e.x),e.y=Math.abs(e.y),e.z=Math.abs(e.z),e),et=(e,t,n)=>(e.x-n.x)*(t.z-n.z)-(t.x-n.x)*(e.z-n.z),tt=(e,t,n,s)=>{const r=et(e,t,n),o=et(e,n,s),i=et(e,s,t);return!((r<0||o<0||i<0)&&(r>0||o>0||i>0))},nt=(e,t,n,s)=>{const r=(n.x-t.x)*(s.y-t.y)-(s.x-t.x)*(n.y-t.y),o=(n.x-t.x)*(s.z-t.z)-(s.x-t.x)*(n.z-t.z),i=(n.z-t.z)*(s.y-t.y)-(s.z-t.z)*(n.y-t.y),a=(n.x-t.x)*(s.z-t.z)-(s.x-t.x)*(n.z-t.z);return t.y+r/o*(e.z-t.z)-i/a*(e.x-t.x)};function st(e){const t=new Map,n=new Map,s=e.clone();return rt(e,s,function(e,s){t.set(s,e),n.set(e,s)}),s.traverse(function(e){if(!e.isSkinnedMesh)return;const s=e,r=t.get(e),o=r.skeleton.bones;s.skeleton=r.skeleton.clone(),s.bindMatrix.copy(r.bindMatrix),s.skeleton.bones=o.map(function(e){return n.get(e)}),s.bind(s.skeleton,s.bindMatrix)}),s}function rt(e,t,n){n(e,t);for(let s=0;s>1|(21845&yt)<<1;Tt=(61680&(Tt=(52428&Tt)>>2|(13107&Tt)<<2))>>4|(3855&Tt)<<4,vt[yt]=((65280&Tt)>>8|(255&Tt)<<8)>>1}var xt=function(e,t,n){for(var s=e.length,r=0,o=new it(t);r>c]=l}else for(i=new it(s),r=0;r>15-e[r]);return i},wt=new ot(288);for(yt=0;yt<144;++yt)wt[yt]=8;for(yt=144;yt<256;++yt)wt[yt]=9;for(yt=256;yt<280;++yt)wt[yt]=7;for(yt=280;yt<288;++yt)wt[yt]=8;var At=new ot(32);for(yt=0;yt<32;++yt)At[yt]=5;var bt=xt(wt,9,1),It=xt(At,5,1),Rt=function(e){for(var t=e[0],n=1;nt&&(t=e[n]);return t},Mt=function(e,t,n){var s=t/8|0;return(e[s]|e[s+1]<<8)>>(7&t)&n},St=function(e,t){var n=t/8|0;return(e[n]|e[n+1]<<8|e[n+2]<<16)>>(7&t)},Et=function(e){return(e+7)/8|0},_t=function(e,t,n){return(null==t||t<0)&&(t=0),(null==n||n>e.length)&&(n=e.length),new ot(e.subarray(t,n))},Nt=["unexpected EOF","invalid block type","invalid length/literal","invalid distance","stream finished","no stream handler",,"no callback","invalid UTF-8 data","extra field too long","date not in range 1980-2099","filename too long","stream finishing","invalid zip data"],Lt=function(e,t,n){var s=new Error(t||Nt[e]);if(s.code=e,Error.captureStackTrace&&Error.captureStackTrace(s,Lt),!n)throw s;return s},Pt=function(e,t,n,s){var r=e.length,o=s?s.length:0;if(!r||t.f&&!t.l)return n||new ot(0);var i=!n,a=i||2!=t.i,c=t.i;i&&(n=new ot(3*r));var l=function(e){var t=n.length;if(e>t){var s=new ot(Math.max(2*t,e));s.set(n),n=s}},u=t.f||0,h=t.p||0,p=t.b||0,d=t.l,f=t.d,m=t.m,g=t.n,v=8*r;do{if(!d){u=Mt(e,h,1);var y=Mt(e,h+1,3);if(h+=3,!y){var T=e[(N=Et(h)+4)-4]|e[N-3]<<8,x=N+T;if(x>r){c&&Lt(0);break}a&&l(p+T),n.set(e.subarray(N,x),p),t.b=p+=T,t.p=h=8*x,t.f=u;continue}if(1==y)d=bt,f=It,m=9,g=5;else if(2==y){var w=Mt(e,h,31)+257,A=Mt(e,h+10,15)+4,b=w+Mt(e,h+5,31)+1;h+=14;for(var I=new ot(b),R=new ot(19),M=0;M>4)<16)I[M++]=N;else{var P=0,C=0;for(16==N?(C=3+Mt(e,h,3),h+=2,P=I[M-1]):17==N?(C=3+Mt(e,h,7),h+=3):18==N&&(C=11+Mt(e,h,127),h+=7);C--;)I[M++]=P}}var O=I.subarray(0,w),k=I.subarray(w);m=Rt(O),g=Rt(k),d=xt(O,m,1),f=xt(k,g,1)}else Lt(1);if(h>v){c&&Lt(0);break}}a&&l(p+131072);for(var D=(1<>4;if((h+=15&P)>v){c&&Lt(0);break}if(P||Lt(2),j<256)n[p++]=j;else{if(256==j){U=h,d=null;break}var H=j-254;if(j>264){var B=ct[M=j-257];H=Mt(e,h,(1<>4;V||Lt(3),h+=15&V;k=gt[G];if(G>3){B=lt[G];k+=St(e,h)&(1<v){c&&Lt(0);break}a&&l(p+131072);var z=p+H;if(p>4>7||(e[0]<<8|e[1])%31)&&Lt(6,"invalid zlib data"),(e[1]>>5&1)==+!t&&Lt(6,"invalid zlib data: "+(32&e[1]?"need":"unexpected")+" dictionary"),2+(e[1]>>3&4)};function kt(e,t){return Pt(e.subarray(Ot(e,t&&t.dictionary),-4),{i:2},t&&t.out,t&&t.dictionary)}var Dt="undefined"!=typeof TextDecoder&&new TextDecoder;try{Dt.decode(Ct,{stream:!0})}catch(e){}"function"==typeof queueMicrotask?queueMicrotask:"function"==typeof setTimeout&&setTimeout;function Ft(e,t,n){const s=n.length-e-1;if(t>=n[s])return s-1;if(t<=n[e])return e;let r=e,o=s,i=Math.floor((r+o)/2);for(;t=n[i+1];)t=o&&(c[r][0]=c[t][0]/a[u+1][l],s=c[r][0]*a[l][u]);const h=e-1<=u?o-1:n-e;for(let e=l>=-1?1:-l;e<=h;++e)c[r][e]=(c[t][e]-c[t][e-1])/a[u+1][l+e],s+=c[r][e]*a[l+e][u];e<=u&&(c[r][o]=-c[t][o-1]/a[u+1][e],s+=c[r][o]*a[e][u]),i[o][e]=s;const p=t;t=r,r=p}}let u=n;for(let e=1;e<=s;++e){for(let t=0;t<=n;++t)i[e][t]*=u;u*=n-e}return i}(a,s,e,o,t),l=[];for(let e=0;ee.toArray()),e.startKnot=this.startKnot,e.endKnot=this.endKnot,e}fromJSON(e){return super.fromJSON(e),this.degree=e.degree,this.knots=[...e.knots],this.controlPoints=e.controlPoints.map(e=>new Me(e[0],e[1],e[2],e[3])),this.startKnot=e.startKnot,this.endKnot=e.endKnot,this}}let Vt,Gt,zt;class Kt extends F{constructor(e){super(e)}load(e,t,n,s){const r=this,o=""===r.path?U.extractUrlBase(e):r.path,i=new v(this.manager);i.setPath(r.path),i.setResponseType("arraybuffer"),i.setRequestHeader(r.requestHeader),i.setWithCredentials(r.withCredentials),i.load(e,function(n){try{t(r.parse(n,o))}catch(t){s&&s(t),r.manager.itemError(e)}},n,s)}parse(e,t){if(function(e){const t="Kaydara FBX Binary \0";return e.byteLength>=t.length&&t===ln(e,0,t.length)}(e))Vt=(new $t).parse(e);else{const t=ln(e);if(!function(e){const t=["K","a","y","d","a","r","a","\\","F","B","X","\\","B","i","n","a","r","y","\\","\\"];let n=0;function s(t){const s=e[t-1];return e=e.slice(n+t),n++,s}for(let e=0;e0,o="string"==typeof r.Content&&""!==r.Content;if(e||o){const e=this.parseImage(n[s]);t[r.RelativeFilename||r.Filename]=e}}}}for(const n in e){const s=e[n];void 0!==t[s]?e[n]=t[s]:e[n]=e[n].split("\\").pop()}return e}parseImage(e){const t=e.Content,n=e.RelativeFilename||e.Filename;let s;switch(n.slice(n.lastIndexOf(".")+1).toLowerCase()){case"bmp":s="image/bmp";break;case"jpg":case"jpeg":s="image/jpeg";break;case"png":s="image/png";break;case"tif":s="image/tiff";break;case"tga":this.manager.getHandler(".tga"),s="image/tga";break;case"webp":s="image/webp";break;default:return}if("string"==typeof t)return"data:"+s+";base64,"+t;{const e=new Uint8Array(t);return window.URL.createObjectURL(new Blob([e],{type:s}))}}parseTextures(e){const t=new Map;if("Texture"in Vt.Objects){const n=Vt.Objects.Texture;for(const s in n){const r=this.parseTexture(n[s],e);t.set(parseInt(s),r)}}return t}parseTexture(e,t){const n=this.loadTexture(e,t);n.ID=e.id,n.name=e.attrName;const s=e.WrapModeU,r=e.WrapModeV,o=void 0!==s?s.value:0,i=void 0!==r?r.value:0;if(n.wrapS=0===o?ue:l,n.wrapT=0===i?ue:l,"Scaling"in e){const t=e.Scaling.value;n.repeat.x=t[0],n.repeat.y=t[1]}if("Translation"in e){const t=e.Translation.value;n.offset.x=t[0],n.offset.y=t[1]}return n}loadTexture(e,t){const n=e.FileName.split(".").pop().toLowerCase();let s=this.manager.getHandler(`.${n}`);null===s&&(s=this.textureLoader);const r=s.path;r||s.setPath(this.textureLoader.path);const o=Gt.get(e.id).children;let i;if(void 0!==o&&o.length>0&&void 0!==t[o[0].ID]&&(i=t[o[0].ID],0!==i.indexOf("blob:")&&0!==i.indexOf("data:")||s.setPath(void 0)),void 0===i)return new ye;const a=s.load(i);return s.setPath(r),a}parseMaterials(e){const t=new Map;if("Material"in Vt.Objects){const n=Vt.Objects.Material;for(const s in n){const r=this.parseMaterial(n[s],e);null!==r&&t.set(parseInt(s),r)}}return t}parseMaterial(e,t){const n=e.id,s=e.attrName;let r=e.ShadingModel;if("object"==typeof r&&(r=r.value),!Gt.has(n))return null;const o=this.parseParameters(e,t,n);let i;switch(r.toLowerCase()){case"phong":default:i=new X;break;case"lambert":i=new K}return i.setValues(o),i.name=s,i}parseParameters(e,t,n){const s={};e.BumpFactor&&(s.bumpScale=e.BumpFactor.value),e.Diffuse?s.color=h.colorSpaceToWorking((new u).fromArray(e.Diffuse.value),he):!e.DiffuseColor||"Color"!==e.DiffuseColor.type&&"ColorRGB"!==e.DiffuseColor.type||(s.color=h.colorSpaceToWorking((new u).fromArray(e.DiffuseColor.value),he)),e.DisplacementFactor&&(s.displacementScale=e.DisplacementFactor.value),e.Emissive?s.emissive=h.colorSpaceToWorking((new u).fromArray(e.Emissive.value),he):!e.EmissiveColor||"Color"!==e.EmissiveColor.type&&"ColorRGB"!==e.EmissiveColor.type||(s.emissive=h.colorSpaceToWorking((new u).fromArray(e.EmissiveColor.value),he)),e.EmissiveFactor&&(s.emissiveIntensity=parseFloat(e.EmissiveFactor.value)),s.opacity=1-(e.TransparencyFactor?parseFloat(e.TransparencyFactor.value):0),1!==s.opacity&&0!==s.opacity||(s.opacity=e.Opacity?parseFloat(e.Opacity.value):null,null===s.opacity&&(s.opacity=1-(e.TransparentColor?parseFloat(e.TransparentColor.value[0]):0))),s.opacity<1&&(s.transparent=!0),e.ReflectionFactor&&(s.reflectivity=e.ReflectionFactor.value),e.Shininess&&(s.shininess=e.Shininess.value),e.Specular?s.specular=h.colorSpaceToWorking((new u).fromArray(e.Specular.value),he):e.SpecularColor&&"Color"===e.SpecularColor.type&&(s.specular=h.colorSpaceToWorking((new u).fromArray(e.SpecularColor.value),he));const r=this;return Gt.get(n).children.forEach(function(e){switch(e.relationship){case"Bump":s.bumpMap=r.getTexture(t,e.ID);break;case"Maya|TEX_ao_map":s.aoMap=r.getTexture(t,e.ID);break;case"DiffuseColor":case"Maya|TEX_color_map":s.map=r.getTexture(t,e.ID),void 0!==s.map&&(s.map.colorSpace=he);break;case"DisplacementColor":s.displacementMap=r.getTexture(t,e.ID);break;case"EmissiveColor":s.emissiveMap=r.getTexture(t,e.ID),void 0!==s.emissiveMap&&(s.emissiveMap.colorSpace=he);break;case"NormalMap":case"Maya|TEX_normal_map":s.normalMap=r.getTexture(t,e.ID);break;case"ReflectionColor":s.envMap=r.getTexture(t,e.ID),void 0!==s.envMap&&(s.envMap.mapping=m,s.envMap.colorSpace=he);break;case"SpecularColor":s.specularMap=r.getTexture(t,e.ID),void 0!==s.specularMap&&(s.specularMap.colorSpace=he);break;case"TransparentColor":case"TransparencyFactor":s.alphaMap=r.getTexture(t,e.ID),s.transparent=!0}}),s}getTexture(e,t){return"LayeredTexture"in Vt.Objects&&t in Vt.Objects.LayeredTexture&&(t=Gt.get(t).children[0].ID),e.get(t)}parseDeformers(){const e={},t={};if("Deformer"in Vt.Objects){const n=Vt.Objects.Deformer;for(const s in n){const r=n[s],o=Gt.get(parseInt(s));if("Skin"===r.attrType){const t=this.parseSkeleton(o,n);t.ID=s,o.parents.length,t.geometryID=o.parents[0].ID,e[s]=t}else if("BlendShape"===r.attrType){const e={id:s};e.rawTargets=this.parseMorphTargets(o,n),e.id=s,o.parents.length,t[s]=e}}}return{skeletons:e,morphTargets:t}}parseSkeleton(e,t){const n=[];return e.children.forEach(function(e){const s=t[e.ID];if("Cluster"!==s.attrType)return;const r={ID:e.ID,indices:[],weights:[],transformLink:(new V).fromArray(s.TransformLink.a)};"Indexes"in s&&(r.indices=s.Indexes.a,r.weights=s.Weights.a),n.push(r)}),{rawBones:n,bones:[]}}parseMorphTargets(e,t){const n=[];for(let s=0;s1?o=i:i.length>0?o=i[0]:(o=new X({name:F.DEFAULT_MATERIAL_NAME,color:13421772}),i.push(o)),"color"in r.attributes&&i.forEach(function(e){e.vertexColors=!0}),r.groups.length>0){let e=!1;for(let t=0,n=r.groups.length;t=i.length)&&(n.materialIndex=i.length,e=!0)}if(e){const e=new X;i.push(e)}}return r.FBX_Deformer?(s=new fe(r,o),s.normalizeSkinWeights()):s=new G(r,o),s}createCurve(e,t){const n=e.children.reduce(function(e,n){return t.has(n.ID)&&(e=t.get(n.ID)),e},null),s=new N({name:F.DEFAULT_MATERIAL_NAME,color:3342591,linewidth:1});return new _(n,s)}getTransformData(e,t){const n={};"InheritType"in t&&(n.inheritType=parseInt(t.InheritType.value)),n.eulerOrder=an("RotationOrder"in t?t.RotationOrder.value:0),"Lcl_Translation"in t&&(n.translation=t.Lcl_Translation.value),"PreRotation"in t&&(n.preRotation=t.PreRotation.value),"Lcl_Rotation"in t&&(n.rotation=t.Lcl_Rotation.value),"PostRotation"in t&&(n.postRotation=t.PostRotation.value),"Lcl_Scaling"in t&&(n.scale=t.Lcl_Scaling.value),"ScalingOffset"in t&&(n.scalingOffset=t.ScalingOffset.value),"ScalingPivot"in t&&(n.scalingPivot=t.ScalingPivot.value),"RotationOffset"in t&&(n.rotationOffset=t.RotationOffset.value),"RotationPivot"in t&&(n.rotationPivot=t.RotationPivot.value),e.userData.transformData=n}setLookAtProperties(e,t){if("LookAtProperty"in t){Gt.get(e.ID).children.forEach(function(t){if("LookAtProperty"===t.relationship){const n=Vt.Objects.Model[t.ID];if("Lcl_Translation"in n){const t=n.Lcl_Translation.value;void 0!==e.target?(e.target.position.fromArray(t),zt.add(e.target)):e.lookAt((new Re).fromArray(t))}}})}}bindSkeleton(e,t,n){const s=this.parsePoseNodes();for(const r in e){const o=e[r];Gt.get(parseInt(o.ID)).parents.forEach(function(e){if(t.has(e.ID)){const t=e.ID;Gt.get(t).parents.forEach(function(e){if(n.has(e.ID)){n.get(e.ID).bind(new de(o.bones),s[e.ID])}})}})}}parsePoseNodes(){const e={};if("Pose"in Vt.Objects){const t=Vt.Objects.Pose;for(const n in t)if("BindPose"===t[n].attrType&&t[n].NbPoseNodes>0){const s=t[n].PoseNode;Array.isArray(s)?s.forEach(function(t){e[t.Node]=(new V).fromArray(t.Matrix.a)}):e[s.Node]=(new V).fromArray(s.Matrix.a)}}return e}addGlobalSceneSettings(){if("GlobalSettings"in Vt){if("AmbientColor"in Vt.GlobalSettings){const t=Vt.GlobalSettings.AmbientColor.value,n=t[0],s=t[1],r=t[2];if(0!==n||0!==s||0!==r){const t=(new u).setRGB(n,s,r,he);zt.add(new e(t,1))}}"UnitScaleFactor"in Vt.GlobalSettings&&(zt.userData.unitScaleFactor=Vt.GlobalSettings.UnitScaleFactor.value)}}}class Wt{constructor(){this.negativeMaterialIndices=!1}parse(e){const t=new Map;if("Geometry"in Vt.Objects){const n=Vt.Objects.Geometry;for(const s in n){const r=Gt.get(parseInt(s)),o=this.parseGeometry(r,n[s],e);t.set(parseInt(s),o)}}return this.negativeMaterialIndices,t}parseGeometry(e,t,n){switch(t.attrType){case"Mesh":return this.parseMeshGeometry(e,t,n);case"NurbsCurve":return this.parseNurbsGeometry(t)}}parseMeshGeometry(e,t,n){const s=n.skeletons,r=[],o=e.parents.map(function(e){return Vt.Objects.Model[e.ID]});if(0===o.length)return;const i=e.children.reduce(function(e,t){return void 0!==s[t.ID]&&(e=s[t.ID]),e},null);e.children.forEach(function(e){void 0!==n.morphTargets[e.ID]&&r.push(n.morphTargets[e.ID])});const a=o[0],c={};"RotationOrder"in a&&(c.eulerOrder=an(a.RotationOrder.value)),"InheritType"in a&&(c.inheritType=parseInt(a.InheritType.value)),"GeometricTranslation"in a&&(c.translation=a.GeometricTranslation.value),"GeometricRotation"in a&&(c.rotation=a.GeometricRotation.value),"GeometricScaling"in a&&(c.scale=a.GeometricScaling.value);const l=on(c);return this.genGeometry(t,i,r,l)}genGeometry(e,t,n,s){const r=new c;e.attrName&&(r.name=e.attrName);const o=this.parseGeoNode(e,t),i=this.genBuffers(o),a=new y(i.vertex,3);if(a.applyMatrix4(s),r.setAttribute("position",a),i.colors.length>0&&r.setAttribute("color",new y(i.colors,3)),t&&(r.setAttribute("skinIndex",new be(i.weightsIndices,4)),r.setAttribute("skinWeight",new y(i.vertexWeights,4)),r.FBX_Deformer=t),i.normal.length>0){const e=(new B).getNormalMatrix(s),t=new y(i.normal,3);t.applyNormalMatrix(e),r.setAttribute("normal",t)}if(i.uvs.forEach(function(e,t){const n=0===t?"uv":`uv${t}`;r.setAttribute(n,new y(i.uvs[t],2))}),o.material&&"AllSame"!==o.material.mappingType){let e=i.materialIndex[0],t=0;if(i.materialIndex.forEach(function(n,s){n!==e&&(r.addGroup(t,s-t,e),e=n,t=s)}),r.groups.length>0){const t=r.groups[r.groups.length-1],n=t.start+t.count;n!==i.materialIndex.length&&r.addGroup(n,i.materialIndex.length-n,e)}0===r.groups.length&&r.addGroup(0,i.materialIndex.length,i.materialIndex[0])}return this.addMorphTargets(r,e,n,s),r}parseGeoNode(e,t){const n={};if(n.vertexPositions=void 0!==e.Vertices?e.Vertices.a:[],n.vertexIndices=void 0!==e.PolygonVertexIndex?e.PolygonVertexIndex.a:[],e.LayerElementColor&&(n.color=this.parseVertexColors(e.LayerElementColor[0])),e.LayerElementMaterial&&(n.material=this.parseMaterialIndices(e.LayerElementMaterial[0])),e.LayerElementNormal&&(n.normal=this.parseNormals(e.LayerElementNormal[0])),e.LayerElementUV){n.uv=[];let t=0;for(;e.LayerElementUV[t];)e.LayerElementUV[t].UV&&n.uv.push(this.parseUVs(e.LayerElementUV[t])),t++}return n.weightTable={},null!==t&&(n.skeleton=t,t.rawBones.forEach(function(e,t){e.indices.forEach(function(s,r){void 0===n.weightTable[s]&&(n.weightTable[s]=[]),n.weightTable[s].push({id:t,weight:e.weights[r]})})})),n}genBuffers(e){const t={vertex:[],normal:[],colors:[],uvs:[],materialIndex:[],vertexWeights:[],weightsIndices:[]};let n=0,s=0,r=!1,o=[],i=[],a=[],c=[],l=[],u=[];const h=this;return e.vertexIndices.forEach(function(p,d){let f,m=!1;p<0&&(p^=-1,m=!0);let g=[],v=[];if(o.push(3*p,3*p+1,3*p+2),e.color){const t=nn(d,n,p,e.color);a.push(t[0],t[1],t[2])}if(e.skeleton){if(void 0!==e.weightTable[p]&&e.weightTable[p].forEach(function(e){v.push(e.weight),g.push(e.id)}),v.length>4){r||(r=!0);const e=[0,0,0,0],t=[0,0,0,0];v.forEach(function(n,s){let r=n,o=g[s];t.forEach(function(t,n,s){if(r>t){s[n]=r,r=t;const i=e[n];e[n]=o,o=i}})}),g=e,v=t}for(;v.length<4;)v.push(0),g.push(0);for(let e=0;e<4;++e)l.push(v[e]),u.push(g[e])}if(e.normal){const t=nn(d,n,p,e.normal);i.push(t[0],t[1],t[2])}e.material&&"AllSame"!==e.material.mappingType&&(f=nn(d,n,p,e.material)[0],f<0&&(h.negativeMaterialIndices=!0,f=0)),e.uv&&e.uv.forEach(function(e,t){const s=nn(d,n,p,e);void 0===c[t]&&(c[t]=[]),c[t].push(s[0]),c[t].push(s[1])}),s++,m&&(h.genFace(t,e,o,f,i,a,c,l,u,s),n++,s=0,o=[],i=[],a=[],c=[],l=[],u=[])}),t}getNormalNewell(e){const t=new Re(0,0,0);for(let n=0;n.5?new Re(0,1,0):new Re(0,0,1)).cross(t).normalize(),s=t.clone().cross(n).normalize();return{normal:t,tangent:n,bitangent:s}}flattenVertex(e,t,n){return new Ie(e.dot(t),e.dot(n))}genFace(e,t,n,s,r,o,i,a,c,l){let u;if(l>3){const e=[],s=t.baseVertexPositions||t.vertexPositions;for(let t=0;t0){const s=this.generateVectorTrack(e.modelName,e.T.curves,n,"position");void 0!==s&&t.push(s)}if(void 0!==e.R&&Object.keys(e.R.curves).length>0){const n=this.generateRotationTrack(e.modelName,e.R.curves,e.preRotation,e.postRotation,e.eulerOrder);void 0!==n&&t.push(n)}if(void 0!==e.S&&Object.keys(e.S.curves).length>0){const n=this.generateVectorTrack(e.modelName,e.S.curves,s,"scale");void 0!==n&&t.push(n)}if(void 0!==e.DeformPercent){const n=this.generateMorphTrack(e);void 0!==n&&t.push(n)}return t}generateVectorTrack(e,t,n,s){const r=this.getTimesForAllAxes(t),o=this.getKeyframeTrackValues(r,t,n);return new Se(e+"."+s,r,o)}generateRotationTrack(e,t,n,s,r){let o,i;if(void 0!==t.x&&void 0!==t.y&&void 0!==t.z){const e=this.interpolateRotations(t.x,t.y,t.z,r);o=e[0],i=e[1]}const a=an(0);void 0!==n&&((n=n.map(H.degToRad)).push(a),n=(new g).fromArray(n),n=(new ce).setFromEuler(n)),void 0!==s&&((s=s.map(H.degToRad)).push(a),s=(new g).fromArray(s),s=(new ce).setFromEuler(s).invert());const c=new ce,l=new g,u=[];if(!i||!o)return new le(e+".quaternion",[0],[0]);for(let e=0;e2){(new ce).fromArray(u,(e-3)/3*4).dot(c)<0&&c.set(-c.x,-c.y,-c.z,-c.w)}c.toArray(u,e/3*4)}return new le(e+".quaternion",o,u)}generateMorphTrack(e){const t=e.DeformPercent.curves.morph,n=t.values.map(function(e){return e/100}),s=zt.getObjectByName(e.modelName).morphTargetDictionary[e.morphName];return new Q(e.modelName+".morphTargetInfluences["+s+"]",t.times,n)}getTimesForAllAxes(e){let t=[];if(void 0!==e.x&&(t=t.concat(e.x.times)),void 0!==e.y&&(t=t.concat(e.y.times)),void 0!==e.z&&(t=t.concat(e.z.times)),t=t.sort(function(e,t){return e-t}),t.length>1){let e=1,n=t[0];for(let s=1;s=180||p[1]>=180||p[2]>=180){const t=Math.max(...p)/180,n=new g(...c,s),a=new g(...u,s),l=(new ce).setFromEuler(n),h=(new ce).setFromEuler(a);l.dot(h)&&h.set(-h.x,-h.y,-h.z,-h.w);const d=e.times[i-1],f=e.times[i]-d,m=new ce,v=new g;for(let e=0;e<1;e+=1/t)m.copy(l.clone().slerp(h.clone(),e)),r.push(d+e*f),v.setFromQuaternion(m,s),o.push(v.x),o.push(v.y),o.push(v.z)}else r.push(e.times[i]),o.push(H.degToRad(e.values[i])),o.push(H.degToRad(t.values[i])),o.push(H.degToRad(n.values[i]))}return[r,o]}}class Yt{getPrevNode(){return this.nodeStack[this.currentIndent-2]}getCurrentNode(){return this.nodeStack[this.currentIndent-1]}getCurrentProp(){return this.currentProp}pushStack(e){this.nodeStack.push(e),this.currentIndent+=1}popStack(){this.nodeStack.pop(),this.currentIndent-=1}setCurrentProp(e,t){this.currentProp=e,this.currentPropName=t}parse(e){this.currentIndent=0,this.allNodes=new Jt,this.nodeStack=[],this.currentProp=[],this.currentPropName="";const t=this,n=e.split(/[\r\n]+/);return n.forEach(function(e,s){const r=e.match(/^[\s\t]*;/),o=e.match(/^[\s\t]*$/);if(r||o)return;const i=e.match("^\\t{"+t.currentIndent+"}(\\w+):(.*){",""),a=e.match("^\\t{"+t.currentIndent+"}(\\w+):[\\s\\t\\r\\n](.*)"),c=e.match("^\\t{"+(t.currentIndent-1)+"}}");i?t.parseNodeBegin(e,i):a?t.parseNodeProperty(e,a,n[++s]):c?t.popStack():e.match(/^[^\s\t}]/)&&t.parseNodePropertyContinued(e)}),this.allNodes}parseNodeBegin(e,t){const n=t[1].trim().replace(/^"/,"").replace(/"$/,""),s=t[2].split(",").map(function(e){return e.trim().replace(/^"/,"").replace(/"$/,"")}),r={name:n},o=this.parseNodeAttr(s),i=this.getCurrentNode();0===this.currentIndent?this.allNodes.add(n,r):n in i?("PoseNode"===n?i.PoseNode.push(r):void 0!==i[n].id&&(i[n]={},i[n][i[n].id]=i[n]),""!==o.id&&(i[n][o.id]=r)):"number"==typeof o.id?(i[n]={},i[n][o.id]=r):"Properties70"!==n&&(i[n]="PoseNode"===n?[r]:r),"number"==typeof o.id&&(r.id=o.id),""!==o.name&&(r.attrName=o.name),""!==o.type&&(r.attrType=o.type),this.pushStack(r)}parseNodeAttr(e){let t=e[0];""!==e[0]&&(t=parseInt(e[0]),isNaN(t)&&(t=e[0]));let n="",s="";return e.length>1&&(n=e[1].replace(/^(\w+)::/,""),s=e[2]),{id:t,name:n,type:s}}parseNodeProperty(e,t,n){let s=t[1].replace(/^"/,"").replace(/"$/,"").trim(),r=t[2].replace(/^"/,"").replace(/"$/,"").trim();"Content"===s&&","===r&&(r=n.replace(/"/g,"").replace(/,$/,"").trim());const o=this.getCurrentNode();if("Properties70"!==o.name){if("C"===s){const e=r.split(",").slice(1),t=parseInt(e[0]),n=parseInt(e[1]);let i=r.split(",").slice(3);i=i.map(function(e){return e.trim().replace(/^"/,"")}),s="connections",r=[t,n],function(e,t){for(let n=0,s=e.length,r=t.length;n=e.size():e.getOffset()+160+16>=e.size()}parseNode(e,t){const n={},s=t>=7500?e.getUint64():e.getUint32(),r=t>=7500?e.getUint64():e.getUint32();t>=7500?e.getUint64():e.getUint32();const o=e.getUint8(),i=e.getString(o);if(0===s)return null;const a=[];for(let t=0;t0?a[0]:"",l=a.length>1?a[1]:"",u=a.length>2?a[2]:"";for(n.singleProperty=1===r&&e.getOffset()===s;s>e.getOffset();){const s=this.parseNode(e,t);null!==s&&this.parseSubNode(i,n,s)}return n.propertyList=a,"number"==typeof c&&(n.id=c),""!==l&&(n.attrName=l),""!==u&&(n.attrType=u),""!==i&&(n.name=i),n}parseSubNode(e,t,n){if(!0===n.singleProperty){const e=n.propertyList[0];Array.isArray(e)?(t[n.name]=n,n.a=e):t[n.name]=e}else if("Connections"===e&&"C"===n.name){const e=[];n.propertyList.forEach(function(t,n){0!==n&&e.push(t)}),void 0===t.connections&&(t.connections=[]),t.connections.push(e)}else if("Properties70"===n.name){Object.keys(n).forEach(function(e){t[e]=n[e]})}else if("Properties70"===e&&"P"===n.name){let e=n.propertyList[0],s=n.propertyList[1];const r=n.propertyList[2],o=n.propertyList[3];let i;0===e.indexOf("Lcl ")&&(e=e.replace("Lcl ","Lcl_")),0===s.indexOf("Lcl ")&&(s=s.replace("Lcl ","Lcl_")),i="Color"===s||"ColorRGB"===s||"Vector"===s||"Vector3D"===s||0===s.indexOf("Lcl_")?[n.propertyList[4],n.propertyList[5],n.propertyList[6]]:n.propertyList[4],t[e]={type:s,type2:r,flag:o,value:i}}else void 0===t[n.name]?"number"==typeof n.id?(t[n.name]={},t[n.name][n.id]=n):t[n.name]=n:"PoseNode"===n.name?(Array.isArray(t[n.name])||(t[n.name]=[t[n.name]]),t[n.name].push(n)):void 0===t[n.name][n.id]&&(t[n.name][n.id]=n)}parseProperty(e){const t=e.getString(1);let n;switch(t){case"C":return e.getBoolean();case"D":return e.getFloat64();case"F":return e.getFloat32();case"I":return e.getInt32();case"L":return e.getInt64();case"R":return n=e.getUint32(),e.getArrayBuffer(n);case"S":return n=e.getUint32(),e.getString(n);case"Y":return e.getInt16();case"b":case"c":case"d":case"f":case"i":case"l":const s=e.getUint32(),r=e.getUint32(),o=e.getUint32();if(0===r)switch(t){case"b":case"c":return e.getBooleanArray(s);case"d":return e.getFloat64Array(s);case"f":return e.getFloat32Array(s);case"i":return e.getInt32Array(s);case"l":return e.getInt64Array(s)}const i=kt(new Uint8Array(e.getArrayBuffer(o))),a=new Zt(i.buffer);switch(t){case"b":case"c":return a.getBooleanArray(s);case"d":return a.getFloat64Array(s);case"f":return a.getFloat32Array(s);case"i":return a.getInt32Array(s);case"l":return a.getInt64Array(s)}break;default:throw new Error("THREE.FBXLoader: Unknown property type "+t)}}}class Zt{constructor(e,t){this.dv=new DataView(e),this.offset=0,this.littleEndian=void 0===t||t,this._textDecoder=new TextDecoder}getOffset(){return this.offset}size(){return this.dv.buffer.byteLength}skip(e){this.offset+=e}getBoolean(){return!(1&~this.getUint8())}getBooleanArray(e){const t=[];for(let n=0;n=0&&(n=new Uint8Array(this.dv.buffer,t,s)),this._textDecoder.decode(n)}}class Jt{add(e,t){this[e]=t}}function Qt(e){const t=e.match(/FBXVersion: (\d+)/);if(t){return parseInt(t[1])}throw new Error("THREE.FBXLoader: Cannot find the version number for the file given.")}function en(e){return e/46186158e3}const tn=[];function nn(e,t,n,s){let r;switch(s.mappingType){case"ByPolygonVertex":r=e;break;case"ByPolygon":r=t;break;case"ByVertice":r=n;break;case"AllSame":r=s.indices[0]}"IndexToDirect"===s.referenceType&&(r=s.indices[r]);const o=r*s.dataSize,i=o+s.dataSize;return function(e,t,n,s){for(let r=n,o=0;r=0)throw new Error("THREE.GLTFLoader: setKTX2Loader must be called before loading KTX2 textures");return null}return t.loadTextureImage(e,r.source,o)}}class Sn{constructor(e){this.parser=e,this.name=pn.EXT_TEXTURE_WEBP}loadTexture(e){const t=this.name,n=this.parser,s=n.json,r=s.textures[e];if(!r.extensions||!r.extensions[t])return null;const o=r.extensions[t],i=s.images[o.source];let a=n.textureLoader;if(i.uri){const e=n.options.manager.getHandler(i.uri);null!==e&&(a=e)}return n.loadTextureImage(e,o.source,a)}}class En{constructor(e){this.parser=e,this.name=pn.EXT_TEXTURE_AVIF}loadTexture(e){const t=this.name,n=this.parser,s=n.json,r=s.textures[e];if(!r.extensions||!r.extensions[t])return null;const o=r.extensions[t],i=s.images[o.source];let a=n.textureLoader;if(i.uri){const e=n.options.manager.getHandler(i.uri);null!==e&&(a=e)}return n.loadTextureImage(e,o.source,a)}}class _n{constructor(e){this.name=pn.EXT_MESHOPT_COMPRESSION,this.parser=e}loadBufferView(e){const t=this.parser.json,n=t.bufferViews[e];if(n.extensions&&n.extensions[this.name]){const e=n.extensions[this.name],s=this.parser.getDependency("buffer",e.buffer),r=this.parser.options.meshoptDecoder;if(!r||!r.supported){if(t.extensionsRequired&&t.extensionsRequired.indexOf(this.name)>=0)throw new Error("THREE.GLTFLoader: setMeshoptDecoder must be called before loading compressed files");return null}return s.then(function(t){const n=e.byteOffset||0,s=e.byteLength||0,o=e.count,i=e.byteStride,a=new Uint8Array(t,n,s);return r.decodeGltfBufferAsync?r.decodeGltfBufferAsync(o,i,a,e.mode,e.filter).then(function(e){return e.buffer}):r.ready.then(function(){const t=new ArrayBuffer(o*i);return r.decodeGltfBuffer(new Uint8Array(t),o,i,a,e.mode,e.filter),t})})}return null}}class Nn{constructor(e){this.name=pn.EXT_MESH_GPU_INSTANCING,this.parser=e}createNodeMesh(e){const t=this.parser.json,n=t.nodes[e];if(!n.extensions||!n.extensions[this.name]||void 0===n.mesh)return null;const s=t.meshes[n.mesh];for(const e of s.primitives)if(e.mode!==Bn.TRIANGLES&&e.mode!==Bn.TRIANGLE_STRIP&&e.mode!==Bn.TRIANGLE_FAN&&void 0!==e.mode)return null;const r=n.extensions[this.name].attributes,o=[],i={};for(const e in r)o.push(this.parser.getDependency("accessor",r[e]).then(t=>(i[e]=t,i[e])));return o.length<1?null:(o.push(this.parser.createNodeMesh(e)),Promise.all(o).then(e=>{const t=e.pop(),n=t.isGroup?t.children:[t],s=e[0].count,r=[];for(const e of n){const t=new V,n=new Re,o=new ce,a=new Re(1,1,1),c=new b(e.geometry,e.material,s);for(let e=0;e-1,o=r?e.match(/Firefox\/([0-9]+)\./)[1]:-1}"undefined"==typeof createImageBitmap||n&&s<17||r&&o<98?this.textureLoader=new Te(this.options.manager):this.textureLoader=new w(this.options.manager),this.textureLoader.setCrossOrigin(this.options.crossOrigin),this.textureLoader.setRequestHeader(this.options.requestHeader),this.fileLoader=new v(this.options.manager),this.fileLoader.setResponseType("arraybuffer"),"use-credentials"===this.options.crossOrigin&&this.fileLoader.setWithCredentials(!0)}setExtensions(e){this.extensions=e}setPlugins(e){this.plugins=e}parse(e,t){const n=this,s=this.json,r=this.extensions;this.cache.removeAll(),this.nodeCache={},this._invokeAll(function(e){return e._markDefs&&e._markDefs()}),Promise.all(this._invokeAll(function(e){return e.beforeRoot&&e.beforeRoot()})).then(function(){return Promise.all([n.getDependencies("scene"),n.getDependencies("animation"),n.getDependencies("camera")])}).then(function(t){const o={scene:t[0][s.scene||0],scenes:t[0],animations:t[1],cameras:t[2],asset:s.asset,parser:n,userData:{}};return Qn(r,o,s),es(o,s),Promise.all(n._invokeAll(function(e){return e.afterRoot&&e.afterRoot(o)})).then(function(){for(const e of o.scenes)e.updateMatrixWorld();e(o)})}).catch(t)}_markDefs(){const e=this.json.nodes||[],t=this.json.skins||[],n=this.json.meshes||[];for(let n=0,s=t.length;n{const n=this.associations.get(e);null!=n&&this.associations.set(t,n);for(const[n,s]of e.children.entries())r(s,t.children[n])};return r(n,s),s.name+="_instance_"+e.uses[t]++,s}_invokeOne(e){const t=Object.values(this.plugins);t.push(this);for(let n=0;n=2&&f.setY(t,h[e*o+1]),o>=3&&f.setZ(t,h[e*o+2]),o>=4&&f.setW(t,h[e*o+3]),o>=5)throw new Error("THREE.GLTFLoader: Unsupported itemSize in sparse BufferAttribute.")}f.normalized=p}return f})}loadTexture(e){const t=this.json,n=this.options,s=t.textures[e].source,r=t.images[s];let o=this.textureLoader;if(r.uri){const e=n.manager.getHandler(r.uri);null!==e&&(o=e)}return this.loadTextureImage(e,s,o)}loadTextureImage(e,t,n){const s=this,r=this.json,o=r.textures[e],i=r.images[t],a=(i.uri||i.bufferView)+":"+o.sampler;if(this.textureCache[a])return this.textureCache[a];const c=this.loadImageSource(t,n).then(function(t){t.flipY=!1,t.name=o.name||i.name||"",""===t.name&&"string"==typeof i.uri&&!1===i.uri.startsWith("data:image/")&&(t.name=i.uri);const n=(r.samplers||{})[o.sampler]||{};return t.magFilter=Gn[n.magFilter]||C,t.minFilter=Gn[n.minFilter]||O,t.wrapS=zn[n.wrapS]||ue,t.wrapT=zn[n.wrapT]||ue,t.generateMipmaps=!t.isCompressedTexture&&t.minFilter!==$&&t.minFilter!==C,s.associations.set(t,{textures:e}),t}).catch(function(){return null});return this.textureCache[a]=c,c}loadImageSource(e,t){const n=this,s=this.json,r=this.options;if(void 0!==this.sourceCache[e])return this.sourceCache[e].then(e=>e.clone());const o=s.images[e],i=self.URL||self.webkitURL;let a=o.uri||"",c=!1;if(void 0!==o.bufferView)a=n.getDependency("bufferView",o.bufferView).then(function(e){c=!0;const t=new Blob([e],{type:o.mimeType});return a=i.createObjectURL(t),a});else if(void 0===o.uri)throw new Error("THREE.GLTFLoader: Image "+e+" is missing URI and bufferView");const l=Promise.resolve(a).then(function(e){return new Promise(function(n,s){let o=n;!0===t.isImageBitmapLoader&&(o=function(e){const t=new ye(e);t.needsUpdate=!0,n(t)}),t.load(U.resolveURL(e,r.path),o,void 0,s)})}).then(function(e){var t;return!0===c&&i.revokeObjectURL(a),es(e,o),e.userData.mimeType=o.mimeType||((t=o.uri).search(/\.jpe?g($|\?)/i)>0||0===t.search(/^data\:image\/jpeg/)?"image/jpeg":t.search(/\.webp($|\?)/i)>0||0===t.search(/^data\:image\/webp/)?"image/webp":t.search(/\.ktx2($|\?)/i)>0||0===t.search(/^data\:image\/ktx2/)?"image/ktx2":"image/png"),e}).catch(function(e){throw e});return this.sourceCache[e]=l,l}assignTexture(e,t,n,s){const r=this;return this.getDependency("texture",n.index).then(function(o){if(!o)return null;if(void 0!==n.texCoord&&n.texCoord>0&&((o=o.clone()).channel=n.texCoord),r.extensions[pn.KHR_TEXTURE_TRANSFORM]){const e=void 0!==n.extensions?n.extensions[pn.KHR_TEXTURE_TRANSFORM]:void 0;if(e){const t=r.associations.get(o);o=r.extensions[pn.KHR_TEXTURE_TRANSFORM].extendTexture(o,e),r.associations.set(o,t)}}return void 0!==s&&(o.colorSpace=s),e[t]=o,o})}assignFinalMaterial(e){const t=e.geometry;let n=e.material;const s=void 0===t.attributes.tangent,r=void 0!==t.attributes.color,o=void 0===t.attributes.normal;if(e.isPoints){const e="PointsMaterial:"+n.uuid;let t=this.cache.get(e);t||(t=new oe,j.prototype.copy.call(t,n),t.color.copy(n.color),t.map=n.map,t.sizeAttenuation=!1,this.cache.add(e,t)),n=t}else if(e.isLine){const e="LineBasicMaterial:"+n.uuid;let t=this.cache.get(e);t||(t=new N,j.prototype.copy.call(t,n),t.color.copy(n.color),t.map=n.map,this.cache.add(e,t)),n=t}if(s||r||o){let e="ClonedMaterial:"+n.uuid+":";s&&(e+="derivative-tangents:"),r&&(e+="vertex-colors:"),o&&(e+="flat-shading:");let t=this.cache.get(e);t||(t=n.clone(),r&&(t.vertexColors=!0),o&&(t.flatShading=!0),s&&(t.normalScale&&(t.normalScale.y*=-1),t.clearcoatNormalScale&&(t.clearcoatNormalScale.y*=-1)),this.cache.add(e,t),this.associations.set(t,this.associations.get(n))),n=t}e.material=n}getMaterialType(){return q}loadMaterial(e){const t=this,n=this.json,s=this.extensions,r=n.materials[e];let o;const i={},a=[];if((r.extensions||{})[pn.KHR_MATERIALS_UNLIT]){const e=s[pn.KHR_MATERIALS_UNLIT];o=e.getMaterialType(),a.push(e.extendParams(i,r,t))}else{const n=r.pbrMetallicRoughness||{};if(i.color=new u(1,1,1),i.opacity=1,Array.isArray(n.baseColorFactor)){const e=n.baseColorFactor;i.color.setRGB(e[0],e[1],e[2],D),i.opacity=e[3]}void 0!==n.baseColorTexture&&a.push(t.assignTexture(i,"map",n.baseColorTexture,he)),i.metalness=void 0!==n.metallicFactor?n.metallicFactor:1,i.roughness=void 0!==n.roughnessFactor?n.roughnessFactor:1,void 0!==n.metallicRoughnessTexture&&(a.push(t.assignTexture(i,"metalnessMap",n.metallicRoughnessTexture)),a.push(t.assignTexture(i,"roughnessMap",n.metallicRoughnessTexture))),o=this._invokeOne(function(t){return t.getMaterialType&&t.getMaterialType(e)}),a.push(Promise.all(this._invokeAll(function(t){return t.extendMaterialParams&&t.extendMaterialParams(e,i)})))}!0===r.doubleSided&&(i.side=f);const c=r.alphaMode||Yn;if(c===Zn?(i.transparent=!0,i.depthWrite=!1):(i.transparent=!1,c===$n&&(i.alphaTest=void 0!==r.alphaCutoff?r.alphaCutoff:.5)),void 0!==r.normalTexture&&o!==z&&(a.push(t.assignTexture(i,"normalMap",r.normalTexture)),i.normalScale=new Ie(1,1),void 0!==r.normalTexture.scale)){const e=r.normalTexture.scale;i.normalScale.set(e,e)}if(void 0!==r.occlusionTexture&&o!==z&&(a.push(t.assignTexture(i,"aoMap",r.occlusionTexture)),void 0!==r.occlusionTexture.strength&&(i.aoMapIntensity=r.occlusionTexture.strength)),void 0!==r.emissiveFactor&&o!==z){const e=r.emissiveFactor;i.emissive=(new u).setRGB(e[0],e[1],e[2],D)}return void 0!==r.emissiveTexture&&o!==z&&a.push(t.assignTexture(i,"emissiveMap",r.emissiveTexture,he)),Promise.all(a).then(function(){const n=new o(i);return r.name&&(n.name=r.name),es(n,r),t.associations.set(n,{materials:e}),r.extensions&&Qn(s,n,r),n})}createUniqueName(e){const t=ae.sanitizeNodeName(e||"");return t in this.nodeNamesUsed?t+"_"+ ++this.nodeNamesUsed[t]:(this.nodeNamesUsed[t]=0,t)}loadGeometries(e){const t=this,n=this.extensions,s=this.primitiveCache;function r(e){return n[pn.KHR_DRACO_MESH_COMPRESSION].decodePrimitive(e,t).then(function(n){return as(n,e,t)})}const o=[];for(let n=0,i=e.length;n0&&ts(h,r),h.name=t.createUniqueName(r.name||"mesh_"+e),es(h,r),u.extensions&&Qn(s,h,u),t.assignFinalMaterial(h),c.push(h)}for(let n=0,s=c.length;n1?new x:1===t.length?t[0]:new ee,a!==t[0])for(let e=0,n=t.length;e1){const e=s.associations.get(a);s.associations.set(a,{...e})}}else s.associations.set(a,{});return s.associations.get(a).nodes=e,a}),this.nodeCache[e]}loadScene(e){const t=this.extensions,n=this.json.scenes[e],s=this,r=new x;n.name&&(r.name=s.createUniqueName(n.name)),es(r,n),n.extensions&&Qn(t,r,n);const o=n.nodes||[],i=[];for(let e=0,t=o.length;e{const t=new Map;for(const[e,n]of s.associations)(e instanceof j||e instanceof ye)&&t.set(e,n);return e.traverse(e=>{const n=s.associations.get(e);null!=n&&t.set(e,n)}),t})(r),r})}_createAnimationTracks(e,t,n,s,r){const o=[],i=e.name?e.name:e.uuid,a=[];let c;switch(Wn[r.path]===Wn.weights?e.traverse(function(e){e.morphTargetInfluences&&a.push(e.name?e.name:e.uuid)}):a.push(i),Wn[r.path]){case Wn.weights:c=Q;break;case Wn.rotation:c=le;break;case Wn.translation:case Wn.scale:c=Se;break;default:if(1===n.itemSize)c=Q;else c=Se}const l=void 0!==s.interpolation?qn[s.interpolation]:E,u=this._getArrayFromAccessor(n);for(let e=0,n=a.length;e=2.0 are supported.")));const c=new is(r,{path:t||this.resourcePath||"",crossOrigin:this.crossOrigin,requestHeader:this.requestHeader,manager:this.manager,ktx2Loader:this.ktx2Loader,meshoptDecoder:this.meshoptDecoder});c.fileLoader.setRequestHeader(this.requestHeader);for(let e=0;e=0&&i[t]}}c.setExtensions(o),c.setPlugins(i),c.parse(n,s)}parseAsync(e,t){const n=this;return new Promise(function(s,r){n.parse(e,t,s,r)})}},ls=Array.from({length:3},()=>({loader:new Kt,isUsed:!1}));let us=[];const hs=Array.from({length:3},()=>({loader:new Te,isUsed:!1}));let ps=[];const ds=Array.from({length:3},()=>({loader:new r,isUsed:!1}));let fs=[];const ms=e=>ys(e,ls,us),gs=e=>ys(e,hs,ps),vs=e=>ys(e,ds,fs),ys=(e,t,n)=>{const s=t.find(e=>!e.isUsed);s?(s.isUsed=!0,e(s.loader)):n.push(t=>{e(t.loader),t.isUsed=!0})},Ts=(e,t,n)=>{const s=t.find(t=>t.loader===e);if(s)if(n.length>0){const e=n.shift();e&&e(s)}else s.isUsed=!1},xs=({list:e,onElementLoaded:t,onComplete:n,onError:s})=>{if(e.length>0){const{url:r}=e[0];cs.load(r,({scene:r,animations:o})=>{t({...e[0],gltfModel:{scene:r,animations:o}}),e.shift(),xs({list:e,onElementLoaded:t,onComplete:n,onError:s})},void 0,e=>s(String(e)))}else n()},ws=(e,t)=>{const n=[];return new Promise((s,r)=>{if(e.length>0){const o=[...e];for(;o.length>0;){const{url:e,id:i}=o[0],a=o[0];o.shift(),ms(o=>o.load(e,e=>{var r;r={...a,id:i,fbxModel:e},n.push(r),t(),Ts(o,ls,us),ls.some(e=>e.isUsed)||s(n)},void 0,t=>r(new Error(`Something wrong happened with an FBX model: ${i}, url: ${e}, error: ${t}`))))}}else s([])})},As={},bs={},Is={},Rs={},Ms={},Ss=({id:e,fbxModel:t})=>{As[e]=t},Es=e=>{const t=st(As[e]);return t.animations=[...As[e].animations],t},_s=({id:e,fbxModel:t})=>{Ms[e]=t.animations[0]},Ns=e=>Ms[e],Ls=({id:e,gltfModel:t})=>{bs[e]=t},Ps=e=>bs[e],Cs=({id:e,texture:t})=>{Is[e]=t},Os=e=>Is[e]||null,ks=({id:e,audioBuffer:t})=>{Rs[e]=t},Ds=e=>Rs[e]||null,Fs=({material:e,materialConfig:t={texture:{id:""},color:16777215,alphaTest:.5}})=>{"map"in e&&(e.map=t?.texture?.id?Os(t.texture.id):null),"alphaTest"in e&&(e.alphaTest=t?.alphaTest||.5),"color"in e&&(e.color=new u(t?.color||16777215))},Us=(e={materialType:void 0,texture:{id:"",flipY:!0},color:16777215,alphaTest:.5})=>{let t=null;if(e instanceof Array)t=e.map(e=>Us(e));else if(e.materialType){const n=e?.texture?.id?Os(e.texture.id):null;n&&(n.flipY=e?.texture?.flipY??!0),t=new e.materialType({map:n,alphaTest:e.alphaTest||.5,color:new u(e?.color||16777215)})}return t},js=()=>{Object.entries(Is).forEach(([e,t])=>{t.dispose(),delete Is[e]}),Object.entries(As).forEach(([e,t])=>{ze(t),delete As[e]}),Object.entries(bs).forEach(([e,t])=>{ze(t.scene),delete bs[e]})},Hs=({textures:e,gltfModels:t,fbxModels:n,fbxSkeletonAnimations:s,audio:r,onProgress:o,verbose:i=!0})=>new Promise(i=>{const a={fbxModels:[]},c=e.length+t.length+n.length+s.length+r.length;let l=0;const u=()=>{l++,o&&o(l/c)};((e,t)=>{const n=[];return new Promise((s,r)=>{if(e.length>0){const o=[...e];for(;o.length>0;){const{url:e,id:i}=o[0];o.shift(),gs(o=>o.load(e,r=>{var a;r.wrapS=ue,r.wrapT=ue,a={id:i,url:e,texture:r},n.push(a),t(),Ts(o,hs,ps),hs.some(e=>e.isUsed)||s(n)},void 0,t=>r(new Error(`Something wrong happened with a texture: ${i}, url: ${e}, error: ${t}`))))}}else s([])})})(e,u).then(e=>{e.forEach(e=>{e.texture.colorSpace=he,Cs(e)}),((e,t)=>{const n=[],s=e=>{n.push(e),t()};return new Promise((t,r)=>{xs({list:[...e],onElementLoaded:s,onComplete:()=>t(n),onError:e=>r(new Error(`Something wrong happened: ${e}`))})})})(t,u).then(e=>{e.forEach(e=>{const t=Us(e.material);let n=0;e.gltfModel.scene.traverse(s=>{if(s.isMesh){const r=s;r.castShadow=!0,r.receiveShadow=!0,r.material instanceof Array?r.material=t:r.material=t instanceof Array?t[n]:t||r.material,!t&&e.material&&Fs({material:r.material,materialConfig:e.material instanceof Array?e.material[n]:e.material}),n++}}),Ls(e)}),ws(s,u).then(e=>{e.forEach(e=>{_s(e)}),ws(n,u).then(e=>{e.forEach(e=>{const t=Us(e.material);let n=0;e.fbxModel.traverse(s=>{if(s.isMesh){const r=s;r.castShadow=!0,r.receiveShadow=!0,r.material instanceof Array?r.material=t:r.material=t instanceof Array?t[n]:t||r.material,!t&&e.material&&Fs({material:r.material,materialConfig:e.material instanceof Array?e.material[n]:e.material}),n++}}),Ss(e)}),a.fbxModels=[...e],((e,t)=>{const n=[];return new Promise((s,r)=>{if(e.length>0){const o=[...e];for(;o.length>0;){const{url:e,id:i}=o[0];o.shift(),vs(o=>o.load(e,r=>{var a;a={id:i,url:e,audioBuffer:r},n.push(a),t(),Ts(o,ds,fs),ds.some(e=>e.isUsed)||s(n)},void 0,t=>r(new Error(`Something wrong happened with an audio: ${i}, url: ${e}, error: ${t}`))))}}else s([])})})(r,u).then(e=>{e.forEach(e=>ks(e)),i(a)}).catch(e=>{})}).catch(e=>{})})})}).catch(e=>{})});class Bs extends _{constructor(e,t=1,n=16,s=2){const r=new c,o=new Float32Array(3*(3*(n+2*s)+3));r.setAttribute("position",new a(o,3));const i=new N({color:65280});super(r,[new N({color:16776960}),i]),this.audio=e,this.range=t,this.divisionsInnerAngle=n,this.divisionsOuterAngle=s,this.type="PositionalAudioHelper",this.update()}update(){const e=this.audio,t=this.range,n=this.divisionsInnerAngle,s=this.divisionsOuterAngle,r=H.degToRad(e.panner.coneInnerAngle),o=H.degToRad(e.panner.coneOuterAngle),i=r/2,a=o/2;let c,l,u=0,h=0;const p=this.geometry,d=p.attributes.position;function f(e,n,s,r){const o=(n-e)/s;for(d.setXYZ(u,0,0,0),h++,c=e;c{Gs=e},Ws=({audioId:e,position:t,radius:r=1,scene:o,camera:i,cacheId:a})=>{const c=Date.now();let l;if(a&&zs[a]){const{audio:e,container:n}=zs[a];l=e,l.isPlaying&&l.stop(),n&&t&&n.position.copy(t),zs[a].lastPlayedTime=c}else{const u=Ds(e);if(!u)return;const{loop:h,volume:p,isMusic:d}={...Vs,...Gs[e]},f=new s;let m;if(t&&o&&i){l=new ie(f),l.setRefDistance(r);const e=new ge(r,32,32);m=new G(e),m.visible=!1;const n=new Bs(l,r);l.add(n),m.position.copy(t),m.add(l),o.add(m),i.add(f)}else l=new n(f);l.setBuffer(u),l.setLoop(h||!1),l.setVolume((p||1)*Ks.masterVolume*(d?Ks.musicVolume:Ks.effectsVolume)),zs[a||e]={audio:l,audioId:e,container:m,lastPlayedTime:c}}l.play()},qs=e=>{const t=Ys(e);t.audio&&t.audio.isPlaying&&t.audio.stop()},Ys=e=>zs[e]||{audio:null,audioId:"",container:void 0,lastPlayedTime:0},$s=()=>{Object.keys(zs).forEach(e=>{const{audio:t,audioId:n}=Ys(e);if(t){const{volume:e,isMusic:s}={...Vs,...Gs[n]};t.setVolume((e||1)*Ks.masterVolume*(s?Ks.musicVolume:Ks.effectsVolume))}})},Zs=e=>{Ks.masterVolume=e,$s()},Js=e=>{Ks.musicVolume=e,$s()},Qs=e=>{Ks.effectsVolume=e,$s()},er={playAudio:Ws,stopAudio:qs,setMasterVolume:Zs,setMusicVolume:Js,setEffectsVolume:Qs};export{De as AssetsUtils,Fe as AudioUtils,_e as CallbackUtils,Ne as DisposeUtils,ke as GeomUtils,Le as ObjectUtils,Pe as TimeUtils,Ce as TokenUtils,Oe as Vector3Utils}; \ No newline at end of file diff --git a/dist/three-utils.min.js.LICENSE.txt b/dist/three-utils.min.js.LICENSE.txt new file mode 100644 index 0000000..e0932b3 --- /dev/null +++ b/dist/three-utils.min.js.LICENSE.txt @@ -0,0 +1,6 @@ +/*! +fflate - fast JavaScript compression/decompression + +Licensed under MIT. https://github.com/101arrowz/fflate/blob/master/LICENSE +version 0.8.2 +*/ diff --git a/src/assets/assets.ts b/src/assets/assets.ts index 799e3ff..aabe120 100644 --- a/src/assets/assets.ts +++ b/src/assets/assets.ts @@ -1,22 +1,368 @@ -// Assets registry for textures and audio buffers -const textureRegistry = new Map(); -const audioBufferRegistry = new Map(); +import * as THREE from 'three'; +import { GLTF } from 'three/examples/jsm/loaders/GLTFLoader.js'; +import { clone } from 'three/examples/jsm/utils/SkeletonUtils.js'; +import { deepDispose } from '../dispose-utils.js'; +import { + loadAudio, + loadFBXModels, + loadGLTFModels, + loadTextures, +} from './loaders.js'; -export const registerTexture = (id: string, texture: any): void => { - textureRegistry.set(id, texture); +// Type definitions +interface FBXModelEntry { + id: string; + fbxModel: THREE.Group; + material?: MaterialConfig | MaterialConfig[]; +} + +interface GLTFModelEntry { + id: string; + gltfModel: GLTF; + material?: MaterialConfig | MaterialConfig[]; +} + +interface TextureEntry { + id: string; + texture: THREE.Texture; +} + +interface AudioBufferEntry { + id: string; + audioBuffer: AudioBuffer; +} + +interface MaterialConfig { + materialType?: new (params: any) => THREE.Material; + texture?: { + id: string; + flipY?: boolean; + }; + color?: number; + alphaTest?: number; +} + +interface LoadAssetsParams { + textures: Array<{ id: string; url: string }>; + gltfModels: Array<{ + id: string; + url: string; + material?: MaterialConfig | MaterialConfig[]; + }>; + fbxModels: Array<{ + id: string; + url: string; + material?: MaterialConfig | MaterialConfig[]; + }>; + fbxSkeletonAnimations: Array<{ id: string; url: string }>; + audio: Array<{ id: string; url: string }>; + onProgress?: (progress: number) => void; + verbose?: boolean; +} + +// Asset registries +const _fbxModels: Record = {}; +const _gltfModels: Record = {}; +const _textures: Record = {}; +const _audioBuffers: Record = {}; +const fbxSkeletonAnimations: Record = {}; + +// FBX Model functions +export const registerFBXModel = ({ + id, + fbxModel, +}: { + id: string; + fbxModel: THREE.Group; +}): void => { + _fbxModels[id] = fbxModel; +}; + +export const getFBXModel = (id: string): THREE.Group => { + const clonedModel = clone(_fbxModels[id]) as THREE.Group; + clonedModel.animations = [..._fbxModels[id].animations]; + return clonedModel; +}; + +// FBX Skeleton Animation functions +export const registerFBXSkeletonAnimation = ({ + id, + fbxModel, +}: { + id: string; + fbxModel: THREE.Group; +}): void => { + fbxSkeletonAnimations[id] = fbxModel.animations[0]; +}; + +export const getFBXSkeletonAnimation = (id: string): THREE.AnimationClip => { + return fbxSkeletonAnimations[id]; +}; + +// GLTF Model functions +export const registerGLTFModel = ({ + id, + gltfModel, +}: { + id: string; + gltfModel: GLTF; +}): void => { + _gltfModels[id] = gltfModel; +}; + +export const getGLTFModel = (id: string): GLTF => { + return _gltfModels[id]; +}; + +// Texture functions +export const registerTexture = ({ + id, + texture, +}: { + id: string; + texture: THREE.Texture; +}): void => { + _textures[id] = texture; }; -export const getTexture = (id: string): any => { - return textureRegistry.get(id) || null; +export const getTexture = (id: string): THREE.Texture | null => { + return _textures[id] || null; }; -export const registerAudioBuffer = ( - id: string, - audioBuffer: AudioBuffer -): void => { - audioBufferRegistry.set(id, audioBuffer); +// Audio Buffer functions +export const registerAudioBuffer = ({ + id, + audioBuffer, +}: { + id: string; + audioBuffer: AudioBuffer; +}): void => { + _audioBuffers[id] = audioBuffer; }; export const getAudioBuffer = (id: string): AudioBuffer | null => { - return audioBufferRegistry.get(id) || null; + return _audioBuffers[id] || null; +}; + +// Material helper functions +const applyMaterialConfig = ({ + material, + materialConfig = { texture: { id: '' }, color: 0xffffff, alphaTest: 0.5 }, +}: { + material: THREE.Material; + materialConfig?: MaterialConfig; +}): void => { + if ('map' in material) { + (material as any).map = materialConfig?.texture?.id + ? getTexture(materialConfig.texture.id) + : null; + } + if ('alphaTest' in material) { + (material as any).alphaTest = materialConfig?.alphaTest || 0.5; + } + if ('color' in material) { + (material as any).color = new THREE.Color( + materialConfig?.color || 0xffffff + ); + } +}; + +const createMaterial = ( + materialConfig: MaterialConfig | MaterialConfig[] = { + materialType: undefined, + texture: { id: '', flipY: true }, + color: 0xffffff, + alphaTest: 0.5, + } +): THREE.Material | THREE.Material[] | null => { + let material: THREE.Material | THREE.Material[] | null = null; + + if (materialConfig instanceof Array) { + material = materialConfig.map( + (config) => createMaterial(config) as THREE.Material + ); + } else if (materialConfig.materialType) { + const map = materialConfig?.texture?.id + ? getTexture(materialConfig.texture.id) + : null; + if (map) { + map.flipY = materialConfig?.texture?.flipY ?? true; + } + material = new materialConfig.materialType({ + map, + alphaTest: materialConfig.alphaTest || 0.5, + color: new THREE.Color(materialConfig?.color || 0xffffff), + }); + } + return material; }; + +// Asset disposal +export const disposeAssets = (): void => { + Object.entries(_textures).forEach(([key, texture]) => { + texture.dispose(); + delete _textures[key]; + }); + Object.entries(_fbxModels).forEach(([key, fbxModel]) => { + deepDispose(fbxModel); + delete _fbxModels[key]; + }); + Object.entries(_gltfModels).forEach(([key, gltfModel]) => { + deepDispose(gltfModel.scene); + delete _gltfModels[key]; + }); +}; + +// Main asset loading function +export const loadAssets = ({ + textures, + gltfModels, + fbxModels, + fbxSkeletonAnimations, + audio, + onProgress, + verbose = true, +}: LoadAssetsParams): Promise<{ fbxModels: FBXModelEntry[] }> => + new Promise((resolve) => { + const result: { fbxModels: FBXModelEntry[] } = { fbxModels: [] }; + const assetCount = + textures.length + + gltfModels.length + + fbxModels.length + + fbxSkeletonAnimations.length + + audio.length; + let loadedCount = 0; + const updateProgress = (): void => { + loadedCount++; + onProgress && onProgress(loadedCount / assetCount); + }; + + loadTextures(textures, updateProgress) + .then((loadedTextures: TextureEntry[]) => { + loadedTextures.forEach((element) => { + element.texture.colorSpace = THREE.SRGBColorSpace; + registerTexture(element); + }); + if (verbose) { + console.log(`Textures(${loadedTextures.length}) are loaded...`); + } + + loadGLTFModels(gltfModels, updateProgress).then( + (loadedModels: GLTFModelEntry[]) => { + loadedModels.forEach((element) => { + const createdMaterial = createMaterial(element.material); + let textureIndex = 0; + element.gltfModel.scene.traverse((child) => { + if ((child as THREE.Mesh).isMesh) { + const mesh = child as THREE.Mesh; + mesh.castShadow = true; + mesh.receiveShadow = true; + if (mesh.material instanceof Array) { + mesh.material = createdMaterial as THREE.Material[]; + } else { + mesh.material = + createdMaterial instanceof Array + ? createdMaterial[textureIndex] + : (createdMaterial as THREE.Material) || mesh.material; + } + if (!createdMaterial && element.material) { + applyMaterialConfig({ + material: mesh.material as THREE.Material, + materialConfig: + element.material instanceof Array + ? element.material[textureIndex] + : element.material, + }); + } + textureIndex++; + } + }); + registerGLTFModel(element); + }); + if (verbose) { + console.log(`GLTF Models(${loadedModels.length}) are loaded...`); + } + + loadFBXModels(fbxSkeletonAnimations, updateProgress).then( + (loadedAnimations: FBXModelEntry[]) => { + loadedAnimations.forEach((element) => { + registerFBXSkeletonAnimation(element); + }); + if (verbose) { + console.log( + `FBX Skeleton Animations(${loadedAnimations.length}) are loaded...` + ); + } + + loadFBXModels(fbxModels, updateProgress) + .then((loadedModels: FBXModelEntry[]) => { + loadedModels.forEach((element) => { + const createdMaterial = createMaterial(element.material); + let textureIndex = 0; + element.fbxModel.traverse((child) => { + if ((child as THREE.Mesh).isMesh) { + const mesh = child as THREE.Mesh; + mesh.castShadow = true; + mesh.receiveShadow = true; + if (mesh.material instanceof Array) { + mesh.material = createdMaterial as THREE.Material[]; + } else { + mesh.material = + createdMaterial instanceof Array + ? createdMaterial[textureIndex] + : (createdMaterial as THREE.Material) || + mesh.material; + } + if (!createdMaterial && element.material) { + applyMaterialConfig({ + material: mesh.material as THREE.Material, + materialConfig: + element.material instanceof Array + ? element.material[textureIndex] + : element.material, + }); + } + textureIndex++; + } + }); + registerFBXModel(element); + }); + result.fbxModels = [...loadedModels]; + if (verbose) { + console.log( + `FBX Models(${loadedModels.length}) are loaded...` + ); + } + + loadAudio(audio, updateProgress) + .then((loadedAudio: AudioBufferEntry[]) => { + loadedAudio.forEach((element) => + registerAudioBuffer(element) + ); + if (verbose) { + console.log( + `Audio files(${loadedAudio.length}) are loaded...` + ); + } + resolve(result); + }) + .catch((error: unknown) => + console.error( + `Fatal error during Audio files preloader phase: ${error}` + ) + ); + }) + .catch((error: unknown) => + console.error( + `Fatal error during FBX model preloader phase: ${error}` + ) + ); + } + ); + } + ); + }) + .catch((error: unknown) => + console.error(`Fatal error during texture preloader phase: ${error}`) + ); + }); diff --git a/src/assets/loaders.ts b/src/assets/loaders.ts new file mode 100644 index 0000000..dfcd996 --- /dev/null +++ b/src/assets/loaders.ts @@ -0,0 +1,310 @@ +import * as THREE from 'three'; +import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader.js'; +import { GLTFLoader, GLTF } from 'three/examples/jsm/loaders/GLTFLoader.js'; + +// Type definitions +interface LoaderEntry { + loader: T; + isUsed: boolean; +} + +interface AssetLoadItem { + id: string; + url: string; +} + +interface FBXModelResult extends AssetLoadItem { + fbxModel: THREE.Group; +} + +interface GLTFModelResult extends AssetLoadItem { + gltfModel: GLTF; +} + +interface TextureResult extends AssetLoadItem { + texture: THREE.Texture; +} + +interface AudioResult extends AssetLoadItem { + audioBuffer: AudioBuffer; +} + +type LoaderQueue = Array<(loader: LoaderEntry) => void>; + +// Loader instances +const gltfLoader = new GLTFLoader(); + +const fbxLoaders: LoaderEntry[] = Array.from({ length: 3 }, () => ({ + loader: new FBXLoader(), + isUsed: false, +})); +let fbxLoaderQueue: LoaderQueue = []; + +const textureLoaders: LoaderEntry[] = Array.from( + { length: 3 }, + () => ({ + loader: new THREE.TextureLoader(), + isUsed: false, + }) +); +let textureLoaderQueue: LoaderQueue = []; + +const audioLoaders: LoaderEntry[] = Array.from( + { length: 3 }, + () => ({ + loader: new THREE.AudioLoader(), + isUsed: false, + }) +); +let audioLoaderQueue: LoaderQueue = []; + +// Loader getter functions +const getFBXLoader = (onComplete: (loader: FBXLoader) => void): void => + getLoader(onComplete, fbxLoaders, fbxLoaderQueue); + +const getTextureLoader = ( + onComplete: (loader: THREE.TextureLoader) => void +): void => getLoader(onComplete, textureLoaders, textureLoaderQueue); + +const getAudioLoader = ( + onComplete: (loader: THREE.AudioLoader) => void +): void => getLoader(onComplete, audioLoaders, audioLoaderQueue); + +const getLoader = ( + onComplete: (loader: T) => void, + loaders: LoaderEntry[], + loaderQueue: LoaderQueue +): void => { + const loader = loaders.find((entry) => !entry.isUsed); + if (loader) { + loader.isUsed = true; + onComplete(loader.loader); + } else { + loaderQueue.push((availableLoader) => { + onComplete(availableLoader.loader); + availableLoader.isUsed = true; + }); + } +}; + +// Loader release functions +const releaseFBXLoader = (loader: FBXLoader): void => + releaseLoader(loader, fbxLoaders, fbxLoaderQueue); + +const releaseTextureLoader = (loader: THREE.TextureLoader): void => + releaseLoader(loader, textureLoaders, textureLoaderQueue); + +const releaseAudioLoader = (loader: THREE.AudioLoader): void => + releaseLoader(loader, audioLoaders, audioLoaderQueue); + +const releaseLoader = ( + loader: T, + loaders: LoaderEntry[], + loaderQueue: LoaderQueue +): void => { + const loaderObject = loaders.find((entry) => entry.loader === loader); + + if (loaderObject) { + if (loaderQueue.length > 0) { + const callback = loaderQueue.shift(); + if (callback) { + callback(loaderObject); + } + } else { + loaderObject.isUsed = false; + } + } +}; + +// GLTF Model loading +const loadGLTFModelRoutine = ({ + list, + onElementLoaded, + onComplete, + onError, +}: { + list: AssetLoadItem[]; + onElementLoaded: (element: GLTFModelResult) => void; + onComplete: () => void; + onError: (error: string) => void; +}): void => { + if (list.length > 0) { + const { url } = list[0]; + gltfLoader.load( + url, + ({ scene, animations }) => { + onElementLoaded({ + ...list[0], + gltfModel: { scene, animations } as GLTF, + }); + list.shift(); + loadGLTFModelRoutine({ list, onElementLoaded, onComplete, onError }); + }, + undefined, + (error) => onError(String(error)) + ); + } else { + onComplete(); + } +}; + +export const loadGLTFModels = ( + list: AssetLoadItem[], + onProgress: () => void +): Promise => { + const elements: GLTFModelResult[] = []; + const onElementLoaded = (element: GLTFModelResult): void => { + elements.push(element); + onProgress(); + }; + + const promise = new Promise((resolve, reject) => { + loadGLTFModelRoutine({ + list: [...list], // Create a copy to avoid modifying the original + onElementLoaded, + onComplete: () => resolve(elements), + onError: (error) => + reject(new Error(`Something wrong happened: ${error}`)), + }); + }); + + return promise; +}; + +export const loadFBXModels = ( + list: AssetLoadItem[], + onProgress: () => void +): Promise => { + const elements: FBXModelResult[] = []; + const onElementLoaded = (element: FBXModelResult): void => { + elements.push(element); + onProgress(); + }; + + const promise = new Promise((resolve, reject) => { + if (list.length > 0) { + const listCopy = [...list]; // Create a copy to avoid modifying the original + while (listCopy.length > 0) { + const { url, id } = listCopy[0]; + const current = listCopy[0]; + listCopy.shift(); + getFBXLoader((fbxLoader) => + fbxLoader.load( + url, + (fbxModel) => { + onElementLoaded({ ...current, id, fbxModel }); + releaseFBXLoader(fbxLoader); + + if (!fbxLoaders.some((entry) => entry.isUsed)) { + resolve(elements); + } + }, + undefined, + (error) => + reject( + new Error( + `Something wrong happened with an FBX model: ${id}, url: ${url}, error: ${error}` + ) + ) + ) + ); + } + } else { + resolve([]); + } + }); + return promise; +}; + +export const loadTextures = ( + list: AssetLoadItem[], + onProgress: () => void +): Promise => { + const elements: TextureResult[] = []; + const onElementLoaded = (element: TextureResult): void => { + elements.push(element); + onProgress(); + }; + + const promise = new Promise((resolve, reject) => { + if (list.length > 0) { + const listCopy = [...list]; // Create a copy to avoid modifying the original + while (listCopy.length > 0) { + const { url, id } = listCopy[0]; + listCopy.shift(); + getTextureLoader((textureLoader) => + textureLoader.load( + url, + (texture) => { + texture.wrapS = THREE.RepeatWrapping; + texture.wrapT = THREE.RepeatWrapping; + + onElementLoaded({ id, url, texture }); + releaseTextureLoader(textureLoader); + + if (!textureLoaders.some((entry) => entry.isUsed)) { + resolve(elements); + } + }, + undefined, + (error) => + reject( + new Error( + `Something wrong happened with a texture: ${id}, url: ${url}, error: ${error}` + ) + ) + ) + ); + } + } else { + resolve([]); + } + }); + + return promise; +}; + +export const loadAudio = ( + list: AssetLoadItem[], + onProgress: () => void +): Promise => { + const elements: AudioResult[] = []; + const onElementLoaded = (element: AudioResult): void => { + elements.push(element); + onProgress(); + }; + + const promise = new Promise((resolve, reject) => { + if (list.length > 0) { + const listCopy = [...list]; // Create a copy to avoid modifying the original + while (listCopy.length > 0) { + const { url, id } = listCopy[0]; + listCopy.shift(); + getAudioLoader((audioLoader) => + audioLoader.load( + url, + (audioBuffer) => { + onElementLoaded({ id, url, audioBuffer }); + releaseAudioLoader(audioLoader); + + if (!audioLoaders.some((entry) => entry.isUsed)) { + resolve(elements); + } + }, + undefined, + (error) => + reject( + new Error( + `Something wrong happened with an audio: ${id}, url: ${url}, error: ${error}` + ) + ) + ) + ); + } + } else { + resolve([]); + } + }); + + return promise; +}; diff --git a/src/dispose-utils.ts b/src/dispose-utils.ts index 0a255c0..9845f51 100644 --- a/src/dispose-utils.ts +++ b/src/dispose-utils.ts @@ -13,8 +13,8 @@ export const disposeMaterials = ( } }; -export const deepDispose = (container: THREE.Mesh): void => { - const { isMesh, material, geometry } = container; +export const deepDispose = (container: THREE.Object3D): void => { + const { isMesh, material, geometry } = container as any; if (isMesh) { if (material) { disposeMaterials(material); From 49e645cc2bc2808cd6f7da8d71ba2522140539fb Mon Sep 17 00:00:00 2001 From: Krisztian Somoracz Date: Thu, 16 Oct 2025 21:54:58 +0200 Subject: [PATCH 16/20] docs: add GitHub Copilot instructions for TypeScript conventions and project guidelines --- .github/copilot-instructions.md | 38 +++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 .github/copilot-instructions.md diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 0000000..f10edf5 --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,38 @@ +# GitHub Copilot Instructions for THREE Utils + +This file contains coding conventions and guidelines for the THREE Utils project to help GitHub Copilot generate consistent and appropriate code suggestions. + +## TypeScript Conventions + +- Use `type` instead of `interface` for object type definitions +- Import types with `import type { ... }` syntax +- Place complex type definitions in `src/types/` directory +- Export types with descriptive names + +## Code Style Guidelines + +- Follow existing project patterns and naming conventions +- Ensure all exported functions have JSDoc documentation +- Use strict TypeScript settings and explicit return types +- Prefer functional programming patterns where appropriate + +## Three.js Specific Guidelines + +- Always clone Three.js objects (Vector3, Matrix4, Quaternion) before modification +- Implement proper dispose patterns for Three.js resources (geometries, materials, textures) +- Use namespace-based exports for utility modules (e.g., `CallbackUtils`, `GeomUtils`) +- Maintain performance considerations for animation loops and real-time rendering + +## Testing Requirements + +- Write unit tests for all new functionality using Jest +- Place test files in `src/__tests__/` directory +- Aim for minimum 80% code coverage +- Include both positive and negative test cases + +## Module Organization + +- Keep utilities in separate files by functionality +- Use modular exports to support tree-shaking +- Maintain separate entry points for `assets` and `audio` modules +- Follow the existing file naming pattern (kebab-case) \ No newline at end of file From d00275c414792ea4a401b047b69911e7c296fbd0 Mon Sep 17 00:00:00 2001 From: Krisztian Somoracz Date: Thu, 16 Oct 2025 21:56:22 +0200 Subject: [PATCH 17/20] chore: remove dist folder from git tracking and update .gitignore --- .gitignore | 4 +- dist/assets/assets.d.ts | 73 ---------- dist/assets/assets.d.ts.map | 1 - dist/assets/assets.js | 218 ---------------------------- dist/assets/index.d.ts | 2 - dist/assets/index.d.ts.map | 1 - dist/assets/index.js | 1 - dist/assets/loaders.d.ts | 24 --- dist/assets/loaders.d.ts.map | 1 - dist/assets/loaders.js | 172 ---------------------- dist/audio/audio.d.ts | 36 ----- dist/audio/audio.d.ts.map | 1 - dist/audio/audio.js | 113 -------------- dist/audio/index.d.ts | 2 - dist/audio/index.d.ts.map | 1 - dist/audio/index.js | 1 - dist/callback-utils.d.ts | 22 --- dist/callback-utils.d.ts.map | 1 - dist/callback-utils.js | 45 ------ dist/dispose-utils.d.ts | 4 - dist/dispose-utils.d.ts.map | 1 - dist/dispose-utils.js | 29 ---- dist/geom-utils.d.ts | 5 - dist/geom-utils.d.ts.map | 1 - dist/geom-utils.js | 29 ---- dist/index.d.ts | 10 -- dist/index.d.ts.map | 1 - dist/index.js | 9 -- dist/object-utils.d.ts | 8 - dist/object-utils.d.ts.map | 1 - dist/object-utils.js | 80 ---------- dist/three-utils.min.js | 2 - dist/three-utils.min.js.LICENSE.txt | 6 - dist/time-utils.d.ts | 7 - dist/time-utils.d.ts.map | 1 - dist/time-utils.js | 24 --- dist/token.d.ts | 2 - dist/token.d.ts.map | 1 - dist/token.js | 2 - dist/vector3-utils.d.ts | 3 - dist/vector3-utils.d.ts.map | 1 - dist/vector3-utils.js | 6 - 42 files changed, 2 insertions(+), 950 deletions(-) delete mode 100644 dist/assets/assets.d.ts delete mode 100644 dist/assets/assets.d.ts.map delete mode 100644 dist/assets/assets.js delete mode 100644 dist/assets/index.d.ts delete mode 100644 dist/assets/index.d.ts.map delete mode 100644 dist/assets/index.js delete mode 100644 dist/assets/loaders.d.ts delete mode 100644 dist/assets/loaders.d.ts.map delete mode 100644 dist/assets/loaders.js delete mode 100644 dist/audio/audio.d.ts delete mode 100644 dist/audio/audio.d.ts.map delete mode 100644 dist/audio/audio.js delete mode 100644 dist/audio/index.d.ts delete mode 100644 dist/audio/index.d.ts.map delete mode 100644 dist/audio/index.js delete mode 100644 dist/callback-utils.d.ts delete mode 100644 dist/callback-utils.d.ts.map delete mode 100644 dist/callback-utils.js delete mode 100644 dist/dispose-utils.d.ts delete mode 100644 dist/dispose-utils.d.ts.map delete mode 100644 dist/dispose-utils.js delete mode 100644 dist/geom-utils.d.ts delete mode 100644 dist/geom-utils.d.ts.map delete mode 100644 dist/geom-utils.js delete mode 100644 dist/index.d.ts delete mode 100644 dist/index.d.ts.map delete mode 100644 dist/index.js delete mode 100644 dist/object-utils.d.ts delete mode 100644 dist/object-utils.d.ts.map delete mode 100644 dist/object-utils.js delete mode 100644 dist/three-utils.min.js delete mode 100644 dist/three-utils.min.js.LICENSE.txt delete mode 100644 dist/time-utils.d.ts delete mode 100644 dist/time-utils.d.ts.map delete mode 100644 dist/time-utils.js delete mode 100644 dist/token.d.ts delete mode 100644 dist/token.d.ts.map delete mode 100644 dist/token.js delete mode 100644 dist/vector3-utils.d.ts delete mode 100644 dist/vector3-utils.d.ts.map delete mode 100644 dist/vector3-utils.js diff --git a/.gitignore b/.gitignore index cd10b09..7a817c4 100644 --- a/.gitignore +++ b/.gitignore @@ -4,8 +4,8 @@ npm-debug.log* yarn-debug.log* yarn-error.log* -# Build outputs - keep dist for npm publishing -# dist/ +# Build outputs +dist/ build/ *.tsbuildinfo diff --git a/dist/assets/assets.d.ts b/dist/assets/assets.d.ts deleted file mode 100644 index e5376bc..0000000 --- a/dist/assets/assets.d.ts +++ /dev/null @@ -1,73 +0,0 @@ -import * as THREE from 'three'; -import { GLTF } from 'three/examples/jsm/loaders/GLTFLoader.js'; -interface FBXModelEntry { - id: string; - fbxModel: THREE.Group; - material?: MaterialConfig | MaterialConfig[]; -} -interface MaterialConfig { - materialType?: new (params: any) => THREE.Material; - texture?: { - id: string; - flipY?: boolean; - }; - color?: number; - alphaTest?: number; -} -interface LoadAssetsParams { - textures: Array<{ - id: string; - url: string; - }>; - gltfModels: Array<{ - id: string; - url: string; - material?: MaterialConfig | MaterialConfig[]; - }>; - fbxModels: Array<{ - id: string; - url: string; - material?: MaterialConfig | MaterialConfig[]; - }>; - fbxSkeletonAnimations: Array<{ - id: string; - url: string; - }>; - audio: Array<{ - id: string; - url: string; - }>; - onProgress?: (progress: number) => void; - verbose?: boolean; -} -export declare const registerFBXModel: ({ id, fbxModel }: { - id: string; - fbxModel: THREE.Group; -}) => void; -export declare const getFBXModel: (id: string) => THREE.Group; -export declare const registerFBXSkeletonAnimation: ({ id, fbxModel }: { - id: string; - fbxModel: THREE.Group; -}) => void; -export declare const getFBXSkeletonAnimation: (id: string) => THREE.AnimationClip; -export declare const registerGLTFModel: ({ id, gltfModel }: { - id: string; - gltfModel: GLTF; -}) => void; -export declare const getGLTFModel: (id: string) => GLTF; -export declare const registerTexture: ({ id, texture }: { - id: string; - texture: THREE.Texture; -}) => void; -export declare const getTexture: (id: string) => THREE.Texture | null; -export declare const registerAudioBuffer: ({ id, audioBuffer }: { - id: string; - audioBuffer: AudioBuffer; -}) => void; -export declare const getAudioBuffer: (id: string) => AudioBuffer | null; -export declare const disposeAssets: () => void; -export declare const loadAssets: ({ textures, gltfModels, fbxModels, fbxSkeletonAnimations, audio, onProgress, verbose, }: LoadAssetsParams) => Promise<{ - fbxModels: FBXModelEntry[]; -}>; -export {}; -//# sourceMappingURL=assets.d.ts.map \ No newline at end of file diff --git a/dist/assets/assets.d.ts.map b/dist/assets/assets.d.ts.map deleted file mode 100644 index 545a572..0000000 --- a/dist/assets/assets.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"assets.d.ts","sourceRoot":"","sources":["../../src/assets/assets.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EAAE,IAAI,EAAE,MAAM,0CAA0C,CAAC;AAUhE,UAAU,aAAa;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,KAAK,CAAC,KAAK,CAAC;IACtB,QAAQ,CAAC,EAAE,cAAc,GAAG,cAAc,EAAE,CAAC;CAC9C;AAkBD,UAAU,cAAc;IACtB,YAAY,CAAC,EAAE,KAAK,MAAM,EAAE,GAAG,KAAK,KAAK,CAAC,QAAQ,CAAC;IACnD,OAAO,CAAC,EAAE;QACR,EAAE,EAAE,MAAM,CAAC;QACX,KAAK,CAAC,EAAE,OAAO,CAAC;KACjB,CAAC;IACF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,UAAU,gBAAgB;IACxB,QAAQ,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC7C,UAAU,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,cAAc,GAAG,cAAc,EAAE,CAAA;KAAE,CAAC,CAAC;IAC7F,SAAS,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,cAAc,GAAG,cAAc,EAAE,CAAA;KAAE,CAAC,CAAC;IAC5F,qBAAqB,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC1D,KAAK,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC1C,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAUD,eAAO,MAAM,gBAAgB,GAAI,kBAAkB;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,KAAK,CAAC,KAAK,CAAA;CAAE,KAAG,IAE1F,CAAC;AAEF,eAAO,MAAM,WAAW,GAAI,IAAI,MAAM,KAAG,KAAK,CAAC,KAI9C,CAAC;AAGF,eAAO,MAAM,4BAA4B,GAAI,kBAAkB;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,KAAK,CAAC,KAAK,CAAA;CAAE,KAAG,IAEtG,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAAI,IAAI,MAAM,KAAG,KAAK,CAAC,aAE1D,CAAC;AAGF,eAAO,MAAM,iBAAiB,GAAI,mBAAmB;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,IAAI,CAAA;CAAE,KAAG,IAEtF,CAAC;AAEF,eAAO,MAAM,YAAY,GAAI,IAAI,MAAM,KAAG,IAEzC,CAAC;AAGF,eAAO,MAAM,eAAe,GAAI,iBAAiB;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,KAAK,CAAC,OAAO,CAAA;CAAE,KAAG,IAEzF,CAAC;AAEF,eAAO,MAAM,UAAU,GAAI,IAAI,MAAM,KAAG,KAAK,CAAC,OAAO,GAAG,IAEvD,CAAC;AAGF,eAAO,MAAM,mBAAmB,GAAI,qBAAqB;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,WAAW,CAAA;CAAE,KAAG,IAEnG,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,IAAI,MAAM,KAAG,WAAW,GAAG,IAEzD,CAAC;AAoDF,eAAO,MAAM,aAAa,QAAO,IAahC,CAAC;AAGF,eAAO,MAAM,UAAU,GAAI,yFAQxB,gBAAgB,KAAG,OAAO,CAAC;IAAE,SAAS,EAAE,aAAa,EAAE,CAAA;CAAE,CA0IxD,CAAC"} \ No newline at end of file diff --git a/dist/assets/assets.js b/dist/assets/assets.js deleted file mode 100644 index 9e423d2..0000000 --- a/dist/assets/assets.js +++ /dev/null @@ -1,218 +0,0 @@ -import * as THREE from 'three'; -import { clone } from 'three/examples/jsm/utils/SkeletonUtils.js'; -import { deepDispose } from '../dispose-utils.js'; -import { loadAudio, loadFBXModels, loadGLTFModels, loadTextures, } from './loaders.js'; -// Asset registries -const _fbxModels = {}; -const _gltfModels = {}; -const _textures = {}; -const _audioBuffers = {}; -const fbxSkeletonAnimations = {}; -// FBX Model functions -export const registerFBXModel = ({ id, fbxModel }) => { - _fbxModels[id] = fbxModel; -}; -export const getFBXModel = (id) => { - const clonedModel = clone(_fbxModels[id]); - clonedModel.animations = [..._fbxModels[id].animations]; - return clonedModel; -}; -// FBX Skeleton Animation functions -export const registerFBXSkeletonAnimation = ({ id, fbxModel }) => { - fbxSkeletonAnimations[id] = fbxModel.animations[0]; -}; -export const getFBXSkeletonAnimation = (id) => { - return fbxSkeletonAnimations[id]; -}; -// GLTF Model functions -export const registerGLTFModel = ({ id, gltfModel }) => { - _gltfModels[id] = gltfModel; -}; -export const getGLTFModel = (id) => { - return _gltfModels[id]; -}; -// Texture functions -export const registerTexture = ({ id, texture }) => { - _textures[id] = texture; -}; -export const getTexture = (id) => { - return _textures[id] || null; -}; -// Audio Buffer functions -export const registerAudioBuffer = ({ id, audioBuffer }) => { - _audioBuffers[id] = audioBuffer; -}; -export const getAudioBuffer = (id) => { - return _audioBuffers[id] || null; -}; -// Material helper functions -const applyMaterialConfig = ({ material, materialConfig = { texture: { id: '' }, color: 0xffffff, alphaTest: 0.5 }, }) => { - if ('map' in material) { - material.map = materialConfig?.texture?.id - ? getTexture(materialConfig.texture.id) - : null; - } - if ('alphaTest' in material) { - material.alphaTest = materialConfig?.alphaTest || 0.5; - } - if ('color' in material) { - material.color = new THREE.Color(materialConfig?.color || 0xffffff); - } -}; -const createMaterial = (materialConfig = { - materialType: undefined, - texture: { id: '', flipY: true }, - color: 0xffffff, - alphaTest: 0.5, -}) => { - let material = null; - if (materialConfig instanceof Array) { - material = materialConfig.map((config) => createMaterial(config)); - } - else if (materialConfig.materialType) { - const map = materialConfig?.texture?.id - ? getTexture(materialConfig.texture.id) - : null; - if (map) { - map.flipY = materialConfig?.texture?.flipY ?? true; - } - material = new materialConfig.materialType({ - map, - alphaTest: materialConfig.alphaTest || 0.5, - color: new THREE.Color(materialConfig?.color || 0xffffff), - }); - } - return material; -}; -// Asset disposal -export const disposeAssets = () => { - Object.entries(_textures).forEach(([key, texture]) => { - texture.dispose(); - delete _textures[key]; - }); - Object.entries(_fbxModels).forEach(([key, fbxModel]) => { - deepDispose(fbxModel); - delete _fbxModels[key]; - }); - Object.entries(_gltfModels).forEach(([key, gltfModel]) => { - deepDispose(gltfModel.scene); - delete _gltfModels[key]; - }); -}; -// Main asset loading function -export const loadAssets = ({ textures, gltfModels, fbxModels, fbxSkeletonAnimations, audio, onProgress, verbose = true, }) => new Promise((resolve) => { - const result = { fbxModels: [] }; - const assetCount = textures.length + - gltfModels.length + - fbxModels.length + - fbxSkeletonAnimations.length + - audio.length; - let loadedCount = 0; - const updateProgress = () => { - loadedCount++; - onProgress && onProgress(loadedCount / assetCount); - }; - loadTextures(textures, updateProgress) - .then((loadedTextures) => { - loadedTextures.forEach((element) => { - element.texture.colorSpace = THREE.SRGBColorSpace; - registerTexture(element); - }); - if (verbose) { - console.log(`Textures(${loadedTextures.length}) are loaded...`); - } - loadGLTFModels(gltfModels, updateProgress) - .then((loadedModels) => { - loadedModels.forEach((element) => { - const createdMaterial = createMaterial(element.material); - let textureIndex = 0; - element.gltfModel.scene.traverse((child) => { - if (child.isMesh) { - const mesh = child; - mesh.castShadow = true; - mesh.receiveShadow = true; - if (mesh.material instanceof Array) { - mesh.material = createdMaterial; - } - else { - mesh.material = - createdMaterial instanceof Array - ? createdMaterial[textureIndex] - : createdMaterial || mesh.material; - } - if (!createdMaterial && element.material) { - applyMaterialConfig({ - material: mesh.material, - materialConfig: element.material instanceof Array - ? element.material[textureIndex] - : element.material, - }); - } - textureIndex++; - } - }); - registerGLTFModel(element); - }); - if (verbose) { - console.log(`GLTF Models(${loadedModels.length}) are loaded...`); - } - loadFBXModels(fbxSkeletonAnimations, updateProgress) - .then((loadedAnimations) => { - loadedAnimations.forEach((element) => { - registerFBXSkeletonAnimation(element); - }); - if (verbose) { - console.log(`FBX Skeleton Animations(${loadedAnimations.length}) are loaded...`); - } - loadFBXModels(fbxModels, updateProgress) - .then((loadedModels) => { - loadedModels.forEach((element) => { - const createdMaterial = createMaterial(element.material); - let textureIndex = 0; - element.fbxModel.traverse((child) => { - if (child.isMesh) { - const mesh = child; - mesh.castShadow = true; - mesh.receiveShadow = true; - if (mesh.material instanceof Array) { - mesh.material = createdMaterial; - } - else { - mesh.material = - createdMaterial instanceof Array - ? createdMaterial[textureIndex] - : createdMaterial || mesh.material; - } - if (!createdMaterial && element.material) { - applyMaterialConfig({ - material: mesh.material, - materialConfig: element.material instanceof Array - ? element.material[textureIndex] - : element.material, - }); - } - textureIndex++; - } - }); - registerFBXModel(element); - }); - result.fbxModels = [...loadedModels]; - if (verbose) { - console.log(`FBX Models(${loadedModels.length}) are loaded...`); - } - loadAudio(audio, updateProgress) - .then((loadedAudio) => { - loadedAudio.forEach((element) => registerAudioBuffer(element)); - if (verbose) { - console.log(`Audio files(${loadedAudio.length}) are loaded...`); - } - resolve(result); - }) - .catch((error) => console.error(`Fatal error during Audio files preloader phase: ${error}`)); - }) - .catch((error) => console.error(`Fatal error during FBX model preloader phase: ${error}`)); - }); - }); - }) - .catch((error) => console.error(`Fatal error during texture preloader phase: ${error}`)); -}); diff --git a/dist/assets/index.d.ts b/dist/assets/index.d.ts deleted file mode 100644 index 90e7c99..0000000 --- a/dist/assets/index.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * as AssetsUtils from './assets.js'; -//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/dist/assets/index.d.ts.map b/dist/assets/index.d.ts.map deleted file mode 100644 index 472606a..0000000 --- a/dist/assets/index.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/assets/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,WAAW,MAAM,aAAa,CAAC"} \ No newline at end of file diff --git a/dist/assets/index.js b/dist/assets/index.js deleted file mode 100644 index a600e64..0000000 --- a/dist/assets/index.js +++ /dev/null @@ -1 +0,0 @@ -export * as AssetsUtils from './assets.js'; diff --git a/dist/assets/loaders.d.ts b/dist/assets/loaders.d.ts deleted file mode 100644 index 37d2054..0000000 --- a/dist/assets/loaders.d.ts +++ /dev/null @@ -1,24 +0,0 @@ -import * as THREE from 'three'; -import { GLTF } from 'three/examples/jsm/loaders/GLTFLoader.js'; -interface AssetLoadItem { - id: string; - url: string; -} -interface FBXModelResult extends AssetLoadItem { - fbxModel: THREE.Group; -} -interface GLTFModelResult extends AssetLoadItem { - gltfModel: GLTF; -} -interface TextureResult extends AssetLoadItem { - texture: THREE.Texture; -} -interface AudioResult extends AssetLoadItem { - audioBuffer: AudioBuffer; -} -export declare const loadGLTFModels: (list: AssetLoadItem[], onProgress: () => void) => Promise; -export declare const loadFBXModels: (list: AssetLoadItem[], onProgress: () => void) => Promise; -export declare const loadTextures: (list: AssetLoadItem[], onProgress: () => void) => Promise; -export declare const loadAudio: (list: AssetLoadItem[], onProgress: () => void) => Promise; -export {}; -//# sourceMappingURL=loaders.d.ts.map \ No newline at end of file diff --git a/dist/assets/loaders.d.ts.map b/dist/assets/loaders.d.ts.map deleted file mode 100644 index d53c7c0..0000000 --- a/dist/assets/loaders.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"loaders.d.ts","sourceRoot":"","sources":["../../src/assets/loaders.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EAAc,IAAI,EAAE,MAAM,0CAA0C,CAAC;AAQ5E,UAAU,aAAa;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;CACb;AAED,UAAU,cAAe,SAAQ,aAAa;IAC5C,QAAQ,EAAE,KAAK,CAAC,KAAK,CAAC;CACvB;AAED,UAAU,eAAgB,SAAQ,aAAa;IAC7C,SAAS,EAAE,IAAI,CAAC;CACjB;AAED,UAAU,aAAc,SAAQ,aAAa;IAC3C,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC;CACxB;AAED,UAAU,WAAY,SAAQ,aAAa;IACzC,WAAW,EAAE,WAAW,CAAC;CAC1B;AAuHD,eAAO,MAAM,cAAc,GACzB,MAAM,aAAa,EAAE,EACrB,YAAY,MAAM,IAAI,KACrB,OAAO,CAAC,eAAe,EAAE,CAiB3B,CAAC;AAEF,eAAO,MAAM,aAAa,GACxB,MAAM,aAAa,EAAE,EACrB,YAAY,MAAM,IAAI,KACrB,OAAO,CAAC,cAAc,EAAE,CAwC1B,CAAC;AAEF,eAAO,MAAM,YAAY,GACvB,MAAM,aAAa,EAAE,EACrB,YAAY,MAAM,IAAI,KACrB,OAAO,CAAC,aAAa,EAAE,CA2CzB,CAAC;AAEF,eAAO,MAAM,SAAS,GACpB,MAAM,aAAa,EAAE,EACrB,YAAY,MAAM,IAAI,KACrB,OAAO,CAAC,WAAW,EAAE,CAwCvB,CAAC"} \ No newline at end of file diff --git a/dist/assets/loaders.js b/dist/assets/loaders.js deleted file mode 100644 index 7ca9860..0000000 --- a/dist/assets/loaders.js +++ /dev/null @@ -1,172 +0,0 @@ -import * as THREE from 'three'; -import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader.js'; -import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'; -// Loader instances -const gltfLoader = new GLTFLoader(); -const fbxLoaders = Array.from({ length: 3 }, () => ({ - loader: new FBXLoader(), - isUsed: false, -})); -let fbxLoaderQueue = []; -const textureLoaders = Array.from({ length: 3 }, () => ({ - loader: new THREE.TextureLoader(), - isUsed: false, -})); -let textureLoaderQueue = []; -const audioLoaders = Array.from({ length: 3 }, () => ({ - loader: new THREE.AudioLoader(), - isUsed: false, -})); -let audioLoaderQueue = []; -// Loader getter functions -const getFBXLoader = (onComplete) => getLoader(onComplete, fbxLoaders, fbxLoaderQueue); -const getTextureLoader = (onComplete) => getLoader(onComplete, textureLoaders, textureLoaderQueue); -const getAudioLoader = (onComplete) => getLoader(onComplete, audioLoaders, audioLoaderQueue); -const getLoader = (onComplete, loaders, loaderQueue) => { - const loader = loaders.find((entry) => !entry.isUsed); - if (loader) { - loader.isUsed = true; - onComplete(loader.loader); - } - else { - loaderQueue.push((availableLoader) => { - onComplete(availableLoader.loader); - availableLoader.isUsed = true; - }); - } -}; -// Loader release functions -const releaseFBXLoader = (loader) => releaseLoader(loader, fbxLoaders, fbxLoaderQueue); -const releaseTextureLoader = (loader) => releaseLoader(loader, textureLoaders, textureLoaderQueue); -const releaseAudioLoader = (loader) => releaseLoader(loader, audioLoaders, audioLoaderQueue); -const releaseLoader = (loader, loaders, loaderQueue) => { - const loaderObject = loaders.find((entry) => entry.loader === loader); - if (loaderObject) { - if (loaderQueue.length > 0) { - const callback = loaderQueue.shift(); - if (callback) { - callback(loaderObject); - } - } - else { - loaderObject.isUsed = false; - } - } -}; -// GLTF Model loading -const loadGLTFModelRoutine = ({ list, onElementLoaded, onComplete, onError, }) => { - if (list.length > 0) { - const { url } = list[0]; - gltfLoader.load(url, ({ scene, animations }) => { - onElementLoaded({ - ...list[0], - gltfModel: { scene, animations }, - }); - list.shift(); - loadGLTFModelRoutine({ list, onElementLoaded, onComplete, onError }); - }, undefined, (error) => onError(String(error))); - } - else { - onComplete(); - } -}; -export const loadGLTFModels = (list, onProgress) => { - const elements = []; - const onElementLoaded = (element) => { - elements.push(element); - onProgress(); - }; - const promise = new Promise((resolve, reject) => { - loadGLTFModelRoutine({ - list: [...list], // Create a copy to avoid modifying the original - onElementLoaded, - onComplete: () => resolve(elements), - onError: (error) => reject(new Error(`Something wrong happened: ${error}`)), - }); - }); - return promise; -}; -export const loadFBXModels = (list, onProgress) => { - const elements = []; - const onElementLoaded = (element) => { - elements.push(element); - onProgress(); - }; - const promise = new Promise((resolve, reject) => { - if (list.length > 0) { - const listCopy = [...list]; // Create a copy to avoid modifying the original - while (listCopy.length > 0) { - const { url, id } = listCopy[0]; - const current = listCopy[0]; - listCopy.shift(); - getFBXLoader((fbxLoader) => fbxLoader.load(url, (fbxModel) => { - onElementLoaded({ ...current, id, fbxModel }); - releaseFBXLoader(fbxLoader); - if (!fbxLoaders.some((entry) => entry.isUsed)) { - resolve(elements); - } - }, undefined, (error) => reject(new Error(`Something wrong happened with an FBX model: ${id}, url: ${url}, error: ${error}`)))); - } - } - else { - resolve([]); - } - }); - return promise; -}; -export const loadTextures = (list, onProgress) => { - const elements = []; - const onElementLoaded = (element) => { - elements.push(element); - onProgress(); - }; - const promise = new Promise((resolve, reject) => { - if (list.length > 0) { - const listCopy = [...list]; // Create a copy to avoid modifying the original - while (listCopy.length > 0) { - const { url, id } = listCopy[0]; - listCopy.shift(); - getTextureLoader((textureLoader) => textureLoader.load(url, (texture) => { - texture.wrapS = THREE.RepeatWrapping; - texture.wrapT = THREE.RepeatWrapping; - onElementLoaded({ id, url, texture }); - releaseTextureLoader(textureLoader); - if (!textureLoaders.some((entry) => entry.isUsed)) { - resolve(elements); - } - }, undefined, (error) => reject(new Error(`Something wrong happened with a texture: ${id}, url: ${url}, error: ${error}`)))); - } - } - else { - resolve([]); - } - }); - return promise; -}; -export const loadAudio = (list, onProgress) => { - const elements = []; - const onElementLoaded = (element) => { - elements.push(element); - onProgress(); - }; - const promise = new Promise((resolve, reject) => { - if (list.length > 0) { - const listCopy = [...list]; // Create a copy to avoid modifying the original - while (listCopy.length > 0) { - const { url, id } = listCopy[0]; - listCopy.shift(); - getAudioLoader((audioLoader) => audioLoader.load(url, (audioBuffer) => { - onElementLoaded({ id, url, audioBuffer }); - releaseAudioLoader(audioLoader); - if (!audioLoaders.some((entry) => entry.isUsed)) { - resolve(elements); - } - }, undefined, (error) => reject(new Error(`Something wrong happened with an audio: ${id}, url: ${url}, error: ${error}`)))); - } - } - else { - resolve([]); - } - }); - return promise; -}; diff --git a/dist/audio/audio.d.ts b/dist/audio/audio.d.ts deleted file mode 100644 index 4ab48f7..0000000 --- a/dist/audio/audio.d.ts +++ /dev/null @@ -1,36 +0,0 @@ -import * as THREE from 'three'; -interface AudioConfig { - loop?: boolean; - volume?: number; - isMusic?: boolean; -} -interface PlayAudioParams { - audioId: string; - position?: THREE.Vector3; - radius?: number; - scene?: THREE.Scene; - camera?: THREE.Camera; - cacheId?: string; -} -interface AudioCacheEntry { - audio: THREE.Audio | THREE.PositionalAudio; - audioId: string; - container?: THREE.Mesh; - lastPlayedTime: number; -} -export declare const setAudioConfig: (config: Record) => void; -export declare const playAudio: ({ audioId, position, radius, scene, camera, cacheId, }: PlayAudioParams) => void; -export declare const stopAudio: (cacheId: string) => void; -export declare const getAudioCache: (cacheId: string) => AudioCacheEntry; -export declare const setMasterVolume: (masterVolume: number) => void; -export declare const setMusicVolume: (musicVolume: number) => void; -export declare const setEffectsVolume: (effectsVolume: number) => void; -declare const AudioPlayer: { - playAudio: ({ audioId, position, radius, scene, camera, cacheId, }: PlayAudioParams) => void; - stopAudio: (cacheId: string) => void; - setMasterVolume: (masterVolume: number) => void; - setMusicVolume: (musicVolume: number) => void; - setEffectsVolume: (effectsVolume: number) => void; -}; -export default AudioPlayer; -//# sourceMappingURL=audio.d.ts.map \ No newline at end of file diff --git a/dist/audio/audio.d.ts.map b/dist/audio/audio.d.ts.map deleted file mode 100644 index ac671ff..0000000 --- a/dist/audio/audio.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"audio.d.ts","sourceRoot":"","sources":["../../src/audio/audio.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,UAAU,WAAW;IACnB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,UAAU,eAAe;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,KAAK,CAAC,OAAO,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC;IACpB,MAAM,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,UAAU,eAAe;IACvB,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,KAAK,CAAC,eAAe,CAAC;IACrD,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;CACxB;AAkBD,eAAO,MAAM,cAAc,GAAI,QAAQ,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,KAAG,IAEpE,CAAC;AAEF,eAAO,MAAM,SAAS,GAAI,wDAOvB,eAAe,KAAG,IA6DpB,CAAC;AAEF,eAAO,MAAM,SAAS,GAAI,SAAS,MAAM,KAAG,IAK3C,CAAC;AAEF,eAAO,MAAM,aAAa,GAAI,SAAS,MAAM,KAAG,eAS/C,CAAC;AAgBF,eAAO,MAAM,eAAe,GAAI,cAAc,MAAM,KAAG,IAGtD,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,aAAa,MAAM,KAAG,IAGpD,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAI,eAAe,MAAM,KAAG,IAGxD,CAAC;AAEF,QAAA,MAAM,WAAW;wEA9Gd,eAAe,KAAG,IAAI;yBA+DU,MAAM,KAAG,IAAI;oCAgCF,MAAM,KAAG,IAAI;kCAKf,MAAM,KAAG,IAAI;sCAKT,MAAM,KAAG,IAAI;CAW5D,CAAC;AAEF,eAAe,WAAW,CAAC"} \ No newline at end of file diff --git a/dist/audio/audio.js b/dist/audio/audio.js deleted file mode 100644 index 8af930f..0000000 --- a/dist/audio/audio.js +++ /dev/null @@ -1,113 +0,0 @@ -import * as THREE from 'three'; -import { PositionalAudioHelper } from 'three/examples/jsm/helpers/PositionalAudioHelper.js'; -import { getAudioBuffer } from '../assets/assets.js'; -const defaultConfig = { loop: false, volume: 1, isMusic: false }; -let audioConfig = {}; -const audioCache = {}; -const coreConfig = { - masterVolume: 1, - musicVolume: 1, - effectsVolume: 1, -}; -export const setAudioConfig = (config) => { - audioConfig = config; -}; -export const playAudio = ({ audioId, position, radius = 1, scene, camera, cacheId, }) => { - const now = Date.now(); - let audio; - if (!cacheId || !audioCache[cacheId]) { - const audioBuffer = getAudioBuffer(audioId); - if (!audioBuffer) { - console.warn(`Audio buffer not found for ID: ${audioId}`); - return; - } - const { loop, volume, isMusic } = { - ...defaultConfig, - ...audioConfig[audioId], - }; - const listener = new THREE.AudioListener(); - let container; - if (position && scene && camera) { - audio = new THREE.PositionalAudio(listener); - audio.setRefDistance(radius); - const sphere = new THREE.SphereGeometry(radius, 32, 32); - container = new THREE.Mesh(sphere); - container.visible = false; - const helper = new PositionalAudioHelper(audio, radius); - audio.add(helper); - container.position.copy(position); - container.add(audio); - scene.add(container); - camera.add(listener); - } - else { - audio = new THREE.Audio(listener); - } - audio.setBuffer(audioBuffer); - audio.setLoop(loop || false); - audio.setVolume((volume || 1) * - coreConfig.masterVolume * - (isMusic ? coreConfig.musicVolume : coreConfig.effectsVolume)); - audioCache[cacheId || audioId] = { - audio, - audioId, - container, - lastPlayedTime: now, - }; - } - else { - const { audio: cachedAudio, container } = audioCache[cacheId]; - audio = cachedAudio; - if (audio.isPlaying) - audio.stop(); - if (container && position) - container.position.copy(position); - audioCache[cacheId].lastPlayedTime = now; - } - audio.play(); -}; -export const stopAudio = (cacheId) => { - const audioEntry = getAudioCache(cacheId); - if (audioEntry.audio && audioEntry.audio.isPlaying) { - audioEntry.audio.stop(); - } -}; -export const getAudioCache = (cacheId) => { - return (audioCache[cacheId] || { - audio: null, - audioId: '', - container: undefined, - lastPlayedTime: 0, - }); -}; -const updateMusicVolumes = () => { - Object.keys(audioCache).forEach((key) => { - const { audio, audioId } = getAudioCache(key); - if (audio) { - const { volume, isMusic } = { ...defaultConfig, ...audioConfig[audioId] }; - audio.setVolume((volume || 1) * - coreConfig.masterVolume * - (isMusic ? coreConfig.musicVolume : coreConfig.effectsVolume)); - } - }); -}; -export const setMasterVolume = (masterVolume) => { - coreConfig.masterVolume = masterVolume; - updateMusicVolumes(); -}; -export const setMusicVolume = (musicVolume) => { - coreConfig.musicVolume = musicVolume; - updateMusicVolumes(); -}; -export const setEffectsVolume = (effectsVolume) => { - coreConfig.effectsVolume = effectsVolume; - updateMusicVolumes(); -}; -const AudioPlayer = { - playAudio, - stopAudio, - setMasterVolume, - setMusicVolume, - setEffectsVolume, -}; -export default AudioPlayer; diff --git a/dist/audio/index.d.ts b/dist/audio/index.d.ts deleted file mode 100644 index 839eb73..0000000 --- a/dist/audio/index.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * as AudioUtils from './audio.js'; -//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/dist/audio/index.d.ts.map b/dist/audio/index.d.ts.map deleted file mode 100644 index 7f40e10..0000000 --- a/dist/audio/index.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/audio/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,UAAU,MAAM,YAAY,CAAC"} \ No newline at end of file diff --git a/dist/audio/index.js b/dist/audio/index.js deleted file mode 100644 index 944d0e4..0000000 --- a/dist/audio/index.js +++ /dev/null @@ -1 +0,0 @@ -export * as AudioUtils from './audio.js'; diff --git a/dist/callback-utils.d.ts b/dist/callback-utils.d.ts deleted file mode 100644 index d9ea54d..0000000 --- a/dist/callback-utils.d.ts +++ /dev/null @@ -1,22 +0,0 @@ -export declare const CallLimits: { - readonly NO_LIMIT: -1; - readonly CALL_1_PER_SECONDS: 1000; - readonly CALL_15_PER_SECONDS: number; - readonly CALL_30_PER_SECONDS: number; - readonly CALL_45_PER_SECONDS: number; - readonly CALL_60_PER_SECONDS: number; - readonly CALL_120_PER_SECONDS: number; -}; -interface CallWithReducerParams { - id: string; - callback: (param?: any) => void; - callLimit: number; - elapsed: number; - callbackParam?: any; - forceCallCount?: boolean; -} -export declare const callWithReducer: ({ id, callback, callLimit, elapsed, callbackParam, forceCallCount, }: CallWithReducerParams) => void; -export declare const clearCallReducerData: (id: string) => boolean; -export declare const clearAllCallReducerData: () => void; -export {}; -//# sourceMappingURL=callback-utils.d.ts.map \ No newline at end of file diff --git a/dist/callback-utils.d.ts.map b/dist/callback-utils.d.ts.map deleted file mode 100644 index e9182ba..0000000 --- a/dist/callback-utils.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"callback-utils.d.ts","sourceRoot":"","sources":["../src/callback-utils.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,UAAU;;;;;;;;CAQb,CAAC;AAOX,UAAU,qBAAqB;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,CAAC,KAAK,CAAC,EAAE,GAAG,KAAK,IAAI,CAAC;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,GAAG,CAAC;IACpB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAID,eAAO,MAAM,eAAe,GAAI,sEAO7B,qBAAqB,KAAG,IAgC1B,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAAI,IAAI,MAAM,KAAG,OAC7B,CAAC;AAEtB,eAAO,MAAM,uBAAuB,QAAO,IAE1C,CAAC"} \ No newline at end of file diff --git a/dist/callback-utils.js b/dist/callback-utils.js deleted file mode 100644 index a35e0e2..0000000 --- a/dist/callback-utils.js +++ /dev/null @@ -1,45 +0,0 @@ -export const CallLimits = { - NO_LIMIT: -1, - CALL_1_PER_SECONDS: 1000, - CALL_15_PER_SECONDS: 1000 / 15, - CALL_30_PER_SECONDS: 1000 / 30, - CALL_45_PER_SECONDS: 1000 / 45, - CALL_60_PER_SECONDS: 1000 / 60, - CALL_120_PER_SECONDS: 1000 / 120, -}; -let callData = {}; -export const callWithReducer = ({ id, callback, callLimit, elapsed, callbackParam, forceCallCount = false, }) => { - if (!elapsed) - return; - if (!callData[id]) - callData[id] = { lastUpdate: -1, callCount: 0 }; - const call = () => { - if (callbackParam) - callback(callbackParam); - else - callback(); - }; - if (callLimit === CallLimits.NO_LIMIT) { - call(); - return; - } - if (forceCallCount) { - const expectedCallCount = Math.floor(elapsed / (callLimit * 1000)); - while (callData[id].lastUpdate === -1 || - expectedCallCount > callData[id].callCount) { - call(); - callData[id].lastUpdate += callLimit; - callData[id].callCount++; - } - callData[id].lastUpdate = elapsed; - } - else if (callData[id].lastUpdate === -1 || - elapsed - callData[id].lastUpdate >= callLimit) { - call(); - callData[id].lastUpdate = elapsed; - } -}; -export const clearCallReducerData = (id) => delete callData[id]; -export const clearAllCallReducerData = () => { - callData = {}; -}; diff --git a/dist/dispose-utils.d.ts b/dist/dispose-utils.d.ts deleted file mode 100644 index 0f7582f..0000000 --- a/dist/dispose-utils.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -import * as THREE from 'three'; -export declare const disposeMaterials: (material: THREE.Material | Array) => void; -export declare const deepDispose: (container: THREE.Object3D) => void; -//# sourceMappingURL=dispose-utils.d.ts.map \ No newline at end of file diff --git a/dist/dispose-utils.d.ts.map b/dist/dispose-utils.d.ts.map deleted file mode 100644 index 408b2be..0000000 --- a/dist/dispose-utils.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"dispose-utils.d.ts","sourceRoot":"","sources":["../src/dispose-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,eAAO,MAAM,gBAAgB,GAC3B,UAAU,KAAK,CAAC,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,KAC/C,IASF,CAAC;AAEF,eAAO,MAAM,WAAW,GAAI,WAAW,KAAK,CAAC,QAAQ,KAAG,IAiBvD,CAAC"} \ No newline at end of file diff --git a/dist/dispose-utils.js b/dist/dispose-utils.js deleted file mode 100644 index e00ece3..0000000 --- a/dist/dispose-utils.js +++ /dev/null @@ -1,29 +0,0 @@ -export const disposeMaterials = (material) => { - if (material.isMaterial) { - const mat = material; - mat.map?.dispose(); - mat.map = null; - mat.dispose(); - } - else { - material.forEach(disposeMaterials); - } -}; -export const deepDispose = (container) => { - const { isMesh, material, geometry } = container; - if (isMesh) { - if (material) { - disposeMaterials(material); - container.material = null; - } - if (geometry) { - geometry.dispose(); - container.geometry = null; - } - container.parent?.remove(container); - } - else if (container.children) { - container.children.forEach(deepDispose); - container.parent?.remove(container); - } -}; diff --git a/dist/geom-utils.d.ts b/dist/geom-utils.d.ts deleted file mode 100644 index 77a0d2a..0000000 --- a/dist/geom-utils.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -import * as THREE from 'three'; -export declare const sign: (point1: THREE.Vector3, point2: THREE.Vector3, point3: THREE.Vector3) => number; -export declare const isPointInATriangle: (point: THREE.Vector3, trianglePointA: THREE.Vector3, trianglePointB: THREE.Vector3, trianglePointC: THREE.Vector3) => boolean; -export declare const yFromTriangle: (point: THREE.Vector3, trianglePointA: THREE.Vector3, trianglePointB: THREE.Vector3, trianglePointC: THREE.Vector3) => number; -//# sourceMappingURL=geom-utils.d.ts.map \ No newline at end of file diff --git a/dist/geom-utils.d.ts.map b/dist/geom-utils.d.ts.map deleted file mode 100644 index 1fb18c2..0000000 --- a/dist/geom-utils.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"geom-utils.d.ts","sourceRoot":"","sources":["../src/geom-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,eAAO,MAAM,IAAI,GACf,QAAQ,KAAK,CAAC,OAAO,EACrB,QAAQ,KAAK,CAAC,OAAO,EACrB,QAAQ,KAAK,CAAC,OAAO,KACpB,MAE4C,CAAC;AAEhD,eAAO,MAAM,kBAAkB,GAC7B,OAAO,KAAK,CAAC,OAAO,EACpB,gBAAgB,KAAK,CAAC,OAAO,EAC7B,gBAAgB,KAAK,CAAC,OAAO,EAC7B,gBAAgB,KAAK,CAAC,OAAO,KAC5B,OAMF,CAAC;AAEF,eAAO,MAAM,aAAa,GACxB,OAAO,KAAK,CAAC,OAAO,EACpB,gBAAgB,KAAK,CAAC,OAAO,EAC7B,gBAAgB,KAAK,CAAC,OAAO,EAC7B,gBAAgB,KAAK,CAAC,OAAO,KAC5B,MA2BF,CAAC"} \ No newline at end of file diff --git a/dist/geom-utils.js b/dist/geom-utils.js deleted file mode 100644 index cd87d99..0000000 --- a/dist/geom-utils.js +++ /dev/null @@ -1,29 +0,0 @@ -export const sign = (point1, point2, point3) => (point1.x - point3.x) * (point2.z - point3.z) - - (point2.x - point3.x) * (point1.z - point3.z); -export const isPointInATriangle = (point, trianglePointA, trianglePointB, trianglePointC) => { - const d1 = sign(point, trianglePointA, trianglePointB); - const d2 = sign(point, trianglePointB, trianglePointC); - const d3 = sign(point, trianglePointC, trianglePointA); - return !((d1 < 0 || d2 < 0 || d3 < 0) && (d1 > 0 || d2 > 0 || d3 > 0)); -}; -export const yFromTriangle = (point, trianglePointA, trianglePointB, trianglePointC) => { - const calc1 = (trianglePointB.x - trianglePointA.x) * - (trianglePointC.y - trianglePointA.y) - - (trianglePointC.x - trianglePointA.x) * - (trianglePointB.y - trianglePointA.y); - const calc2 = (trianglePointB.x - trianglePointA.x) * - (trianglePointC.z - trianglePointA.z) - - (trianglePointC.x - trianglePointA.x) * - (trianglePointB.z - trianglePointA.z); - const calc3 = (trianglePointB.z - trianglePointA.z) * - (trianglePointC.y - trianglePointA.y) - - (trianglePointC.z - trianglePointA.z) * - (trianglePointB.y - trianglePointA.y); - const calc4 = (trianglePointB.x - trianglePointA.x) * - (trianglePointC.z - trianglePointA.z) - - (trianglePointC.x - trianglePointA.x) * - (trianglePointB.z - trianglePointA.z); - return (trianglePointA.y + - (calc1 / calc2) * (point.z - trianglePointA.z) - - (calc3 / calc4) * (point.x - trianglePointA.x)); -}; diff --git a/dist/index.d.ts b/dist/index.d.ts deleted file mode 100644 index c80cacf..0000000 --- a/dist/index.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -export * as CallbackUtils from './callback-utils.js'; -export * as DisposeUtils from './dispose-utils.js'; -export * as ObjectUtils from './object-utils.js'; -export * as TimeUtils from './time-utils.js'; -export * as TokenUtils from './token.js'; -export * as Vector3Utils from './vector3-utils.js'; -export * as GeomUtils from './geom-utils.js'; -export * from './assets/index.js'; -export * from './audio/index.js'; -//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/dist/index.d.ts.map b/dist/index.d.ts.map deleted file mode 100644 index 3966fc5..0000000 --- a/dist/index.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,aAAa,MAAM,qBAAqB,CAAC;AACrD,OAAO,KAAK,YAAY,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,WAAW,MAAM,mBAAmB,CAAC;AACjD,OAAO,KAAK,SAAS,MAAM,iBAAiB,CAAC;AAC7C,OAAO,KAAK,UAAU,MAAM,YAAY,CAAC;AACzC,OAAO,KAAK,YAAY,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,SAAS,MAAM,iBAAiB,CAAC;AAC7C,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC"} \ No newline at end of file diff --git a/dist/index.js b/dist/index.js deleted file mode 100644 index c1c5641..0000000 --- a/dist/index.js +++ /dev/null @@ -1,9 +0,0 @@ -export * as CallbackUtils from './callback-utils.js'; -export * as DisposeUtils from './dispose-utils.js'; -export * as ObjectUtils from './object-utils.js'; -export * as TimeUtils from './time-utils.js'; -export * as TokenUtils from './token.js'; -export * as Vector3Utils from './vector3-utils.js'; -export * as GeomUtils from './geom-utils.js'; -export * from './assets/index.js'; -export * from './audio/index.js'; diff --git a/dist/object-utils.d.ts b/dist/object-utils.d.ts deleted file mode 100644 index 5f3a9f8..0000000 --- a/dist/object-utils.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -export type ObjectOperationConfig = { - skippedProperties?: Array; - applyToFirstObject?: boolean; -}; -export declare const patchObject: (objectA: T, objectB: V, config?: ObjectOperationConfig) => T; -export declare const deepMerge: (objectA: T, objectB: V, config?: ObjectOperationConfig) => T | V; -export declare const getObjectDiff: (objectA: T, objectB: V, config?: ObjectOperationConfig) => Partial; -//# sourceMappingURL=object-utils.d.ts.map \ No newline at end of file diff --git a/dist/object-utils.d.ts.map b/dist/object-utils.d.ts.map deleted file mode 100644 index 5af2da7..0000000 --- a/dist/object-utils.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"object-utils.d.ts","sourceRoot":"","sources":["../src/object-utils.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,qBAAqB,GAAG;IAClC,iBAAiB,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAClC,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B,CAAC;AAEF,eAAO,MAAM,WAAW,GAAI,CAAC,EAAE,CAAC,EAC9B,SAAS,CAAC,EACV,SAAS,CAAC,EACV,SAAQ,qBAGP,KACA,CA2BF,CAAC;AAEF,eAAO,MAAM,SAAS,GAAI,CAAC,EAAE,CAAC,EAC5B,SAAS,CAAC,EACV,SAAS,CAAC,EACV,SAAQ,qBAGP,KACA,CAAC,GAAG,CAgCN,CAAC;AAEF,eAAO,MAAM,aAAa,GAAI,CAAC,EAAE,CAAC,EAChC,SAAS,CAAC,EACV,SAAS,CAAC,EACV,SAAQ,qBAAiD,KACxD,OAAO,CAAC,CAAC,GAAG,CAAC,CA0Bf,CAAC"} \ No newline at end of file diff --git a/dist/object-utils.js b/dist/object-utils.js deleted file mode 100644 index 1c999f9..0000000 --- a/dist/object-utils.js +++ /dev/null @@ -1,80 +0,0 @@ -export const patchObject = (objectA, objectB, config = { - skippedProperties: [], - applyToFirstObject: false, -}) => { - const result = {}; - Object.keys(objectA).forEach((key) => { - if (!config.skippedProperties || !config.skippedProperties.includes(key)) { - if (typeof objectA[key] === 'object' && - objectA[key] && - objectB[key] && - !Array.isArray(objectA[key])) { - result[key] = patchObject(objectA[key], objectB[key], config); - } - else { - result[key] = - objectB[key] === 0 - ? 0 - : objectB[key] === false - ? false - : objectB[key] || objectA[key]; - if (config.applyToFirstObject) - objectA[key] = result[key]; - } - } - }); - return result; -}; -export const deepMerge = (objectA, objectB, config = { - skippedProperties: [], - applyToFirstObject: false, -}) => { - const result = {}; - Array.from(new Set([ - ...Object.keys((objectA || {})), - ...Object.keys((objectB || {})), - ])).forEach((key) => { - if (!config.skippedProperties || !config.skippedProperties.includes(key)) { - if (typeof objectA?.[key] === 'object' && - objectA?.[key] && - objectB?.[key] && - !Array.isArray(objectA[key])) { - result[key] = deepMerge(objectA[key], objectB[key], config); - } - else { - result[key] = - objectB?.[key] === 0 - ? 0 - : objectB?.[key] === false - ? false - : objectB?.[key] || objectA?.[key]; - if (config.applyToFirstObject) - objectA[key] = result[key]; - } - } - }); - return result; -}; -export const getObjectDiff = (objectA, objectB, config = { skippedProperties: [] }) => { - const result = {}; - Object.keys(objectA).forEach((key) => { - if (!config.skippedProperties || !config.skippedProperties.includes(key)) { - if (typeof objectA[key] === 'object' && - objectA[key] && - objectB[key] && - !Array.isArray(objectA[key])) { - const objectDiff = getObjectDiff(objectA[key], objectB[key], config); - if (Object.keys(objectDiff).length > 0) - result[key] = objectDiff; - } - else { - const mergedValue = objectB[key] === 0 - ? 0 - : objectB[key] || objectA[key]; - if (mergedValue !== objectA[key]) - result[key] = mergedValue; - } - } - }); - return result; -}; diff --git a/dist/three-utils.min.js b/dist/three-utils.min.js deleted file mode 100644 index d6ff931..0000000 --- a/dist/three-utils.min.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! For license information please see three-utils.min.js.LICENSE.txt */ -import{AmbientLight as e,AnimationClip as t,Audio as n,AudioListener as s,AudioLoader as r,Bone as o,Box3 as i,BufferAttribute as a,BufferGeometry as c,ClampToEdgeWrapping as l,Color as u,ColorManagement as h,Curve as p,DirectionalLight as d,DoubleSide as f,EquirectangularReflectionMapping as m,Euler as g,FileLoader as v,Float32BufferAttribute as y,FrontSide as T,Group as x,ImageBitmapLoader as w,InstancedBufferAttribute as A,InstancedMesh as b,InterleavedBuffer as I,InterleavedBufferAttribute as R,Interpolant as M,InterpolateDiscrete as S,InterpolateLinear as E,Line as _,LineBasicMaterial as N,LineLoop as L,LineSegments as P,LinearFilter as C,LinearMipmapLinearFilter as O,LinearMipmapNearestFilter as k,LinearSRGBColorSpace as D,Loader as F,LoaderUtils as U,Material as j,MathUtils as H,Matrix3 as B,Matrix4 as V,Mesh as G,MeshBasicMaterial as z,MeshLambertMaterial as K,MeshPhongMaterial as X,MeshPhysicalMaterial as W,MeshStandardMaterial as q,MirroredRepeatWrapping as Y,NearestFilter as $,NearestMipmapLinearFilter as Z,NearestMipmapNearestFilter as J,NumberKeyframeTrack as Q,Object3D as ee,OrthographicCamera as te,PerspectiveCamera as ne,PointLight as se,Points as re,PointsMaterial as oe,PositionalAudio as ie,PropertyBinding as ae,Quaternion as ce,QuaternionKeyframeTrack as le,RepeatWrapping as ue,SRGBColorSpace as he,ShapeUtils as pe,Skeleton as de,SkinnedMesh as fe,Sphere as me,SphereGeometry as ge,SpotLight as ve,Texture as ye,TextureLoader as Te,TriangleFanDrawMode as xe,TriangleStripDrawMode as we,TrianglesDrawMode as Ae,Uint16BufferAttribute as be,Vector2 as Ie,Vector3 as Re,Vector4 as Me,VectorKeyframeTrack as Se}from"THREE";var Ee={d:(e,t)=>{for(var n in t)Ee.o(t,n)&&!Ee.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r:e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})}},_e={};Ee.r(_e),Ee.d(_e,{CallLimits:()=>Ue,callWithReducer:()=>He,clearAllCallReducerData:()=>Ve,clearCallReducerData:()=>Be});var Ne={};Ee.r(Ne),Ee.d(Ne,{deepDispose:()=>ze,disposeMaterials:()=>Ge});var Le={};Ee.r(Le),Ee.d(Le,{deepMerge:()=>Xe,getObjectDiff:()=>We,patchObject:()=>Ke});var Pe={};Ee.r(Pe),Ee.d(Pe,{TimePattern:()=>qe,formatTime:()=>$e});var Ce={};Ee.r(Ce),Ee.d(Ce,{getUniqueId:()=>Je});var Oe={};Ee.r(Oe),Ee.d(Oe,{absVector3:()=>Qe});var ke={};Ee.r(ke),Ee.d(ke,{isPointInATriangle:()=>tt,sign:()=>et,yFromTriangle:()=>nt});var De={};Ee.r(De),Ee.d(De,{disposeAssets:()=>js,getAudioBuffer:()=>Ds,getFBXModel:()=>Es,getFBXSkeletonAnimation:()=>Ns,getGLTFModel:()=>Ps,getTexture:()=>Os,loadAssets:()=>Hs,registerAudioBuffer:()=>ks,registerFBXModel:()=>Ss,registerFBXSkeletonAnimation:()=>_s,registerGLTFModel:()=>Ls,registerTexture:()=>Cs});var Fe={};Ee.r(Fe),Ee.d(Fe,{default:()=>er,getAudioCache:()=>Ys,playAudio:()=>Ws,setAudioConfig:()=>Xs,setEffectsVolume:()=>Qs,setMasterVolume:()=>Zs,setMusicVolume:()=>Js,stopAudio:()=>qs});const Ue={NO_LIMIT:-1,CALL_1_PER_SECONDS:1e3,CALL_15_PER_SECONDS:1e3/15,CALL_30_PER_SECONDS:1e3/30,CALL_45_PER_SECONDS:1e3/45,CALL_60_PER_SECONDS:1e3/60,CALL_120_PER_SECONDS:1e3/120};let je={};const He=({id:e,callback:t,callLimit:n,elapsed:s,callbackParam:r,forceCallCount:o=!1})=>{if(!s)return;je[e]||(je[e]={lastUpdate:-1,callCount:0});const i=()=>{r?t(r):t()};if(n!==Ue.NO_LIMIT)if(o){const t=Math.floor(s/(1e3*n));for(;-1===je[e].lastUpdate||t>je[e].callCount;)i(),je[e].lastUpdate+=n,je[e].callCount++;je[e].lastUpdate=s}else(-1===je[e].lastUpdate||s-je[e].lastUpdate>=n)&&(i(),je[e].lastUpdate=s);else i()},Be=e=>delete je[e],Ve=()=>{je={}},Ge=e=>{if(e.isMaterial){const t=e;t.map?.dispose(),t.map=null,t.dispose()}else e.forEach(Ge)},ze=e=>{const{isMesh:t,material:n,geometry:s}=e;t?(n&&(Ge(n),e.material=null),s&&(s.dispose(),e.geometry=null),e.parent?.remove(e)):e.children&&(e.children.forEach(ze),e.parent?.remove(e))},Ke=(e,t,n={skippedProperties:[],applyToFirstObject:!1})=>{const s={};return Object.keys(e).forEach(r=>{n.skippedProperties&&n.skippedProperties.includes(r)||("object"==typeof e[r]&&e[r]&&t[r]&&!Array.isArray(e[r])?s[r]=Ke(e[r],t[r],n):(s[r]=0===t[r]?0:!1!==t[r]&&(t[r]||e[r]),n.applyToFirstObject&&(e[r]=s[r])))}),s},Xe=(e,t,n={skippedProperties:[],applyToFirstObject:!1})=>{const s={};return Array.from(new Set([...Object.keys(e||{}),...Object.keys(t||{})])).forEach(r=>{n.skippedProperties&&n.skippedProperties.includes(r)||("object"==typeof e?.[r]&&e?.[r]&&t?.[r]&&!Array.isArray(e[r])?s[r]=Xe(e[r],t[r],n):(s[r]=0===t?.[r]?0:!1!==t?.[r]&&(t?.[r]||e?.[r]),n.applyToFirstObject&&(e[r]=s[r])))}),s},We=(e,t,n={skippedProperties:[]})=>{const s={};return Object.keys(e).forEach(r=>{if(!n.skippedProperties||!n.skippedProperties.includes(r))if("object"==typeof e[r]&&e[r]&&t[r]&&!Array.isArray(e[r])){const o=We(e[r],t[r],n);Object.keys(o).length>0&&(s[r]=o)}else{const n=0===t[r]?0:t[r]||e[r];n!==e[r]&&(s[r]=n)}}),s},qe={HH_MM_SS:"HH:MM:SS",MM_SS:"MM:SS",MM_SS_MS:"MM:SS.MS"},Ye=[{pattern:"HH",routine:({hours:e})=>String(e).padStart(2,"0")},{pattern:"MM",routine:({minutes:e})=>String(e).padStart(2,"0")},{pattern:"SS",routine:({seconds:e})=>String(e).padStart(2,"0")},{pattern:"MS",routine:({milliseconds:e})=>String(e).padStart(3,"0")}],$e=(e,t)=>{const n=Math.floor(e%1e3),s=Math.floor(e/1e3%60),r=Math.floor(Math.floor(e/1e3/60)%60),o={hours:Math.floor(Math.floor(e/1e3/60)/60%24),minutes:r,seconds:s,milliseconds:n};let i=t;return Ye.forEach(({pattern:e,routine:t})=>i=i.replace(e,t(o))),i};let Ze=0;const Je=()=>Ze++,Qe=e=>(e.x=Math.abs(e.x),e.y=Math.abs(e.y),e.z=Math.abs(e.z),e),et=(e,t,n)=>(e.x-n.x)*(t.z-n.z)-(t.x-n.x)*(e.z-n.z),tt=(e,t,n,s)=>{const r=et(e,t,n),o=et(e,n,s),i=et(e,s,t);return!((r<0||o<0||i<0)&&(r>0||o>0||i>0))},nt=(e,t,n,s)=>{const r=(n.x-t.x)*(s.y-t.y)-(s.x-t.x)*(n.y-t.y),o=(n.x-t.x)*(s.z-t.z)-(s.x-t.x)*(n.z-t.z),i=(n.z-t.z)*(s.y-t.y)-(s.z-t.z)*(n.y-t.y),a=(n.x-t.x)*(s.z-t.z)-(s.x-t.x)*(n.z-t.z);return t.y+r/o*(e.z-t.z)-i/a*(e.x-t.x)};function st(e){const t=new Map,n=new Map,s=e.clone();return rt(e,s,function(e,s){t.set(s,e),n.set(e,s)}),s.traverse(function(e){if(!e.isSkinnedMesh)return;const s=e,r=t.get(e),o=r.skeleton.bones;s.skeleton=r.skeleton.clone(),s.bindMatrix.copy(r.bindMatrix),s.skeleton.bones=o.map(function(e){return n.get(e)}),s.bind(s.skeleton,s.bindMatrix)}),s}function rt(e,t,n){n(e,t);for(let s=0;s>1|(21845&yt)<<1;Tt=(61680&(Tt=(52428&Tt)>>2|(13107&Tt)<<2))>>4|(3855&Tt)<<4,vt[yt]=((65280&Tt)>>8|(255&Tt)<<8)>>1}var xt=function(e,t,n){for(var s=e.length,r=0,o=new it(t);r>c]=l}else for(i=new it(s),r=0;r>15-e[r]);return i},wt=new ot(288);for(yt=0;yt<144;++yt)wt[yt]=8;for(yt=144;yt<256;++yt)wt[yt]=9;for(yt=256;yt<280;++yt)wt[yt]=7;for(yt=280;yt<288;++yt)wt[yt]=8;var At=new ot(32);for(yt=0;yt<32;++yt)At[yt]=5;var bt=xt(wt,9,1),It=xt(At,5,1),Rt=function(e){for(var t=e[0],n=1;nt&&(t=e[n]);return t},Mt=function(e,t,n){var s=t/8|0;return(e[s]|e[s+1]<<8)>>(7&t)&n},St=function(e,t){var n=t/8|0;return(e[n]|e[n+1]<<8|e[n+2]<<16)>>(7&t)},Et=function(e){return(e+7)/8|0},_t=function(e,t,n){return(null==t||t<0)&&(t=0),(null==n||n>e.length)&&(n=e.length),new ot(e.subarray(t,n))},Nt=["unexpected EOF","invalid block type","invalid length/literal","invalid distance","stream finished","no stream handler",,"no callback","invalid UTF-8 data","extra field too long","date not in range 1980-2099","filename too long","stream finishing","invalid zip data"],Lt=function(e,t,n){var s=new Error(t||Nt[e]);if(s.code=e,Error.captureStackTrace&&Error.captureStackTrace(s,Lt),!n)throw s;return s},Pt=function(e,t,n,s){var r=e.length,o=s?s.length:0;if(!r||t.f&&!t.l)return n||new ot(0);var i=!n,a=i||2!=t.i,c=t.i;i&&(n=new ot(3*r));var l=function(e){var t=n.length;if(e>t){var s=new ot(Math.max(2*t,e));s.set(n),n=s}},u=t.f||0,h=t.p||0,p=t.b||0,d=t.l,f=t.d,m=t.m,g=t.n,v=8*r;do{if(!d){u=Mt(e,h,1);var y=Mt(e,h+1,3);if(h+=3,!y){var T=e[(N=Et(h)+4)-4]|e[N-3]<<8,x=N+T;if(x>r){c&&Lt(0);break}a&&l(p+T),n.set(e.subarray(N,x),p),t.b=p+=T,t.p=h=8*x,t.f=u;continue}if(1==y)d=bt,f=It,m=9,g=5;else if(2==y){var w=Mt(e,h,31)+257,A=Mt(e,h+10,15)+4,b=w+Mt(e,h+5,31)+1;h+=14;for(var I=new ot(b),R=new ot(19),M=0;M>4)<16)I[M++]=N;else{var P=0,C=0;for(16==N?(C=3+Mt(e,h,3),h+=2,P=I[M-1]):17==N?(C=3+Mt(e,h,7),h+=3):18==N&&(C=11+Mt(e,h,127),h+=7);C--;)I[M++]=P}}var O=I.subarray(0,w),k=I.subarray(w);m=Rt(O),g=Rt(k),d=xt(O,m,1),f=xt(k,g,1)}else Lt(1);if(h>v){c&&Lt(0);break}}a&&l(p+131072);for(var D=(1<>4;if((h+=15&P)>v){c&&Lt(0);break}if(P||Lt(2),j<256)n[p++]=j;else{if(256==j){U=h,d=null;break}var H=j-254;if(j>264){var B=ct[M=j-257];H=Mt(e,h,(1<>4;V||Lt(3),h+=15&V;k=gt[G];if(G>3){B=lt[G];k+=St(e,h)&(1<v){c&&Lt(0);break}a&&l(p+131072);var z=p+H;if(p>4>7||(e[0]<<8|e[1])%31)&&Lt(6,"invalid zlib data"),(e[1]>>5&1)==+!t&&Lt(6,"invalid zlib data: "+(32&e[1]?"need":"unexpected")+" dictionary"),2+(e[1]>>3&4)};function kt(e,t){return Pt(e.subarray(Ot(e,t&&t.dictionary),-4),{i:2},t&&t.out,t&&t.dictionary)}var Dt="undefined"!=typeof TextDecoder&&new TextDecoder;try{Dt.decode(Ct,{stream:!0})}catch(e){}"function"==typeof queueMicrotask?queueMicrotask:"function"==typeof setTimeout&&setTimeout;function Ft(e,t,n){const s=n.length-e-1;if(t>=n[s])return s-1;if(t<=n[e])return e;let r=e,o=s,i=Math.floor((r+o)/2);for(;t=n[i+1];)t=o&&(c[r][0]=c[t][0]/a[u+1][l],s=c[r][0]*a[l][u]);const h=e-1<=u?o-1:n-e;for(let e=l>=-1?1:-l;e<=h;++e)c[r][e]=(c[t][e]-c[t][e-1])/a[u+1][l+e],s+=c[r][e]*a[l+e][u];e<=u&&(c[r][o]=-c[t][o-1]/a[u+1][e],s+=c[r][o]*a[e][u]),i[o][e]=s;const p=t;t=r,r=p}}let u=n;for(let e=1;e<=s;++e){for(let t=0;t<=n;++t)i[e][t]*=u;u*=n-e}return i}(a,s,e,o,t),l=[];for(let e=0;ee.toArray()),e.startKnot=this.startKnot,e.endKnot=this.endKnot,e}fromJSON(e){return super.fromJSON(e),this.degree=e.degree,this.knots=[...e.knots],this.controlPoints=e.controlPoints.map(e=>new Me(e[0],e[1],e[2],e[3])),this.startKnot=e.startKnot,this.endKnot=e.endKnot,this}}let Vt,Gt,zt;class Kt extends F{constructor(e){super(e)}load(e,t,n,s){const r=this,o=""===r.path?U.extractUrlBase(e):r.path,i=new v(this.manager);i.setPath(r.path),i.setResponseType("arraybuffer"),i.setRequestHeader(r.requestHeader),i.setWithCredentials(r.withCredentials),i.load(e,function(n){try{t(r.parse(n,o))}catch(t){s&&s(t),r.manager.itemError(e)}},n,s)}parse(e,t){if(function(e){const t="Kaydara FBX Binary \0";return e.byteLength>=t.length&&t===ln(e,0,t.length)}(e))Vt=(new $t).parse(e);else{const t=ln(e);if(!function(e){const t=["K","a","y","d","a","r","a","\\","F","B","X","\\","B","i","n","a","r","y","\\","\\"];let n=0;function s(t){const s=e[t-1];return e=e.slice(n+t),n++,s}for(let e=0;e0,o="string"==typeof r.Content&&""!==r.Content;if(e||o){const e=this.parseImage(n[s]);t[r.RelativeFilename||r.Filename]=e}}}}for(const n in e){const s=e[n];void 0!==t[s]?e[n]=t[s]:e[n]=e[n].split("\\").pop()}return e}parseImage(e){const t=e.Content,n=e.RelativeFilename||e.Filename;let s;switch(n.slice(n.lastIndexOf(".")+1).toLowerCase()){case"bmp":s="image/bmp";break;case"jpg":case"jpeg":s="image/jpeg";break;case"png":s="image/png";break;case"tif":s="image/tiff";break;case"tga":this.manager.getHandler(".tga"),s="image/tga";break;case"webp":s="image/webp";break;default:return}if("string"==typeof t)return"data:"+s+";base64,"+t;{const e=new Uint8Array(t);return window.URL.createObjectURL(new Blob([e],{type:s}))}}parseTextures(e){const t=new Map;if("Texture"in Vt.Objects){const n=Vt.Objects.Texture;for(const s in n){const r=this.parseTexture(n[s],e);t.set(parseInt(s),r)}}return t}parseTexture(e,t){const n=this.loadTexture(e,t);n.ID=e.id,n.name=e.attrName;const s=e.WrapModeU,r=e.WrapModeV,o=void 0!==s?s.value:0,i=void 0!==r?r.value:0;if(n.wrapS=0===o?ue:l,n.wrapT=0===i?ue:l,"Scaling"in e){const t=e.Scaling.value;n.repeat.x=t[0],n.repeat.y=t[1]}if("Translation"in e){const t=e.Translation.value;n.offset.x=t[0],n.offset.y=t[1]}return n}loadTexture(e,t){const n=e.FileName.split(".").pop().toLowerCase();let s=this.manager.getHandler(`.${n}`);null===s&&(s=this.textureLoader);const r=s.path;r||s.setPath(this.textureLoader.path);const o=Gt.get(e.id).children;let i;if(void 0!==o&&o.length>0&&void 0!==t[o[0].ID]&&(i=t[o[0].ID],0!==i.indexOf("blob:")&&0!==i.indexOf("data:")||s.setPath(void 0)),void 0===i)return new ye;const a=s.load(i);return s.setPath(r),a}parseMaterials(e){const t=new Map;if("Material"in Vt.Objects){const n=Vt.Objects.Material;for(const s in n){const r=this.parseMaterial(n[s],e);null!==r&&t.set(parseInt(s),r)}}return t}parseMaterial(e,t){const n=e.id,s=e.attrName;let r=e.ShadingModel;if("object"==typeof r&&(r=r.value),!Gt.has(n))return null;const o=this.parseParameters(e,t,n);let i;switch(r.toLowerCase()){case"phong":default:i=new X;break;case"lambert":i=new K}return i.setValues(o),i.name=s,i}parseParameters(e,t,n){const s={};e.BumpFactor&&(s.bumpScale=e.BumpFactor.value),e.Diffuse?s.color=h.colorSpaceToWorking((new u).fromArray(e.Diffuse.value),he):!e.DiffuseColor||"Color"!==e.DiffuseColor.type&&"ColorRGB"!==e.DiffuseColor.type||(s.color=h.colorSpaceToWorking((new u).fromArray(e.DiffuseColor.value),he)),e.DisplacementFactor&&(s.displacementScale=e.DisplacementFactor.value),e.Emissive?s.emissive=h.colorSpaceToWorking((new u).fromArray(e.Emissive.value),he):!e.EmissiveColor||"Color"!==e.EmissiveColor.type&&"ColorRGB"!==e.EmissiveColor.type||(s.emissive=h.colorSpaceToWorking((new u).fromArray(e.EmissiveColor.value),he)),e.EmissiveFactor&&(s.emissiveIntensity=parseFloat(e.EmissiveFactor.value)),s.opacity=1-(e.TransparencyFactor?parseFloat(e.TransparencyFactor.value):0),1!==s.opacity&&0!==s.opacity||(s.opacity=e.Opacity?parseFloat(e.Opacity.value):null,null===s.opacity&&(s.opacity=1-(e.TransparentColor?parseFloat(e.TransparentColor.value[0]):0))),s.opacity<1&&(s.transparent=!0),e.ReflectionFactor&&(s.reflectivity=e.ReflectionFactor.value),e.Shininess&&(s.shininess=e.Shininess.value),e.Specular?s.specular=h.colorSpaceToWorking((new u).fromArray(e.Specular.value),he):e.SpecularColor&&"Color"===e.SpecularColor.type&&(s.specular=h.colorSpaceToWorking((new u).fromArray(e.SpecularColor.value),he));const r=this;return Gt.get(n).children.forEach(function(e){switch(e.relationship){case"Bump":s.bumpMap=r.getTexture(t,e.ID);break;case"Maya|TEX_ao_map":s.aoMap=r.getTexture(t,e.ID);break;case"DiffuseColor":case"Maya|TEX_color_map":s.map=r.getTexture(t,e.ID),void 0!==s.map&&(s.map.colorSpace=he);break;case"DisplacementColor":s.displacementMap=r.getTexture(t,e.ID);break;case"EmissiveColor":s.emissiveMap=r.getTexture(t,e.ID),void 0!==s.emissiveMap&&(s.emissiveMap.colorSpace=he);break;case"NormalMap":case"Maya|TEX_normal_map":s.normalMap=r.getTexture(t,e.ID);break;case"ReflectionColor":s.envMap=r.getTexture(t,e.ID),void 0!==s.envMap&&(s.envMap.mapping=m,s.envMap.colorSpace=he);break;case"SpecularColor":s.specularMap=r.getTexture(t,e.ID),void 0!==s.specularMap&&(s.specularMap.colorSpace=he);break;case"TransparentColor":case"TransparencyFactor":s.alphaMap=r.getTexture(t,e.ID),s.transparent=!0}}),s}getTexture(e,t){return"LayeredTexture"in Vt.Objects&&t in Vt.Objects.LayeredTexture&&(t=Gt.get(t).children[0].ID),e.get(t)}parseDeformers(){const e={},t={};if("Deformer"in Vt.Objects){const n=Vt.Objects.Deformer;for(const s in n){const r=n[s],o=Gt.get(parseInt(s));if("Skin"===r.attrType){const t=this.parseSkeleton(o,n);t.ID=s,o.parents.length,t.geometryID=o.parents[0].ID,e[s]=t}else if("BlendShape"===r.attrType){const e={id:s};e.rawTargets=this.parseMorphTargets(o,n),e.id=s,o.parents.length,t[s]=e}}}return{skeletons:e,morphTargets:t}}parseSkeleton(e,t){const n=[];return e.children.forEach(function(e){const s=t[e.ID];if("Cluster"!==s.attrType)return;const r={ID:e.ID,indices:[],weights:[],transformLink:(new V).fromArray(s.TransformLink.a)};"Indexes"in s&&(r.indices=s.Indexes.a,r.weights=s.Weights.a),n.push(r)}),{rawBones:n,bones:[]}}parseMorphTargets(e,t){const n=[];for(let s=0;s1?o=i:i.length>0?o=i[0]:(o=new X({name:F.DEFAULT_MATERIAL_NAME,color:13421772}),i.push(o)),"color"in r.attributes&&i.forEach(function(e){e.vertexColors=!0}),r.groups.length>0){let e=!1;for(let t=0,n=r.groups.length;t=i.length)&&(n.materialIndex=i.length,e=!0)}if(e){const e=new X;i.push(e)}}return r.FBX_Deformer?(s=new fe(r,o),s.normalizeSkinWeights()):s=new G(r,o),s}createCurve(e,t){const n=e.children.reduce(function(e,n){return t.has(n.ID)&&(e=t.get(n.ID)),e},null),s=new N({name:F.DEFAULT_MATERIAL_NAME,color:3342591,linewidth:1});return new _(n,s)}getTransformData(e,t){const n={};"InheritType"in t&&(n.inheritType=parseInt(t.InheritType.value)),n.eulerOrder=an("RotationOrder"in t?t.RotationOrder.value:0),"Lcl_Translation"in t&&(n.translation=t.Lcl_Translation.value),"PreRotation"in t&&(n.preRotation=t.PreRotation.value),"Lcl_Rotation"in t&&(n.rotation=t.Lcl_Rotation.value),"PostRotation"in t&&(n.postRotation=t.PostRotation.value),"Lcl_Scaling"in t&&(n.scale=t.Lcl_Scaling.value),"ScalingOffset"in t&&(n.scalingOffset=t.ScalingOffset.value),"ScalingPivot"in t&&(n.scalingPivot=t.ScalingPivot.value),"RotationOffset"in t&&(n.rotationOffset=t.RotationOffset.value),"RotationPivot"in t&&(n.rotationPivot=t.RotationPivot.value),e.userData.transformData=n}setLookAtProperties(e,t){if("LookAtProperty"in t){Gt.get(e.ID).children.forEach(function(t){if("LookAtProperty"===t.relationship){const n=Vt.Objects.Model[t.ID];if("Lcl_Translation"in n){const t=n.Lcl_Translation.value;void 0!==e.target?(e.target.position.fromArray(t),zt.add(e.target)):e.lookAt((new Re).fromArray(t))}}})}}bindSkeleton(e,t,n){const s=this.parsePoseNodes();for(const r in e){const o=e[r];Gt.get(parseInt(o.ID)).parents.forEach(function(e){if(t.has(e.ID)){const t=e.ID;Gt.get(t).parents.forEach(function(e){if(n.has(e.ID)){n.get(e.ID).bind(new de(o.bones),s[e.ID])}})}})}}parsePoseNodes(){const e={};if("Pose"in Vt.Objects){const t=Vt.Objects.Pose;for(const n in t)if("BindPose"===t[n].attrType&&t[n].NbPoseNodes>0){const s=t[n].PoseNode;Array.isArray(s)?s.forEach(function(t){e[t.Node]=(new V).fromArray(t.Matrix.a)}):e[s.Node]=(new V).fromArray(s.Matrix.a)}}return e}addGlobalSceneSettings(){if("GlobalSettings"in Vt){if("AmbientColor"in Vt.GlobalSettings){const t=Vt.GlobalSettings.AmbientColor.value,n=t[0],s=t[1],r=t[2];if(0!==n||0!==s||0!==r){const t=(new u).setRGB(n,s,r,he);zt.add(new e(t,1))}}"UnitScaleFactor"in Vt.GlobalSettings&&(zt.userData.unitScaleFactor=Vt.GlobalSettings.UnitScaleFactor.value)}}}class Wt{constructor(){this.negativeMaterialIndices=!1}parse(e){const t=new Map;if("Geometry"in Vt.Objects){const n=Vt.Objects.Geometry;for(const s in n){const r=Gt.get(parseInt(s)),o=this.parseGeometry(r,n[s],e);t.set(parseInt(s),o)}}return this.negativeMaterialIndices,t}parseGeometry(e,t,n){switch(t.attrType){case"Mesh":return this.parseMeshGeometry(e,t,n);case"NurbsCurve":return this.parseNurbsGeometry(t)}}parseMeshGeometry(e,t,n){const s=n.skeletons,r=[],o=e.parents.map(function(e){return Vt.Objects.Model[e.ID]});if(0===o.length)return;const i=e.children.reduce(function(e,t){return void 0!==s[t.ID]&&(e=s[t.ID]),e},null);e.children.forEach(function(e){void 0!==n.morphTargets[e.ID]&&r.push(n.morphTargets[e.ID])});const a=o[0],c={};"RotationOrder"in a&&(c.eulerOrder=an(a.RotationOrder.value)),"InheritType"in a&&(c.inheritType=parseInt(a.InheritType.value)),"GeometricTranslation"in a&&(c.translation=a.GeometricTranslation.value),"GeometricRotation"in a&&(c.rotation=a.GeometricRotation.value),"GeometricScaling"in a&&(c.scale=a.GeometricScaling.value);const l=on(c);return this.genGeometry(t,i,r,l)}genGeometry(e,t,n,s){const r=new c;e.attrName&&(r.name=e.attrName);const o=this.parseGeoNode(e,t),i=this.genBuffers(o),a=new y(i.vertex,3);if(a.applyMatrix4(s),r.setAttribute("position",a),i.colors.length>0&&r.setAttribute("color",new y(i.colors,3)),t&&(r.setAttribute("skinIndex",new be(i.weightsIndices,4)),r.setAttribute("skinWeight",new y(i.vertexWeights,4)),r.FBX_Deformer=t),i.normal.length>0){const e=(new B).getNormalMatrix(s),t=new y(i.normal,3);t.applyNormalMatrix(e),r.setAttribute("normal",t)}if(i.uvs.forEach(function(e,t){const n=0===t?"uv":`uv${t}`;r.setAttribute(n,new y(i.uvs[t],2))}),o.material&&"AllSame"!==o.material.mappingType){let e=i.materialIndex[0],t=0;if(i.materialIndex.forEach(function(n,s){n!==e&&(r.addGroup(t,s-t,e),e=n,t=s)}),r.groups.length>0){const t=r.groups[r.groups.length-1],n=t.start+t.count;n!==i.materialIndex.length&&r.addGroup(n,i.materialIndex.length-n,e)}0===r.groups.length&&r.addGroup(0,i.materialIndex.length,i.materialIndex[0])}return this.addMorphTargets(r,e,n,s),r}parseGeoNode(e,t){const n={};if(n.vertexPositions=void 0!==e.Vertices?e.Vertices.a:[],n.vertexIndices=void 0!==e.PolygonVertexIndex?e.PolygonVertexIndex.a:[],e.LayerElementColor&&(n.color=this.parseVertexColors(e.LayerElementColor[0])),e.LayerElementMaterial&&(n.material=this.parseMaterialIndices(e.LayerElementMaterial[0])),e.LayerElementNormal&&(n.normal=this.parseNormals(e.LayerElementNormal[0])),e.LayerElementUV){n.uv=[];let t=0;for(;e.LayerElementUV[t];)e.LayerElementUV[t].UV&&n.uv.push(this.parseUVs(e.LayerElementUV[t])),t++}return n.weightTable={},null!==t&&(n.skeleton=t,t.rawBones.forEach(function(e,t){e.indices.forEach(function(s,r){void 0===n.weightTable[s]&&(n.weightTable[s]=[]),n.weightTable[s].push({id:t,weight:e.weights[r]})})})),n}genBuffers(e){const t={vertex:[],normal:[],colors:[],uvs:[],materialIndex:[],vertexWeights:[],weightsIndices:[]};let n=0,s=0,r=!1,o=[],i=[],a=[],c=[],l=[],u=[];const h=this;return e.vertexIndices.forEach(function(p,d){let f,m=!1;p<0&&(p^=-1,m=!0);let g=[],v=[];if(o.push(3*p,3*p+1,3*p+2),e.color){const t=nn(d,n,p,e.color);a.push(t[0],t[1],t[2])}if(e.skeleton){if(void 0!==e.weightTable[p]&&e.weightTable[p].forEach(function(e){v.push(e.weight),g.push(e.id)}),v.length>4){r||(r=!0);const e=[0,0,0,0],t=[0,0,0,0];v.forEach(function(n,s){let r=n,o=g[s];t.forEach(function(t,n,s){if(r>t){s[n]=r,r=t;const i=e[n];e[n]=o,o=i}})}),g=e,v=t}for(;v.length<4;)v.push(0),g.push(0);for(let e=0;e<4;++e)l.push(v[e]),u.push(g[e])}if(e.normal){const t=nn(d,n,p,e.normal);i.push(t[0],t[1],t[2])}e.material&&"AllSame"!==e.material.mappingType&&(f=nn(d,n,p,e.material)[0],f<0&&(h.negativeMaterialIndices=!0,f=0)),e.uv&&e.uv.forEach(function(e,t){const s=nn(d,n,p,e);void 0===c[t]&&(c[t]=[]),c[t].push(s[0]),c[t].push(s[1])}),s++,m&&(h.genFace(t,e,o,f,i,a,c,l,u,s),n++,s=0,o=[],i=[],a=[],c=[],l=[],u=[])}),t}getNormalNewell(e){const t=new Re(0,0,0);for(let n=0;n.5?new Re(0,1,0):new Re(0,0,1)).cross(t).normalize(),s=t.clone().cross(n).normalize();return{normal:t,tangent:n,bitangent:s}}flattenVertex(e,t,n){return new Ie(e.dot(t),e.dot(n))}genFace(e,t,n,s,r,o,i,a,c,l){let u;if(l>3){const e=[],s=t.baseVertexPositions||t.vertexPositions;for(let t=0;t0){const s=this.generateVectorTrack(e.modelName,e.T.curves,n,"position");void 0!==s&&t.push(s)}if(void 0!==e.R&&Object.keys(e.R.curves).length>0){const n=this.generateRotationTrack(e.modelName,e.R.curves,e.preRotation,e.postRotation,e.eulerOrder);void 0!==n&&t.push(n)}if(void 0!==e.S&&Object.keys(e.S.curves).length>0){const n=this.generateVectorTrack(e.modelName,e.S.curves,s,"scale");void 0!==n&&t.push(n)}if(void 0!==e.DeformPercent){const n=this.generateMorphTrack(e);void 0!==n&&t.push(n)}return t}generateVectorTrack(e,t,n,s){const r=this.getTimesForAllAxes(t),o=this.getKeyframeTrackValues(r,t,n);return new Se(e+"."+s,r,o)}generateRotationTrack(e,t,n,s,r){let o,i;if(void 0!==t.x&&void 0!==t.y&&void 0!==t.z){const e=this.interpolateRotations(t.x,t.y,t.z,r);o=e[0],i=e[1]}const a=an(0);void 0!==n&&((n=n.map(H.degToRad)).push(a),n=(new g).fromArray(n),n=(new ce).setFromEuler(n)),void 0!==s&&((s=s.map(H.degToRad)).push(a),s=(new g).fromArray(s),s=(new ce).setFromEuler(s).invert());const c=new ce,l=new g,u=[];if(!i||!o)return new le(e+".quaternion",[0],[0]);for(let e=0;e2){(new ce).fromArray(u,(e-3)/3*4).dot(c)<0&&c.set(-c.x,-c.y,-c.z,-c.w)}c.toArray(u,e/3*4)}return new le(e+".quaternion",o,u)}generateMorphTrack(e){const t=e.DeformPercent.curves.morph,n=t.values.map(function(e){return e/100}),s=zt.getObjectByName(e.modelName).morphTargetDictionary[e.morphName];return new Q(e.modelName+".morphTargetInfluences["+s+"]",t.times,n)}getTimesForAllAxes(e){let t=[];if(void 0!==e.x&&(t=t.concat(e.x.times)),void 0!==e.y&&(t=t.concat(e.y.times)),void 0!==e.z&&(t=t.concat(e.z.times)),t=t.sort(function(e,t){return e-t}),t.length>1){let e=1,n=t[0];for(let s=1;s=180||p[1]>=180||p[2]>=180){const t=Math.max(...p)/180,n=new g(...c,s),a=new g(...u,s),l=(new ce).setFromEuler(n),h=(new ce).setFromEuler(a);l.dot(h)&&h.set(-h.x,-h.y,-h.z,-h.w);const d=e.times[i-1],f=e.times[i]-d,m=new ce,v=new g;for(let e=0;e<1;e+=1/t)m.copy(l.clone().slerp(h.clone(),e)),r.push(d+e*f),v.setFromQuaternion(m,s),o.push(v.x),o.push(v.y),o.push(v.z)}else r.push(e.times[i]),o.push(H.degToRad(e.values[i])),o.push(H.degToRad(t.values[i])),o.push(H.degToRad(n.values[i]))}return[r,o]}}class Yt{getPrevNode(){return this.nodeStack[this.currentIndent-2]}getCurrentNode(){return this.nodeStack[this.currentIndent-1]}getCurrentProp(){return this.currentProp}pushStack(e){this.nodeStack.push(e),this.currentIndent+=1}popStack(){this.nodeStack.pop(),this.currentIndent-=1}setCurrentProp(e,t){this.currentProp=e,this.currentPropName=t}parse(e){this.currentIndent=0,this.allNodes=new Jt,this.nodeStack=[],this.currentProp=[],this.currentPropName="";const t=this,n=e.split(/[\r\n]+/);return n.forEach(function(e,s){const r=e.match(/^[\s\t]*;/),o=e.match(/^[\s\t]*$/);if(r||o)return;const i=e.match("^\\t{"+t.currentIndent+"}(\\w+):(.*){",""),a=e.match("^\\t{"+t.currentIndent+"}(\\w+):[\\s\\t\\r\\n](.*)"),c=e.match("^\\t{"+(t.currentIndent-1)+"}}");i?t.parseNodeBegin(e,i):a?t.parseNodeProperty(e,a,n[++s]):c?t.popStack():e.match(/^[^\s\t}]/)&&t.parseNodePropertyContinued(e)}),this.allNodes}parseNodeBegin(e,t){const n=t[1].trim().replace(/^"/,"").replace(/"$/,""),s=t[2].split(",").map(function(e){return e.trim().replace(/^"/,"").replace(/"$/,"")}),r={name:n},o=this.parseNodeAttr(s),i=this.getCurrentNode();0===this.currentIndent?this.allNodes.add(n,r):n in i?("PoseNode"===n?i.PoseNode.push(r):void 0!==i[n].id&&(i[n]={},i[n][i[n].id]=i[n]),""!==o.id&&(i[n][o.id]=r)):"number"==typeof o.id?(i[n]={},i[n][o.id]=r):"Properties70"!==n&&(i[n]="PoseNode"===n?[r]:r),"number"==typeof o.id&&(r.id=o.id),""!==o.name&&(r.attrName=o.name),""!==o.type&&(r.attrType=o.type),this.pushStack(r)}parseNodeAttr(e){let t=e[0];""!==e[0]&&(t=parseInt(e[0]),isNaN(t)&&(t=e[0]));let n="",s="";return e.length>1&&(n=e[1].replace(/^(\w+)::/,""),s=e[2]),{id:t,name:n,type:s}}parseNodeProperty(e,t,n){let s=t[1].replace(/^"/,"").replace(/"$/,"").trim(),r=t[2].replace(/^"/,"").replace(/"$/,"").trim();"Content"===s&&","===r&&(r=n.replace(/"/g,"").replace(/,$/,"").trim());const o=this.getCurrentNode();if("Properties70"!==o.name){if("C"===s){const e=r.split(",").slice(1),t=parseInt(e[0]),n=parseInt(e[1]);let i=r.split(",").slice(3);i=i.map(function(e){return e.trim().replace(/^"/,"")}),s="connections",r=[t,n],function(e,t){for(let n=0,s=e.length,r=t.length;n=e.size():e.getOffset()+160+16>=e.size()}parseNode(e,t){const n={},s=t>=7500?e.getUint64():e.getUint32(),r=t>=7500?e.getUint64():e.getUint32();t>=7500?e.getUint64():e.getUint32();const o=e.getUint8(),i=e.getString(o);if(0===s)return null;const a=[];for(let t=0;t0?a[0]:"",l=a.length>1?a[1]:"",u=a.length>2?a[2]:"";for(n.singleProperty=1===r&&e.getOffset()===s;s>e.getOffset();){const s=this.parseNode(e,t);null!==s&&this.parseSubNode(i,n,s)}return n.propertyList=a,"number"==typeof c&&(n.id=c),""!==l&&(n.attrName=l),""!==u&&(n.attrType=u),""!==i&&(n.name=i),n}parseSubNode(e,t,n){if(!0===n.singleProperty){const e=n.propertyList[0];Array.isArray(e)?(t[n.name]=n,n.a=e):t[n.name]=e}else if("Connections"===e&&"C"===n.name){const e=[];n.propertyList.forEach(function(t,n){0!==n&&e.push(t)}),void 0===t.connections&&(t.connections=[]),t.connections.push(e)}else if("Properties70"===n.name){Object.keys(n).forEach(function(e){t[e]=n[e]})}else if("Properties70"===e&&"P"===n.name){let e=n.propertyList[0],s=n.propertyList[1];const r=n.propertyList[2],o=n.propertyList[3];let i;0===e.indexOf("Lcl ")&&(e=e.replace("Lcl ","Lcl_")),0===s.indexOf("Lcl ")&&(s=s.replace("Lcl ","Lcl_")),i="Color"===s||"ColorRGB"===s||"Vector"===s||"Vector3D"===s||0===s.indexOf("Lcl_")?[n.propertyList[4],n.propertyList[5],n.propertyList[6]]:n.propertyList[4],t[e]={type:s,type2:r,flag:o,value:i}}else void 0===t[n.name]?"number"==typeof n.id?(t[n.name]={},t[n.name][n.id]=n):t[n.name]=n:"PoseNode"===n.name?(Array.isArray(t[n.name])||(t[n.name]=[t[n.name]]),t[n.name].push(n)):void 0===t[n.name][n.id]&&(t[n.name][n.id]=n)}parseProperty(e){const t=e.getString(1);let n;switch(t){case"C":return e.getBoolean();case"D":return e.getFloat64();case"F":return e.getFloat32();case"I":return e.getInt32();case"L":return e.getInt64();case"R":return n=e.getUint32(),e.getArrayBuffer(n);case"S":return n=e.getUint32(),e.getString(n);case"Y":return e.getInt16();case"b":case"c":case"d":case"f":case"i":case"l":const s=e.getUint32(),r=e.getUint32(),o=e.getUint32();if(0===r)switch(t){case"b":case"c":return e.getBooleanArray(s);case"d":return e.getFloat64Array(s);case"f":return e.getFloat32Array(s);case"i":return e.getInt32Array(s);case"l":return e.getInt64Array(s)}const i=kt(new Uint8Array(e.getArrayBuffer(o))),a=new Zt(i.buffer);switch(t){case"b":case"c":return a.getBooleanArray(s);case"d":return a.getFloat64Array(s);case"f":return a.getFloat32Array(s);case"i":return a.getInt32Array(s);case"l":return a.getInt64Array(s)}break;default:throw new Error("THREE.FBXLoader: Unknown property type "+t)}}}class Zt{constructor(e,t){this.dv=new DataView(e),this.offset=0,this.littleEndian=void 0===t||t,this._textDecoder=new TextDecoder}getOffset(){return this.offset}size(){return this.dv.buffer.byteLength}skip(e){this.offset+=e}getBoolean(){return!(1&~this.getUint8())}getBooleanArray(e){const t=[];for(let n=0;n=0&&(n=new Uint8Array(this.dv.buffer,t,s)),this._textDecoder.decode(n)}}class Jt{add(e,t){this[e]=t}}function Qt(e){const t=e.match(/FBXVersion: (\d+)/);if(t){return parseInt(t[1])}throw new Error("THREE.FBXLoader: Cannot find the version number for the file given.")}function en(e){return e/46186158e3}const tn=[];function nn(e,t,n,s){let r;switch(s.mappingType){case"ByPolygonVertex":r=e;break;case"ByPolygon":r=t;break;case"ByVertice":r=n;break;case"AllSame":r=s.indices[0]}"IndexToDirect"===s.referenceType&&(r=s.indices[r]);const o=r*s.dataSize,i=o+s.dataSize;return function(e,t,n,s){for(let r=n,o=0;r=0)throw new Error("THREE.GLTFLoader: setKTX2Loader must be called before loading KTX2 textures");return null}return t.loadTextureImage(e,r.source,o)}}class Sn{constructor(e){this.parser=e,this.name=pn.EXT_TEXTURE_WEBP}loadTexture(e){const t=this.name,n=this.parser,s=n.json,r=s.textures[e];if(!r.extensions||!r.extensions[t])return null;const o=r.extensions[t],i=s.images[o.source];let a=n.textureLoader;if(i.uri){const e=n.options.manager.getHandler(i.uri);null!==e&&(a=e)}return n.loadTextureImage(e,o.source,a)}}class En{constructor(e){this.parser=e,this.name=pn.EXT_TEXTURE_AVIF}loadTexture(e){const t=this.name,n=this.parser,s=n.json,r=s.textures[e];if(!r.extensions||!r.extensions[t])return null;const o=r.extensions[t],i=s.images[o.source];let a=n.textureLoader;if(i.uri){const e=n.options.manager.getHandler(i.uri);null!==e&&(a=e)}return n.loadTextureImage(e,o.source,a)}}class _n{constructor(e){this.name=pn.EXT_MESHOPT_COMPRESSION,this.parser=e}loadBufferView(e){const t=this.parser.json,n=t.bufferViews[e];if(n.extensions&&n.extensions[this.name]){const e=n.extensions[this.name],s=this.parser.getDependency("buffer",e.buffer),r=this.parser.options.meshoptDecoder;if(!r||!r.supported){if(t.extensionsRequired&&t.extensionsRequired.indexOf(this.name)>=0)throw new Error("THREE.GLTFLoader: setMeshoptDecoder must be called before loading compressed files");return null}return s.then(function(t){const n=e.byteOffset||0,s=e.byteLength||0,o=e.count,i=e.byteStride,a=new Uint8Array(t,n,s);return r.decodeGltfBufferAsync?r.decodeGltfBufferAsync(o,i,a,e.mode,e.filter).then(function(e){return e.buffer}):r.ready.then(function(){const t=new ArrayBuffer(o*i);return r.decodeGltfBuffer(new Uint8Array(t),o,i,a,e.mode,e.filter),t})})}return null}}class Nn{constructor(e){this.name=pn.EXT_MESH_GPU_INSTANCING,this.parser=e}createNodeMesh(e){const t=this.parser.json,n=t.nodes[e];if(!n.extensions||!n.extensions[this.name]||void 0===n.mesh)return null;const s=t.meshes[n.mesh];for(const e of s.primitives)if(e.mode!==Bn.TRIANGLES&&e.mode!==Bn.TRIANGLE_STRIP&&e.mode!==Bn.TRIANGLE_FAN&&void 0!==e.mode)return null;const r=n.extensions[this.name].attributes,o=[],i={};for(const e in r)o.push(this.parser.getDependency("accessor",r[e]).then(t=>(i[e]=t,i[e])));return o.length<1?null:(o.push(this.parser.createNodeMesh(e)),Promise.all(o).then(e=>{const t=e.pop(),n=t.isGroup?t.children:[t],s=e[0].count,r=[];for(const e of n){const t=new V,n=new Re,o=new ce,a=new Re(1,1,1),c=new b(e.geometry,e.material,s);for(let e=0;e-1,o=r?e.match(/Firefox\/([0-9]+)\./)[1]:-1}"undefined"==typeof createImageBitmap||n&&s<17||r&&o<98?this.textureLoader=new Te(this.options.manager):this.textureLoader=new w(this.options.manager),this.textureLoader.setCrossOrigin(this.options.crossOrigin),this.textureLoader.setRequestHeader(this.options.requestHeader),this.fileLoader=new v(this.options.manager),this.fileLoader.setResponseType("arraybuffer"),"use-credentials"===this.options.crossOrigin&&this.fileLoader.setWithCredentials(!0)}setExtensions(e){this.extensions=e}setPlugins(e){this.plugins=e}parse(e,t){const n=this,s=this.json,r=this.extensions;this.cache.removeAll(),this.nodeCache={},this._invokeAll(function(e){return e._markDefs&&e._markDefs()}),Promise.all(this._invokeAll(function(e){return e.beforeRoot&&e.beforeRoot()})).then(function(){return Promise.all([n.getDependencies("scene"),n.getDependencies("animation"),n.getDependencies("camera")])}).then(function(t){const o={scene:t[0][s.scene||0],scenes:t[0],animations:t[1],cameras:t[2],asset:s.asset,parser:n,userData:{}};return Qn(r,o,s),es(o,s),Promise.all(n._invokeAll(function(e){return e.afterRoot&&e.afterRoot(o)})).then(function(){for(const e of o.scenes)e.updateMatrixWorld();e(o)})}).catch(t)}_markDefs(){const e=this.json.nodes||[],t=this.json.skins||[],n=this.json.meshes||[];for(let n=0,s=t.length;n{const n=this.associations.get(e);null!=n&&this.associations.set(t,n);for(const[n,s]of e.children.entries())r(s,t.children[n])};return r(n,s),s.name+="_instance_"+e.uses[t]++,s}_invokeOne(e){const t=Object.values(this.plugins);t.push(this);for(let n=0;n=2&&f.setY(t,h[e*o+1]),o>=3&&f.setZ(t,h[e*o+2]),o>=4&&f.setW(t,h[e*o+3]),o>=5)throw new Error("THREE.GLTFLoader: Unsupported itemSize in sparse BufferAttribute.")}f.normalized=p}return f})}loadTexture(e){const t=this.json,n=this.options,s=t.textures[e].source,r=t.images[s];let o=this.textureLoader;if(r.uri){const e=n.manager.getHandler(r.uri);null!==e&&(o=e)}return this.loadTextureImage(e,s,o)}loadTextureImage(e,t,n){const s=this,r=this.json,o=r.textures[e],i=r.images[t],a=(i.uri||i.bufferView)+":"+o.sampler;if(this.textureCache[a])return this.textureCache[a];const c=this.loadImageSource(t,n).then(function(t){t.flipY=!1,t.name=o.name||i.name||"",""===t.name&&"string"==typeof i.uri&&!1===i.uri.startsWith("data:image/")&&(t.name=i.uri);const n=(r.samplers||{})[o.sampler]||{};return t.magFilter=Gn[n.magFilter]||C,t.minFilter=Gn[n.minFilter]||O,t.wrapS=zn[n.wrapS]||ue,t.wrapT=zn[n.wrapT]||ue,t.generateMipmaps=!t.isCompressedTexture&&t.minFilter!==$&&t.minFilter!==C,s.associations.set(t,{textures:e}),t}).catch(function(){return null});return this.textureCache[a]=c,c}loadImageSource(e,t){const n=this,s=this.json,r=this.options;if(void 0!==this.sourceCache[e])return this.sourceCache[e].then(e=>e.clone());const o=s.images[e],i=self.URL||self.webkitURL;let a=o.uri||"",c=!1;if(void 0!==o.bufferView)a=n.getDependency("bufferView",o.bufferView).then(function(e){c=!0;const t=new Blob([e],{type:o.mimeType});return a=i.createObjectURL(t),a});else if(void 0===o.uri)throw new Error("THREE.GLTFLoader: Image "+e+" is missing URI and bufferView");const l=Promise.resolve(a).then(function(e){return new Promise(function(n,s){let o=n;!0===t.isImageBitmapLoader&&(o=function(e){const t=new ye(e);t.needsUpdate=!0,n(t)}),t.load(U.resolveURL(e,r.path),o,void 0,s)})}).then(function(e){var t;return!0===c&&i.revokeObjectURL(a),es(e,o),e.userData.mimeType=o.mimeType||((t=o.uri).search(/\.jpe?g($|\?)/i)>0||0===t.search(/^data\:image\/jpeg/)?"image/jpeg":t.search(/\.webp($|\?)/i)>0||0===t.search(/^data\:image\/webp/)?"image/webp":t.search(/\.ktx2($|\?)/i)>0||0===t.search(/^data\:image\/ktx2/)?"image/ktx2":"image/png"),e}).catch(function(e){throw e});return this.sourceCache[e]=l,l}assignTexture(e,t,n,s){const r=this;return this.getDependency("texture",n.index).then(function(o){if(!o)return null;if(void 0!==n.texCoord&&n.texCoord>0&&((o=o.clone()).channel=n.texCoord),r.extensions[pn.KHR_TEXTURE_TRANSFORM]){const e=void 0!==n.extensions?n.extensions[pn.KHR_TEXTURE_TRANSFORM]:void 0;if(e){const t=r.associations.get(o);o=r.extensions[pn.KHR_TEXTURE_TRANSFORM].extendTexture(o,e),r.associations.set(o,t)}}return void 0!==s&&(o.colorSpace=s),e[t]=o,o})}assignFinalMaterial(e){const t=e.geometry;let n=e.material;const s=void 0===t.attributes.tangent,r=void 0!==t.attributes.color,o=void 0===t.attributes.normal;if(e.isPoints){const e="PointsMaterial:"+n.uuid;let t=this.cache.get(e);t||(t=new oe,j.prototype.copy.call(t,n),t.color.copy(n.color),t.map=n.map,t.sizeAttenuation=!1,this.cache.add(e,t)),n=t}else if(e.isLine){const e="LineBasicMaterial:"+n.uuid;let t=this.cache.get(e);t||(t=new N,j.prototype.copy.call(t,n),t.color.copy(n.color),t.map=n.map,this.cache.add(e,t)),n=t}if(s||r||o){let e="ClonedMaterial:"+n.uuid+":";s&&(e+="derivative-tangents:"),r&&(e+="vertex-colors:"),o&&(e+="flat-shading:");let t=this.cache.get(e);t||(t=n.clone(),r&&(t.vertexColors=!0),o&&(t.flatShading=!0),s&&(t.normalScale&&(t.normalScale.y*=-1),t.clearcoatNormalScale&&(t.clearcoatNormalScale.y*=-1)),this.cache.add(e,t),this.associations.set(t,this.associations.get(n))),n=t}e.material=n}getMaterialType(){return q}loadMaterial(e){const t=this,n=this.json,s=this.extensions,r=n.materials[e];let o;const i={},a=[];if((r.extensions||{})[pn.KHR_MATERIALS_UNLIT]){const e=s[pn.KHR_MATERIALS_UNLIT];o=e.getMaterialType(),a.push(e.extendParams(i,r,t))}else{const n=r.pbrMetallicRoughness||{};if(i.color=new u(1,1,1),i.opacity=1,Array.isArray(n.baseColorFactor)){const e=n.baseColorFactor;i.color.setRGB(e[0],e[1],e[2],D),i.opacity=e[3]}void 0!==n.baseColorTexture&&a.push(t.assignTexture(i,"map",n.baseColorTexture,he)),i.metalness=void 0!==n.metallicFactor?n.metallicFactor:1,i.roughness=void 0!==n.roughnessFactor?n.roughnessFactor:1,void 0!==n.metallicRoughnessTexture&&(a.push(t.assignTexture(i,"metalnessMap",n.metallicRoughnessTexture)),a.push(t.assignTexture(i,"roughnessMap",n.metallicRoughnessTexture))),o=this._invokeOne(function(t){return t.getMaterialType&&t.getMaterialType(e)}),a.push(Promise.all(this._invokeAll(function(t){return t.extendMaterialParams&&t.extendMaterialParams(e,i)})))}!0===r.doubleSided&&(i.side=f);const c=r.alphaMode||Yn;if(c===Zn?(i.transparent=!0,i.depthWrite=!1):(i.transparent=!1,c===$n&&(i.alphaTest=void 0!==r.alphaCutoff?r.alphaCutoff:.5)),void 0!==r.normalTexture&&o!==z&&(a.push(t.assignTexture(i,"normalMap",r.normalTexture)),i.normalScale=new Ie(1,1),void 0!==r.normalTexture.scale)){const e=r.normalTexture.scale;i.normalScale.set(e,e)}if(void 0!==r.occlusionTexture&&o!==z&&(a.push(t.assignTexture(i,"aoMap",r.occlusionTexture)),void 0!==r.occlusionTexture.strength&&(i.aoMapIntensity=r.occlusionTexture.strength)),void 0!==r.emissiveFactor&&o!==z){const e=r.emissiveFactor;i.emissive=(new u).setRGB(e[0],e[1],e[2],D)}return void 0!==r.emissiveTexture&&o!==z&&a.push(t.assignTexture(i,"emissiveMap",r.emissiveTexture,he)),Promise.all(a).then(function(){const n=new o(i);return r.name&&(n.name=r.name),es(n,r),t.associations.set(n,{materials:e}),r.extensions&&Qn(s,n,r),n})}createUniqueName(e){const t=ae.sanitizeNodeName(e||"");return t in this.nodeNamesUsed?t+"_"+ ++this.nodeNamesUsed[t]:(this.nodeNamesUsed[t]=0,t)}loadGeometries(e){const t=this,n=this.extensions,s=this.primitiveCache;function r(e){return n[pn.KHR_DRACO_MESH_COMPRESSION].decodePrimitive(e,t).then(function(n){return as(n,e,t)})}const o=[];for(let n=0,i=e.length;n0&&ts(h,r),h.name=t.createUniqueName(r.name||"mesh_"+e),es(h,r),u.extensions&&Qn(s,h,u),t.assignFinalMaterial(h),c.push(h)}for(let n=0,s=c.length;n1?new x:1===t.length?t[0]:new ee,a!==t[0])for(let e=0,n=t.length;e1){const e=s.associations.get(a);s.associations.set(a,{...e})}}else s.associations.set(a,{});return s.associations.get(a).nodes=e,a}),this.nodeCache[e]}loadScene(e){const t=this.extensions,n=this.json.scenes[e],s=this,r=new x;n.name&&(r.name=s.createUniqueName(n.name)),es(r,n),n.extensions&&Qn(t,r,n);const o=n.nodes||[],i=[];for(let e=0,t=o.length;e{const t=new Map;for(const[e,n]of s.associations)(e instanceof j||e instanceof ye)&&t.set(e,n);return e.traverse(e=>{const n=s.associations.get(e);null!=n&&t.set(e,n)}),t})(r),r})}_createAnimationTracks(e,t,n,s,r){const o=[],i=e.name?e.name:e.uuid,a=[];let c;switch(Wn[r.path]===Wn.weights?e.traverse(function(e){e.morphTargetInfluences&&a.push(e.name?e.name:e.uuid)}):a.push(i),Wn[r.path]){case Wn.weights:c=Q;break;case Wn.rotation:c=le;break;case Wn.translation:case Wn.scale:c=Se;break;default:if(1===n.itemSize)c=Q;else c=Se}const l=void 0!==s.interpolation?qn[s.interpolation]:E,u=this._getArrayFromAccessor(n);for(let e=0,n=a.length;e=2.0 are supported.")));const c=new is(r,{path:t||this.resourcePath||"",crossOrigin:this.crossOrigin,requestHeader:this.requestHeader,manager:this.manager,ktx2Loader:this.ktx2Loader,meshoptDecoder:this.meshoptDecoder});c.fileLoader.setRequestHeader(this.requestHeader);for(let e=0;e=0&&i[t]}}c.setExtensions(o),c.setPlugins(i),c.parse(n,s)}parseAsync(e,t){const n=this;return new Promise(function(s,r){n.parse(e,t,s,r)})}},ls=Array.from({length:3},()=>({loader:new Kt,isUsed:!1}));let us=[];const hs=Array.from({length:3},()=>({loader:new Te,isUsed:!1}));let ps=[];const ds=Array.from({length:3},()=>({loader:new r,isUsed:!1}));let fs=[];const ms=e=>ys(e,ls,us),gs=e=>ys(e,hs,ps),vs=e=>ys(e,ds,fs),ys=(e,t,n)=>{const s=t.find(e=>!e.isUsed);s?(s.isUsed=!0,e(s.loader)):n.push(t=>{e(t.loader),t.isUsed=!0})},Ts=(e,t,n)=>{const s=t.find(t=>t.loader===e);if(s)if(n.length>0){const e=n.shift();e&&e(s)}else s.isUsed=!1},xs=({list:e,onElementLoaded:t,onComplete:n,onError:s})=>{if(e.length>0){const{url:r}=e[0];cs.load(r,({scene:r,animations:o})=>{t({...e[0],gltfModel:{scene:r,animations:o}}),e.shift(),xs({list:e,onElementLoaded:t,onComplete:n,onError:s})},void 0,e=>s(String(e)))}else n()},ws=(e,t)=>{const n=[];return new Promise((s,r)=>{if(e.length>0){const o=[...e];for(;o.length>0;){const{url:e,id:i}=o[0],a=o[0];o.shift(),ms(o=>o.load(e,e=>{var r;r={...a,id:i,fbxModel:e},n.push(r),t(),Ts(o,ls,us),ls.some(e=>e.isUsed)||s(n)},void 0,t=>r(new Error(`Something wrong happened with an FBX model: ${i}, url: ${e}, error: ${t}`))))}}else s([])})},As={},bs={},Is={},Rs={},Ms={},Ss=({id:e,fbxModel:t})=>{As[e]=t},Es=e=>{const t=st(As[e]);return t.animations=[...As[e].animations],t},_s=({id:e,fbxModel:t})=>{Ms[e]=t.animations[0]},Ns=e=>Ms[e],Ls=({id:e,gltfModel:t})=>{bs[e]=t},Ps=e=>bs[e],Cs=({id:e,texture:t})=>{Is[e]=t},Os=e=>Is[e]||null,ks=({id:e,audioBuffer:t})=>{Rs[e]=t},Ds=e=>Rs[e]||null,Fs=({material:e,materialConfig:t={texture:{id:""},color:16777215,alphaTest:.5}})=>{"map"in e&&(e.map=t?.texture?.id?Os(t.texture.id):null),"alphaTest"in e&&(e.alphaTest=t?.alphaTest||.5),"color"in e&&(e.color=new u(t?.color||16777215))},Us=(e={materialType:void 0,texture:{id:"",flipY:!0},color:16777215,alphaTest:.5})=>{let t=null;if(e instanceof Array)t=e.map(e=>Us(e));else if(e.materialType){const n=e?.texture?.id?Os(e.texture.id):null;n&&(n.flipY=e?.texture?.flipY??!0),t=new e.materialType({map:n,alphaTest:e.alphaTest||.5,color:new u(e?.color||16777215)})}return t},js=()=>{Object.entries(Is).forEach(([e,t])=>{t.dispose(),delete Is[e]}),Object.entries(As).forEach(([e,t])=>{ze(t),delete As[e]}),Object.entries(bs).forEach(([e,t])=>{ze(t.scene),delete bs[e]})},Hs=({textures:e,gltfModels:t,fbxModels:n,fbxSkeletonAnimations:s,audio:r,onProgress:o,verbose:i=!0})=>new Promise(i=>{const a={fbxModels:[]},c=e.length+t.length+n.length+s.length+r.length;let l=0;const u=()=>{l++,o&&o(l/c)};((e,t)=>{const n=[];return new Promise((s,r)=>{if(e.length>0){const o=[...e];for(;o.length>0;){const{url:e,id:i}=o[0];o.shift(),gs(o=>o.load(e,r=>{var a;r.wrapS=ue,r.wrapT=ue,a={id:i,url:e,texture:r},n.push(a),t(),Ts(o,hs,ps),hs.some(e=>e.isUsed)||s(n)},void 0,t=>r(new Error(`Something wrong happened with a texture: ${i}, url: ${e}, error: ${t}`))))}}else s([])})})(e,u).then(e=>{e.forEach(e=>{e.texture.colorSpace=he,Cs(e)}),((e,t)=>{const n=[],s=e=>{n.push(e),t()};return new Promise((t,r)=>{xs({list:[...e],onElementLoaded:s,onComplete:()=>t(n),onError:e=>r(new Error(`Something wrong happened: ${e}`))})})})(t,u).then(e=>{e.forEach(e=>{const t=Us(e.material);let n=0;e.gltfModel.scene.traverse(s=>{if(s.isMesh){const r=s;r.castShadow=!0,r.receiveShadow=!0,r.material instanceof Array?r.material=t:r.material=t instanceof Array?t[n]:t||r.material,!t&&e.material&&Fs({material:r.material,materialConfig:e.material instanceof Array?e.material[n]:e.material}),n++}}),Ls(e)}),ws(s,u).then(e=>{e.forEach(e=>{_s(e)}),ws(n,u).then(e=>{e.forEach(e=>{const t=Us(e.material);let n=0;e.fbxModel.traverse(s=>{if(s.isMesh){const r=s;r.castShadow=!0,r.receiveShadow=!0,r.material instanceof Array?r.material=t:r.material=t instanceof Array?t[n]:t||r.material,!t&&e.material&&Fs({material:r.material,materialConfig:e.material instanceof Array?e.material[n]:e.material}),n++}}),Ss(e)}),a.fbxModels=[...e],((e,t)=>{const n=[];return new Promise((s,r)=>{if(e.length>0){const o=[...e];for(;o.length>0;){const{url:e,id:i}=o[0];o.shift(),vs(o=>o.load(e,r=>{var a;a={id:i,url:e,audioBuffer:r},n.push(a),t(),Ts(o,ds,fs),ds.some(e=>e.isUsed)||s(n)},void 0,t=>r(new Error(`Something wrong happened with an audio: ${i}, url: ${e}, error: ${t}`))))}}else s([])})})(r,u).then(e=>{e.forEach(e=>ks(e)),i(a)}).catch(e=>{})}).catch(e=>{})})})}).catch(e=>{})});class Bs extends _{constructor(e,t=1,n=16,s=2){const r=new c,o=new Float32Array(3*(3*(n+2*s)+3));r.setAttribute("position",new a(o,3));const i=new N({color:65280});super(r,[new N({color:16776960}),i]),this.audio=e,this.range=t,this.divisionsInnerAngle=n,this.divisionsOuterAngle=s,this.type="PositionalAudioHelper",this.update()}update(){const e=this.audio,t=this.range,n=this.divisionsInnerAngle,s=this.divisionsOuterAngle,r=H.degToRad(e.panner.coneInnerAngle),o=H.degToRad(e.panner.coneOuterAngle),i=r/2,a=o/2;let c,l,u=0,h=0;const p=this.geometry,d=p.attributes.position;function f(e,n,s,r){const o=(n-e)/s;for(d.setXYZ(u,0,0,0),h++,c=e;c{Gs=e},Ws=({audioId:e,position:t,radius:r=1,scene:o,camera:i,cacheId:a})=>{const c=Date.now();let l;if(a&&zs[a]){const{audio:e,container:n}=zs[a];l=e,l.isPlaying&&l.stop(),n&&t&&n.position.copy(t),zs[a].lastPlayedTime=c}else{const u=Ds(e);if(!u)return;const{loop:h,volume:p,isMusic:d}={...Vs,...Gs[e]},f=new s;let m;if(t&&o&&i){l=new ie(f),l.setRefDistance(r);const e=new ge(r,32,32);m=new G(e),m.visible=!1;const n=new Bs(l,r);l.add(n),m.position.copy(t),m.add(l),o.add(m),i.add(f)}else l=new n(f);l.setBuffer(u),l.setLoop(h||!1),l.setVolume((p||1)*Ks.masterVolume*(d?Ks.musicVolume:Ks.effectsVolume)),zs[a||e]={audio:l,audioId:e,container:m,lastPlayedTime:c}}l.play()},qs=e=>{const t=Ys(e);t.audio&&t.audio.isPlaying&&t.audio.stop()},Ys=e=>zs[e]||{audio:null,audioId:"",container:void 0,lastPlayedTime:0},$s=()=>{Object.keys(zs).forEach(e=>{const{audio:t,audioId:n}=Ys(e);if(t){const{volume:e,isMusic:s}={...Vs,...Gs[n]};t.setVolume((e||1)*Ks.masterVolume*(s?Ks.musicVolume:Ks.effectsVolume))}})},Zs=e=>{Ks.masterVolume=e,$s()},Js=e=>{Ks.musicVolume=e,$s()},Qs=e=>{Ks.effectsVolume=e,$s()},er={playAudio:Ws,stopAudio:qs,setMasterVolume:Zs,setMusicVolume:Js,setEffectsVolume:Qs};export{De as AssetsUtils,Fe as AudioUtils,_e as CallbackUtils,Ne as DisposeUtils,ke as GeomUtils,Le as ObjectUtils,Pe as TimeUtils,Ce as TokenUtils,Oe as Vector3Utils}; \ No newline at end of file diff --git a/dist/three-utils.min.js.LICENSE.txt b/dist/three-utils.min.js.LICENSE.txt deleted file mode 100644 index e0932b3..0000000 --- a/dist/three-utils.min.js.LICENSE.txt +++ /dev/null @@ -1,6 +0,0 @@ -/*! -fflate - fast JavaScript compression/decompression - -Licensed under MIT. https://github.com/101arrowz/fflate/blob/master/LICENSE -version 0.8.2 -*/ diff --git a/dist/time-utils.d.ts b/dist/time-utils.d.ts deleted file mode 100644 index f3ea6ac..0000000 --- a/dist/time-utils.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -export declare const TimePattern: { - readonly HH_MM_SS: "HH:MM:SS"; - readonly MM_SS: "MM:SS"; - readonly MM_SS_MS: "MM:SS.MS"; -}; -export declare const formatTime: (timeInMS: number, pattern: string) => string; -//# sourceMappingURL=time-utils.d.ts.map \ No newline at end of file diff --git a/dist/time-utils.d.ts.map b/dist/time-utils.d.ts.map deleted file mode 100644 index fd95806..0000000 --- a/dist/time-utils.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"time-utils.d.ts","sourceRoot":"","sources":["../src/time-utils.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,WAAW;;;;CAId,CAAC;AAwBX,eAAO,MAAM,UAAU,GAAI,UAAU,MAAM,EAAE,SAAS,MAAM,KAAG,MAc9D,CAAC"} \ No newline at end of file diff --git a/dist/time-utils.js b/dist/time-utils.js deleted file mode 100644 index 5d675d9..0000000 --- a/dist/time-utils.js +++ /dev/null @@ -1,24 +0,0 @@ -export const TimePattern = { - HH_MM_SS: 'HH:MM:SS', - MM_SS: 'MM:SS', - MM_SS_MS: 'MM:SS.MS', -}; -const patterns = [ - { pattern: 'HH', routine: ({ hours }) => String(hours).padStart(2, '0') }, - { pattern: 'MM', routine: ({ minutes }) => String(minutes).padStart(2, '0') }, - { pattern: 'SS', routine: ({ seconds }) => String(seconds).padStart(2, '0') }, - { - pattern: 'MS', - routine: ({ milliseconds }) => String(milliseconds).padStart(3, '0'), - }, -]; -export const formatTime = (timeInMS, pattern) => { - const milliseconds = Math.floor(timeInMS % 1000); - const seconds = Math.floor((timeInMS / 1000) % 60); - const minutes = Math.floor(Math.floor(timeInMS / 1000 / 60) % 60); - const hours = Math.floor((Math.floor(timeInMS / 1000 / 60) / 60) % 24); - const timeDetails = { hours, minutes, seconds, milliseconds }; - let result = pattern; - patterns.forEach(({ pattern: currentPattern, routine }) => (result = result.replace(currentPattern, routine(timeDetails)))); - return result; -}; diff --git a/dist/token.d.ts b/dist/token.d.ts deleted file mode 100644 index 0317230..0000000 --- a/dist/token.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -export declare const getUniqueId: () => number; -//# sourceMappingURL=token.d.ts.map \ No newline at end of file diff --git a/dist/token.d.ts.map b/dist/token.d.ts.map deleted file mode 100644 index d3128e8..0000000 --- a/dist/token.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"token.d.ts","sourceRoot":"","sources":["../src/token.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,WAAW,QAAO,MAAoB,CAAC"} \ No newline at end of file diff --git a/dist/token.js b/dist/token.js deleted file mode 100644 index 81f09a1..0000000 --- a/dist/token.js +++ /dev/null @@ -1,2 +0,0 @@ -let uniqueId = 0; -export const getUniqueId = () => uniqueId++; diff --git a/dist/vector3-utils.d.ts b/dist/vector3-utils.d.ts deleted file mode 100644 index 88afdde..0000000 --- a/dist/vector3-utils.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -import * as THREE from 'three'; -export declare const absVector3: (vector: THREE.Vector3) => THREE.Vector3; -//# sourceMappingURL=vector3-utils.d.ts.map \ No newline at end of file diff --git a/dist/vector3-utils.d.ts.map b/dist/vector3-utils.d.ts.map deleted file mode 100644 index f3c059e..0000000 --- a/dist/vector3-utils.d.ts.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"vector3-utils.d.ts","sourceRoot":"","sources":["../src/vector3-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,eAAO,MAAM,UAAU,GAAI,QAAQ,KAAK,CAAC,OAAO,KAAG,KAAK,CAAC,OAMxD,CAAC"} \ No newline at end of file diff --git a/dist/vector3-utils.js b/dist/vector3-utils.js deleted file mode 100644 index eaf4898..0000000 --- a/dist/vector3-utils.js +++ /dev/null @@ -1,6 +0,0 @@ -export const absVector3 = (vector) => { - vector.x = Math.abs(vector.x); - vector.y = Math.abs(vector.y); - vector.z = Math.abs(vector.z); - return vector; -}; From de0f5c8d11eeb4b0dcc6c23871943b71c824de6b Mon Sep 17 00:00:00 2001 From: Krisztian Somoracz Date: Thu, 16 Oct 2025 21:59:23 +0200 Subject: [PATCH 18/20] chore: remove old JavaScript files after TypeScript migration - Removed legacy JS files from src/js/newkrok/three-utils/ - All files have been successfully converted to TypeScript - Cleanup includes main utility files, assets, and audio modules - Project now uses pure TypeScript source structure --- src/js/newkrok/three-utils/assets/assets.js | 233 ------------------ src/js/newkrok/three-utils/assets/index.js | 1 - src/js/newkrok/three-utils/assets/loaders.js | 216 ---------------- src/js/newkrok/three-utils/audio/audio.js | 125 ---------- src/js/newkrok/three-utils/audio/index.js | 1 - src/js/newkrok/three-utils/callback-utils.js | 55 ----- src/js/newkrok/three-utils/dispose-utils.d.ts | 4 - src/js/newkrok/three-utils/dispose-utils.js | 28 --- src/js/newkrok/three-utils/geom-utils.d.ts | 17 -- src/js/newkrok/three-utils/geom-utils.js | 50 ---- src/js/newkrok/three-utils/index.js | 7 - src/js/newkrok/three-utils/object-utils.d.ts | 15 -- src/js/newkrok/three-utils/object-utils.js | 85 ------- src/js/newkrok/three-utils/time-utils.d.ts | 1 - src/js/newkrok/three-utils/time-utils.js | 31 --- src/js/newkrok/three-utils/token.d.ts | 1 - src/js/newkrok/three-utils/token.js | 2 - src/js/newkrok/three-utils/vector3-utils.d.ts | 1 - src/js/newkrok/three-utils/vector3-utils.js | 7 - 19 files changed, 880 deletions(-) delete mode 100644 src/js/newkrok/three-utils/assets/assets.js delete mode 100644 src/js/newkrok/three-utils/assets/index.js delete mode 100644 src/js/newkrok/three-utils/assets/loaders.js delete mode 100644 src/js/newkrok/three-utils/audio/audio.js delete mode 100644 src/js/newkrok/three-utils/audio/index.js delete mode 100644 src/js/newkrok/three-utils/callback-utils.js delete mode 100644 src/js/newkrok/three-utils/dispose-utils.d.ts delete mode 100644 src/js/newkrok/three-utils/dispose-utils.js delete mode 100644 src/js/newkrok/three-utils/geom-utils.d.ts delete mode 100644 src/js/newkrok/three-utils/geom-utils.js delete mode 100644 src/js/newkrok/three-utils/index.js delete mode 100644 src/js/newkrok/three-utils/object-utils.d.ts delete mode 100644 src/js/newkrok/three-utils/object-utils.js delete mode 100644 src/js/newkrok/three-utils/time-utils.d.ts delete mode 100644 src/js/newkrok/three-utils/time-utils.js delete mode 100644 src/js/newkrok/three-utils/token.d.ts delete mode 100644 src/js/newkrok/three-utils/token.js delete mode 100644 src/js/newkrok/three-utils/vector3-utils.d.ts delete mode 100644 src/js/newkrok/three-utils/vector3-utils.js diff --git a/src/js/newkrok/three-utils/assets/assets.js b/src/js/newkrok/three-utils/assets/assets.js deleted file mode 100644 index e5667ef..0000000 --- a/src/js/newkrok/three-utils/assets/assets.js +++ /dev/null @@ -1,233 +0,0 @@ -import * as THREE from 'three'; - -import { - loadAudio, - loadFBXModels, - loadGLTFModels, - loadTextures, -} from './loaders.js'; - -import { clone } from 'three/examples/jsm/utils/SkeletonUtils.js'; -import { deepDispose } from '../dispose-utils.js'; - -const _fbxModels = {}; -export const registerFBXModel = ({ id, fbxModel }) => - (_fbxModels[id] = fbxModel); -export const getFBXModel = (id) => { - const clonedModel = clone(_fbxModels[id]); - clonedModel.animations = [..._fbxModels[id].animations]; - return clonedModel; -}; - -const fbxSkeletonAnimations = {}; -export const registerFBXSkeletonAnimation = ({ id, fbxModel }) => - (fbxSkeletonAnimations[id] = fbxModel.animations[0]); -export const getFBXSkeletonAnimation = (id) => fbxSkeletonAnimations[id]; - -const _gltfModels = {}; -export const registerGLTFModel = ({ id, gltfModel }) => - (_gltfModels[id] = gltfModel); -export const getGLTFModel = (id) => _gltfModels[id]; - -const _textures = {}; -export const registerTexture = ({ id, texture }) => (_textures[id] = texture); -export const getTexture = (id) => _textures[id]; - -const _audioBuffers = {}; -export const registerAudioBuffer = ({ id, audioBuffer }) => - (_audioBuffers[id] = audioBuffer); -export const getAudioBuffer = (id) => _audioBuffers[id]; - -const applyMaterialConfig = ({ - material = null, - materialConfig = { texture: { id: null }, color: 0xffffff, alphaTest: 0.5 }, -}) => { - material.map = materialConfig?.texture?.id - ? getTexture(materialConfig?.texture.id) - : null; - material.alphaTest = materialConfig?.alphaTest || 0.5; - material.color = new THREE.Color(materialConfig?.color || 0xffffff); -}; - -const createMaterial = ( - materialConfig = { - materialType: null, - texture: { id: null, flipY: true }, - color: 0xffffff, - alphaTest: 0.5, - } -) => { - let material = null; - if (materialConfig instanceof Array) - material = materialConfig.map((config) => createMaterial(config)); - else if (materialConfig.materialType) { - const map = materialConfig?.texture?.id - ? getTexture(materialConfig?.texture.id) - : null; - if (map) { - map.flipY = materialConfig?.texture?.flipY ?? true; - } - material = new materialConfig.materialType({ - map, - alphaTest: materialConfig.alphaTest || 0.5, - color: new THREE.Color(materialConfig?.color || 0xffffff), - }); - } - return material; -}; - -export const disposeAssets = () => { - Object.entries(_textures).forEach(([key, texture]) => { - texture.dispose(); - delete _textures[key]; - }); - Object.entries(_fbxModels).forEach(([key, fbxModel]) => { - deepDispose(fbxModel); - delete _fbxModels[key]; - }); - Object.entries(_gltfModels).forEach(([key, gltfModel]) => { - deepDispose(gltfModel.scene); - delete _gltfModels[key]; - }); -}; - -export const loadAssets = ({ - textures, - gltfModels, - fbxModels, - fbxSkeletonAnimations, - audio, - onProgress, - verbose = true, -}) => - new Promise((resolve) => { - const result = []; - const assetCount = - textures.length + - gltfModels.length + - fbxModels.length + - fbxSkeletonAnimations.length + - audio.length; - let loadedCount = 0; - const updateProgress = () => { - loadedCount++; - onProgress && onProgress(loadedCount / assetCount); - }; - - loadTextures(textures, updateProgress) - .then((loadedTextures) => { - loadedTextures.forEach((element) => { - element.encoding = THREE.sRGBEncoding; - registerTexture(element); - }); - if (verbose) - console.log(`Textures(${loadedTextures.length}) are loaded...`); - - loadGLTFModels(gltfModels, updateProgress).then((loadedModels) => { - loadedModels.forEach((element) => { - const createdMaterial = createMaterial(element.material); - let textureIndex = 0; - element.gltfModel.scene.traverse((child) => { - if (child.isMesh) { - child.castShadow = true; - child.receiveShadow = true; - if (child.material instanceof Array) - child.material = createdMaterial; - else - child.material = - createdMaterial instanceof Array - ? createdMaterial[textureIndex] - : createdMaterial || child.material; - if (!createdMaterial && element.material) { - applyMaterialConfig({ - material: child.material, - materialConfig: - element.material instanceof Array - ? element.material[textureIndex] - : element.material, - }); - } - textureIndex++; - } - }); - registerGLTFModel(element); - }); - if (verbose) - console.log(`GLTF Models(${loadedModels.length}) are loaded...`); - - loadFBXModels(fbxSkeletonAnimations, updateProgress).then( - (loadedAnimations) => { - loadedAnimations.forEach((element) => { - registerFBXSkeletonAnimation(element); - }); - if (verbose) - console.log( - `FBX Skeleton Animations(${loadedAnimations.length}) are loaded...` - ); - - loadFBXModels(fbxModels, updateProgress) - .then((loadedModels) => { - loadedModels.forEach((element) => { - const createdMaterial = createMaterial(element.material); - let textureIndex = 0; - element.fbxModel.traverse((child) => { - if (child.isMesh) { - child.castShadow = true; - child.receiveShadow = true; - if (child.material instanceof Array) - child.material = createdMaterial; - else - child.material = - createdMaterial instanceof Array - ? createdMaterial[textureIndex] - : createdMaterial || child.material; - if (!createdMaterial && element.material) { - applyMaterialConfig({ - material: child.material, - materialConfig: - element.material instanceof Array - ? element.material[textureIndex] - : element.material, - }); - } - textureIndex++; - } - }); - registerFBXModel(element); - }); - result.fbxModels = [...loadedModels]; - if (verbose) - console.log( - `FBX Models(${loadedModels.length}) are loaded...` - ); - - loadAudio(audio, updateProgress) - .then((loadedAudio) => { - loadedAudio.forEach((element) => - registerAudioBuffer(element) - ); - if (verbose) - console.log( - `Audio files(${loadedAudio.length}) are loaded...` - ); - resolve(result); - }) - .catch((error) => - console.error( - `Fatal error during Audio files preloader phase: ${error}` - ) - ); - }) - .catch((error) => - console.error( - `Fatal error during FBX model preloader phase: ${error}` - ) - ); - } - ); - }); - }) - .catch((error) => - console.error(`Fatal error during texture preloader phase: ${error}`) - ); - }); diff --git a/src/js/newkrok/three-utils/assets/index.js b/src/js/newkrok/three-utils/assets/index.js deleted file mode 100644 index a600e64..0000000 --- a/src/js/newkrok/three-utils/assets/index.js +++ /dev/null @@ -1 +0,0 @@ -export * as AssetsUtils from './assets.js'; diff --git a/src/js/newkrok/three-utils/assets/loaders.js b/src/js/newkrok/three-utils/assets/loaders.js deleted file mode 100644 index 87ae024..0000000 --- a/src/js/newkrok/three-utils/assets/loaders.js +++ /dev/null @@ -1,216 +0,0 @@ -import * as THREE from 'three'; - -import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader.js'; -import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'; - -const gltfLoader = new GLTFLoader(); - -const fbxLoaders = Array.from({ length: 3 }, () => ({ - loader: new FBXLoader(), - isUsed: false, -})); -let fbxLoaderQueue = []; - -const textureLoaders = Array.from({ length: 3 }, () => ({ - loader: new THREE.TextureLoader(), - isUsed: false, -})); -let textureLoaderQueue = []; - -const audioLoaders = Array.from({ length: 3 }, () => ({ - loader: new THREE.AudioLoader(), - isUsed: false, -})); -let audioLoaderQueue = []; - -const getFBXLoader = (onComplete) => - getLoader(onComplete, fbxLoaders, fbxLoaderQueue); -const getTextureLoader = (onComplete) => - getLoader(onComplete, textureLoaders, textureLoaderQueue); -const getAudioLoader = (onComplete) => - getLoader(onComplete, audioLoaders, audioLoaderQueue); - -const getLoader = (onComplete, loaders, loaderQueue) => { - const loader = loaders.find((entry) => !entry.isUsed); - if (loader) { - loader.isUsed = true; - onComplete(loader.loader); - } else - loaderQueue.push((availableLoader) => { - onComplete(availableLoader.loader); - availableLoader.isUsed = true; - }); -}; - -const releaseFBXLoader = (loader) => - releaseLoader(loader, fbxLoaders, fbxLoaderQueue); -const releaseTextureLoader = (loader) => - releaseLoader(loader, textureLoaders, textureLoaderQueue); -const releaseAudioLoader = (loader) => - releaseLoader(loader, audioLoaders, audioLoaderQueue); - -const releaseLoader = (loader, loaders, loaderQueue) => { - const loaderObject = loaders.find((entry) => entry.loader === loader); - - if (loaderQueue.length > 0) { - loaderQueue[0](loaderObject); - loaderQueue.shift(); - } else { - loaderObject.isUsed = false; - } -}; - -const loadGLTFModelRoutine = ({ - list, - onElementLoaded, - onComplete, - onError, -}) => { - if (list.length > 0) { - const { url } = list[0]; - gltfLoader.load(url, ({ scene, animations }) => { - onElementLoaded({ - ...list[0], - gltfModel: { scene, animations }, - }); - list.shift(); - loadGLTFModelRoutine({ list, onElementLoaded, onComplete, onError }); - }); - } else onComplete(); -}; - -export const loadGLTFModels = (list, onProgress) => { - const elements = []; - const onElementLoaded = (element) => { - elements.push(element); - onProgress(); - }; - - const promise = new Promise((resolve, reject) => { - loadGLTFModelRoutine({ - list, - onElementLoaded, - onComplete: () => resolve(elements), - onError: (error) => reject(Error(`Something wrong happened: ${error}`)), - }); - }); - - return promise; -}; - -export const loadFBXModels = (list, onProgress) => { - const elements = []; - const onElementLoaded = (element) => { - elements.push(element); - onProgress(); - }; - - const promise = new Promise((resolve, reject) => { - if (list.length > 0) { - while (list.length > 0) { - const { url, id } = list[0]; - const current = list[0]; - list.shift(); - getFBXLoader((fbxLoader) => - fbxLoader.load( - url, - (fbxModel) => { - onElementLoaded({ ...current, id, fbxModel }); - releaseFBXLoader(fbxLoader); - - if (!fbxLoaders.some((entry) => entry.isUsed)) resolve(elements); - }, - null, - (error) => - reject( - Error( - `Something wrong happened with an FBX model: ${id}, url: ${url}, error: ${error}` - ) - ) - ) - ); - } - } else resolve([]); - }); - return promise; -}; - -export const loadTextures = (list, onProgress) => { - const elements = []; - const onElementLoaded = (element) => { - elements.push(element); - onProgress(); - }; - - const promise = new Promise((resolve, reject) => { - if (list.length > 0) { - while (list.length > 0) { - const { url, id } = list[0]; - list.shift(); - getTextureLoader((textureLoader) => - textureLoader.load( - url, - (texture) => { - texture.wrapS = THREE.RepeatWrapping; - texture.wrapT = THREE.RepeatWrapping; - - onElementLoaded({ id, texture }); - releaseTextureLoader(textureLoader); - - if (!textureLoaders.some((entry) => entry.isUsed)) { - resolve(elements); - } - }, - null, - (error) => - reject( - Error( - `Something wrong happened with a texture: ${id}, url: ${url}, error: ${error}` - ) - ) - ) - ); - } - } else resolve([]); - }); - - return promise; -}; - -export const loadAudio = (list, onProgress) => { - const elements = []; - const onElementLoaded = (element) => { - elements.push(element); - onProgress(); - }; - - const promise = new Promise((resolve, reject) => { - if (list.length > 0) { - while (list.length > 0) { - const { url, id } = list[0]; - list.shift(); - getAudioLoader((audioLoader) => - audioLoader.load( - url, - (audioBuffer) => { - onElementLoaded({ id, audioBuffer }); - releaseAudioLoader(audioLoader); - - if (!audioLoaders.some((entry) => entry.isUsed)) - resolve(elements); - }, - null, - (error) => - reject( - Error( - `Something wrong happened with an audio: ${id}, url: ${url}, error: ${error}` - ) - ) - ) - ); - } - } else resolve([]); - }); - - return promise; -}; diff --git a/src/js/newkrok/three-utils/audio/audio.js b/src/js/newkrok/three-utils/audio/audio.js deleted file mode 100644 index 799bdc7..0000000 --- a/src/js/newkrok/three-utils/audio/audio.js +++ /dev/null @@ -1,125 +0,0 @@ -import * as THREE from 'three'; - -import { PositionalAudioHelper } from 'three/examples/jsm/helpers/PositionalAudioHelper'; -import { getAudioBuffer } from '../assets/assets.js'; - -const defaultConfig = { loop: false, volume: 1, isMusic: false }; -let audioConfig = {}; - -const audioCache = {}; -const coreConfig = { - masterVolume: 1, - musicVolume: 1, - effectsVolume: 1, -}; - -export const setAudioConfig = (config) => (audioConfig = config); - -export const playAudio = ({ - audioId, - position, - radius, - scene, - camera, - cacheId, -}) => { - const now = Date.now(); - let audio; - if (!cacheId || !audioCache[cacheId]) { - const audioBuffer = getAudioBuffer(audioId); - const { loop, volume, isMusic } = { - ...defaultConfig, - ...audioConfig[audioId], - }; - - const listener = new THREE.AudioListener(); - let container; - if (position) { - audio = new THREE.PositionalAudio(listener); - audio.setRefDistance(radius); - const sphere = new THREE.SphereGeometry(radius, 32, 32); - container = new THREE.Mesh(sphere); - container.visible = false; - const helper = new PositionalAudioHelper(audio, radius); - audio.add(helper); - container.position.copy(position); - container.add(audio); - scene.add(container); - camera.add(listener); - } else audio = new THREE.Audio(listener); - audio.setBuffer(audioBuffer); - audio.setLoop(loop); - audio.setVolume( - volume * - coreConfig.masterVolume * - (isMusic ? coreConfig.musicVolume : coreConfig.effectsVolume) - ); - audioCache[cacheId || audioId] = { - audio, - audioId, - container, - lastPlayedTime: now, - }; - } else { - const { audio: cachedAudio, container } = audioCache[cacheId]; - audio = cachedAudio; - if (audio.isPlaying) audio.stop(); - if (container) container.position.copy(position); - audioCache[cacheId].lastPlayedTime = now; - } - audio.play(); -}; - -export const stopAudio = (cacheId) => { - const audio = getAudioCache(cacheId).audio; - if (audio && audio.isPlaying) { - audio.stop(); - } -}; - -export const getAudioCache = (cacheId) => - audioCache[cacheId] || { - audio: null, - audioId: '', - container: null, - lastPlayedTime: 0, - }; - -const updateMusicVolumes = () => { - Object.keys(audioCache).forEach((key) => { - const { audio, audioId } = getAudioCache(key); - if (audio) { - const { volume, isMusic } = { ...defaultConfig, ...audioConfig[audioId] }; - audio.setVolume( - volume * - coreConfig.masterVolume * - (isMusic ? coreConfig.musicVolume : coreConfig.effectsVolume) - ); - } - }); -}; - -export const setMasterVolume = (masterVolume) => { - coreConfig.masterVolume = masterVolume; - updateMusicVolumes(); -}; - -export const setMusicVolume = (musicVolume) => { - coreConfig.musicVolume = musicVolume; - updateMusicVolumes(); -}; - -export const setEffectsVolume = (effectsVolume) => { - coreConfig.effectsVolume = effectsVolume; - updateMusicVolumes(); -}; - -const AudioPlayer = { - playAudio, - stopAudio, - setMasterVolume, - setMusicVolume, - setEffectsVolume, -}; - -export default AudioPlayer; diff --git a/src/js/newkrok/three-utils/audio/index.js b/src/js/newkrok/three-utils/audio/index.js deleted file mode 100644 index 944d0e4..0000000 --- a/src/js/newkrok/three-utils/audio/index.js +++ /dev/null @@ -1 +0,0 @@ -export * as AudioUtils from './audio.js'; diff --git a/src/js/newkrok/three-utils/callback-utils.js b/src/js/newkrok/three-utils/callback-utils.js deleted file mode 100644 index 504e3ef..0000000 --- a/src/js/newkrok/three-utils/callback-utils.js +++ /dev/null @@ -1,55 +0,0 @@ -export const CallLimits = { - NO_LIMIT: -1, - CALL_1_PER_SECONDS: 1000, - CALL_15_PER_SECONDS: 1000 / 15, - CALL_30_PER_SECONDS: 1000 / 30, - CALL_45_PER_SECONDS: 1000 / 45, - CALL_60_PER_SECONDS: 1000 / 60, - CALL_120_PER_SECONDS: 1000 / 120, -}; - -let callData = {}; -export const callWithReducer = ({ - id, - callback, - callLimit, - elapsed, - callbackParam, - forceCallCount = false, -}) => { - if (!elapsed) return; - if (!callData[id]) callData[id] = { lastUpdate: -1, callCount: 0 }; - - const call = () => { - if (callbackParam) callback(callbackParam); - else callback(); - }; - - if (callLimit === CallLimits.NO_LIMIT) { - call(); - return; - } - - if (forceCallCount) { - const expectedCallCount = Math.floor(elapsed / (callLimit * 1000)); - while ( - callData[id].lastUpdate === -1 || - expectedCallCount > callData[id].callCount - ) { - call(); - callData[id].lastUpdate += callLimit; - callData[id].callCount++; - } - callData[id].lastUpdate = elapsed; - } else if ( - callData[id].lastUpdate === -1 || - elapsed - callData[id].lastUpdate >= callLimit - ) { - call(); - callData[id].lastUpdate = elapsed; - } -}; - -export const clearCallReducerData = (id) => delete callData[id]; - -export const clearAllCallReducerData = () => (callData = {}); diff --git a/src/js/newkrok/three-utils/dispose-utils.d.ts b/src/js/newkrok/three-utils/dispose-utils.d.ts deleted file mode 100644 index 4170c7f..0000000 --- a/src/js/newkrok/three-utils/dispose-utils.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -export function disposeMaterials( - material: THREE.Material | Array -): void; -export function deepDispose(container: THREE.Mesh): void; diff --git a/src/js/newkrok/three-utils/dispose-utils.js b/src/js/newkrok/three-utils/dispose-utils.js deleted file mode 100644 index d8423e4..0000000 --- a/src/js/newkrok/three-utils/dispose-utils.js +++ /dev/null @@ -1,28 +0,0 @@ -export const disposeMaterials = (material) => { - if (material.isMaterial) { - material.map?.dispose(); - material.map = null; - material.dispose(); - } else { - material.forEach(disposeMaterials); - } -}; - -export const deepDispose = (container) => { - const { isMesh, material, geometry } = container; - if (isMesh) { - if (material) { - disposeMaterials(material); - container.material = null; - } - - if (geometry) { - geometry.dispose(); - container.geometry = null; - } - container.parent?.remove(container); - } else if (container.children) { - container.children.forEach(deepDispose); - container.parent?.remove(container); - } -}; diff --git a/src/js/newkrok/three-utils/geom-utils.d.ts b/src/js/newkrok/three-utils/geom-utils.d.ts deleted file mode 100644 index 64c27e5..0000000 --- a/src/js/newkrok/three-utils/geom-utils.d.ts +++ /dev/null @@ -1,17 +0,0 @@ -export function sign( - point1: THREE.Vector3, - point2: THREE.Vector3, - point3: THREE.Vector3 -): number; -export function isPointInATriangle( - point: THREE.Vector3, - trianglePointA: THREE.Vector3, - trianglePointB: THREE.Vector3, - trianglePointC: THREE.Vector3 -): boolean; -export function yFromTriangle( - point: THREE.Vector3, - trianglePointA: THREE.Vector3, - trianglePointB: THREE.Vector3, - trianglePointC: THREE.Vector3 -): number; diff --git a/src/js/newkrok/three-utils/geom-utils.js b/src/js/newkrok/three-utils/geom-utils.js deleted file mode 100644 index be101a5..0000000 --- a/src/js/newkrok/three-utils/geom-utils.js +++ /dev/null @@ -1,50 +0,0 @@ -export const sign = (point1, point2, point3) => - (point1.x - point3.x) * (point2.z - point3.z) - - (point2.x - point3.x) * (point1.z - point3.z); - -export const isPointInATriangle = ( - point, - trianglePointA, - trianglePointB, - trianglePointC -) => { - const d1 = sign(point, trianglePointA, trianglePointB); - const d2 = sign(point, trianglePointB, trianglePointC); - const d3 = sign(point, trianglePointC, trianglePointA); - - return !((d1 < 0 || d2 < 0 || d3 < 0) && (d1 > 0 || d2 > 0 || d3 > 0)); -}; - -export const yFromTriangle = ( - point, - trianglePointA, - trianglePointB, - trianglePointC -) => { - const calc1 = - (trianglePointB.x - trianglePointA.x) * - (trianglePointC.y - trianglePointA.y) - - (trianglePointC.x - trianglePointA.x) * - (trianglePointB.y - trianglePointA.y); - const calc2 = - (trianglePointB.x - trianglePointA.x) * - (trianglePointC.z - trianglePointA.z) - - (trianglePointC.x - trianglePointA.x) * - (trianglePointB.z - trianglePointA.z); - const calc3 = - (trianglePointB.z - trianglePointA.z) * - (trianglePointC.y - trianglePointA.y) - - (trianglePointC.z - trianglePointA.z) * - (trianglePointB.y - trianglePointA.y); - const calc4 = - (trianglePointB.x - trianglePointA.x) * - (trianglePointC.z - trianglePointA.z) - - (trianglePointC.x - trianglePointA.x) * - (trianglePointB.z - trianglePointA.z); - - return ( - trianglePointA.y + - (calc1 / calc2) * (point.z - trianglePointA.z) - - (calc3 / calc4) * (point.x - trianglePointA.x) - ); -}; diff --git a/src/js/newkrok/three-utils/index.js b/src/js/newkrok/three-utils/index.js deleted file mode 100644 index 25589c9..0000000 --- a/src/js/newkrok/three-utils/index.js +++ /dev/null @@ -1,7 +0,0 @@ -export * as CallbackUtils from './callback-utils.js'; -export * as DisposeUtils from './dispose-utils.js'; -export * as ObjectUtils from './object-utils.js'; -export * as TimeUtils from './time-utils.js'; -export * as TokenUtils from './token.js'; -export * as Vector3Utils from './vector3-utils.js'; -export * as GeomUtils from './geom-utils.js'; diff --git a/src/js/newkrok/three-utils/object-utils.d.ts b/src/js/newkrok/three-utils/object-utils.d.ts deleted file mode 100644 index e7b48a4..0000000 --- a/src/js/newkrok/three-utils/object-utils.d.ts +++ /dev/null @@ -1,15 +0,0 @@ -export type ObjectOperationConfig = { - skippedProperties: Array; - applyToFirstObject: boolean; -}; - -export function patchObject( - objectA: T, - objectB: V, - config: ObjectOperationConfig -): T; -export function deepMerge( - objectA: T, - objectB: V, - config: ObjectOperationConfig -): T | V; diff --git a/src/js/newkrok/three-utils/object-utils.js b/src/js/newkrok/three-utils/object-utils.js deleted file mode 100644 index c4d70a5..0000000 --- a/src/js/newkrok/three-utils/object-utils.js +++ /dev/null @@ -1,85 +0,0 @@ -export const patchObject = ( - objectA, - objectB, - config = { skippedProperties: [], applyToFirstObject: false } -) => { - const result = {}; - Object.keys(objectA).forEach((key) => { - if (!config.skippedProperties || !config.skippedProperties.includes(key)) { - if ( - typeof objectA[key] === 'object' && - objectA[key] && - objectB[key] && - !Array.isArray(objectA[key]) - ) { - result[key] = patchObject(objectA[key], objectB[key], config); - } else { - result[key] = - objectB[key] === 0 - ? 0 - : objectB[key] === false - ? false - : objectB[key] || objectA[key]; - if (config.applyToFirstObject) objectA[key] = result[key]; - } - } - }); - return result; -}; - -export const deepMerge = ( - objectA, - objectB, - config = { skippedProperties: [], applyToFirstObject: false } -) => { - const result = {}; - Array.from( - new Set([...Object.keys(objectA || {}), ...Object.keys(objectB || {})]) - ).forEach((key) => { - if (!config.skippedProperties || !config.skippedProperties.includes(key)) { - if ( - typeof objectA[key] === 'object' && - objectA[key] && - objectB[key] && - !Array.isArray(objectA[key]) - ) { - result[key] = deepMerge(objectA[key], objectB[key], config); - } else { - result[key] = - objectB[key] === 0 - ? 0 - : objectB[key] === false - ? false - : objectB[key] || objectA[key]; - if (config.applyToFirstObject) objectA[key] = result[key]; - } - } - }); - return result; -}; - -const getObjectDiff = ( - objectA, - objectB, - config = { skippedProperties: [] } -) => { - const result = {}; - Object.keys(objectA).forEach((key) => { - if (!config.skippedProperties || !config.skippedProperties.includes(key)) { - if ( - typeof objectA[key] === 'object' && - objectA[key] && - objectB[key] && - !Array.isArray(objectA[key]) - ) { - const objectDiff = getObjectDiff(objectA[key], objectB[key], config); - if (Object.keys(objectDiff).length > 0) result[key] = objectDiff; - } else { - const mergedValue = - objectB[key] === 0 ? 0 : objectB[key] || objectA[key]; - if (mergedValue !== objectA[key]) result[key] = mergedValue; - } - } - }); - return result; -}; diff --git a/src/js/newkrok/three-utils/time-utils.d.ts b/src/js/newkrok/three-utils/time-utils.d.ts deleted file mode 100644 index 7e05f35..0000000 --- a/src/js/newkrok/three-utils/time-utils.d.ts +++ /dev/null @@ -1 +0,0 @@ -export function formatTime(timeInMS: number, pattern: string): string; diff --git a/src/js/newkrok/three-utils/time-utils.js b/src/js/newkrok/three-utils/time-utils.js deleted file mode 100644 index f3ccf9f..0000000 --- a/src/js/newkrok/three-utils/time-utils.js +++ /dev/null @@ -1,31 +0,0 @@ -export const TimePattern = { - HH_MM_SS: 'HH:MM:SS', - MM_SS: 'MM:SS', - MM_SS_MS: 'MM:SS.MS', -}; - -const patterns = [ - { pattern: 'HH', routine: ({ hours }) => String(hours).padStart(2, '0') }, - { pattern: 'MM', routine: ({ minutes }) => String(minutes).padStart(2, '0') }, - { pattern: 'SS', routine: ({ seconds }) => String(seconds).padStart(2, '0') }, - { - pattern: 'MS', - routine: ({ milliseconds }) => String(milliseconds).padStart(3, '0'), - }, -]; - -export const formatTime = (timeInMS, pattern) => { - const milliseconds = Math.floor(timeInMS % 1000); - const seconds = Math.floor((timeInMS / 1000) % 60); - const minutes = Math.floor(Math.floor(timeInMS / 1000 / 60) % 60); - const hours = Math.floor((Math.floor(timeInMS / 1000 / 60) / 60) % 24); - const timeDetails = { hours, minutes, seconds, milliseconds }; - - let result = pattern; - patterns.forEach( - ({ pattern: currentPattern, routine }) => - (result = result.replace(currentPattern, routine(timeDetails))) - ); - - return result; -}; diff --git a/src/js/newkrok/three-utils/token.d.ts b/src/js/newkrok/three-utils/token.d.ts deleted file mode 100644 index 9531250..0000000 --- a/src/js/newkrok/three-utils/token.d.ts +++ /dev/null @@ -1 +0,0 @@ -export function getUniqueId(): number; diff --git a/src/js/newkrok/three-utils/token.js b/src/js/newkrok/three-utils/token.js deleted file mode 100644 index 81f09a1..0000000 --- a/src/js/newkrok/three-utils/token.js +++ /dev/null @@ -1,2 +0,0 @@ -let uniqueId = 0; -export const getUniqueId = () => uniqueId++; diff --git a/src/js/newkrok/three-utils/vector3-utils.d.ts b/src/js/newkrok/three-utils/vector3-utils.d.ts deleted file mode 100644 index a0be7ef..0000000 --- a/src/js/newkrok/three-utils/vector3-utils.d.ts +++ /dev/null @@ -1 +0,0 @@ -export function absVector3(vector: THREE.Vector3): THREE.Vector3; diff --git a/src/js/newkrok/three-utils/vector3-utils.js b/src/js/newkrok/three-utils/vector3-utils.js deleted file mode 100644 index 2b9458b..0000000 --- a/src/js/newkrok/three-utils/vector3-utils.js +++ /dev/null @@ -1,7 +0,0 @@ -export const absVector3 = (vector) => { - vector.x = Math.abs(vector.x); - vector.y = Math.abs(vector.y); - vector.z = Math.abs(vector.z); - - return vector; -}; From c0a8dfed986e74956cec20f9dcdd77b40ee36f97 Mon Sep 17 00:00:00 2001 From: Krisztian Somoracz Date: Thu, 16 Oct 2025 22:17:02 +0200 Subject: [PATCH 19/20] feat: add comprehensive test suite with 100% coverage - Add complete test coverage for all utility modules - callback-utils: 10 tests covering CallLimits constants and timing logic - dispose-utils: 13 tests with Three.js mocking for material/geometry disposal - geom-utils: 14 tests for geometric calculations with Vector3 - object-utils: 21 tests for complex object operations (patch, merge, diff) - vector3-utils: 8 tests for Vector3 absolute value mutations - Enhanced time-utils: additional edge cases and TimePattern validation - Enhanced token-utils: rapid calls and consistency testing Total: 81 tests with 100% statement coverage, 96.8% branch coverage All tests passing with comprehensive edge case handling --- src/__tests__/callback-utils.test.ts | 211 ++++++++++++++++++++ src/__tests__/dispose-utils.test.ts | 213 ++++++++++++++++++++ src/__tests__/geom-utils.test.ts | 172 +++++++++++++++++ src/__tests__/object-utils.test.ts | 277 +++++++++++++++++++++++++++ src/__tests__/time-utils.test.ts | 32 ++++ src/__tests__/token.test.ts | 30 +++ src/__tests__/vector3-utils.test.ts | 88 +++++++++ 7 files changed, 1023 insertions(+) create mode 100644 src/__tests__/callback-utils.test.ts create mode 100644 src/__tests__/dispose-utils.test.ts create mode 100644 src/__tests__/geom-utils.test.ts create mode 100644 src/__tests__/object-utils.test.ts create mode 100644 src/__tests__/vector3-utils.test.ts diff --git a/src/__tests__/callback-utils.test.ts b/src/__tests__/callback-utils.test.ts new file mode 100644 index 0000000..95c8647 --- /dev/null +++ b/src/__tests__/callback-utils.test.ts @@ -0,0 +1,211 @@ +import { + callWithReducer, + clearCallReducerData, + clearAllCallReducerData, + CallLimits +} from '../callback-utils.js'; + +describe('CallbackUtils', () => { + beforeEach(() => { + clearAllCallReducerData(); + jest.clearAllMocks(); + }); + + describe('CallLimits', () => { + it('should have correct constant values', () => { + expect(CallLimits.NO_LIMIT).toBe(-1); + expect(CallLimits.CALL_1_PER_SECONDS).toBe(1000); + expect(CallLimits.CALL_15_PER_SECONDS).toBe(1000 / 15); + expect(CallLimits.CALL_30_PER_SECONDS).toBe(1000 / 30); + expect(CallLimits.CALL_45_PER_SECONDS).toBe(1000 / 45); + expect(CallLimits.CALL_60_PER_SECONDS).toBe(1000 / 60); + expect(CallLimits.CALL_120_PER_SECONDS).toBe(1000 / 120); + }); + }); + + describe('callWithReducer', () => { + const mockCallback = jest.fn(); + + beforeEach(() => { + mockCallback.mockClear(); + }); + + it('should not call callback when elapsed is 0 or falsy', () => { + callWithReducer({ + id: 'test', + callback: mockCallback, + callLimit: CallLimits.CALL_30_PER_SECONDS, + elapsed: 0, + }); + + expect(mockCallback).not.toHaveBeenCalled(); + }); + + it('should call callback immediately with NO_LIMIT', () => { + callWithReducer({ + id: 'test', + callback: mockCallback, + callLimit: CallLimits.NO_LIMIT, + elapsed: 100, + }); + + expect(mockCallback).toHaveBeenCalledTimes(1); + }); + + it('should call callback with parameter when provided', () => { + const param = { test: 'data' }; + + callWithReducer({ + id: 'test', + callback: mockCallback, + callLimit: CallLimits.NO_LIMIT, + elapsed: 100, + callbackParam: param, + }); + + expect(mockCallback).toHaveBeenCalledWith(param); + }); + + it('should respect call limit timing', () => { + const callLimit = 100; // 100ms limit + + // First call should work (elapsed > 0 is required) + callWithReducer({ + id: 'test', + callback: mockCallback, + callLimit, + elapsed: 50, + }); + expect(mockCallback).toHaveBeenCalledTimes(1); + + // Second call within limit should not trigger + callWithReducer({ + id: 'test', + callback: mockCallback, + callLimit, + elapsed: 100, + }); + expect(mockCallback).toHaveBeenCalledTimes(1); + + // Third call after limit should trigger + callWithReducer({ + id: 'test', + callback: mockCallback, + callLimit, + elapsed: 200, + }); + expect(mockCallback).toHaveBeenCalledTimes(2); + }); + + it('should handle forceCallCount correctly', () => { + const callLimit = 0.1; // 0.1s limit (100ms in seconds) + + callWithReducer({ + id: 'test', + callback: mockCallback, + callLimit, + elapsed: 250, + forceCallCount: true, + }); + + // Should call multiple times based on elapsed time (250ms / 100ms = 2+ calls) + expect(mockCallback).toHaveBeenCalledTimes(2); + }); + + it('should handle multiple different IDs independently', () => { + const mockCallback1 = jest.fn(); + const mockCallback2 = jest.fn(); + const callLimit = 100; + + callWithReducer({ + id: 'test1', + callback: mockCallback1, + callLimit, + elapsed: 50, + }); + + callWithReducer({ + id: 'test2', + callback: mockCallback2, + callLimit, + elapsed: 50, + }); + + expect(mockCallback1).toHaveBeenCalledTimes(1); + expect(mockCallback2).toHaveBeenCalledTimes(1); + }); + }); + + describe('clearCallReducerData', () => { + it('should clear data for specific ID', () => { + const mockCallback = jest.fn(); + + // Set up some call data + callWithReducer({ + id: 'test', + callback: mockCallback, + callLimit: 100, + elapsed: 50, + }); + + const result = clearCallReducerData('test'); + expect(result).toBe(true); + + // Next call should behave as if it's the first call + callWithReducer({ + id: 'test', + callback: mockCallback, + callLimit: 100, + elapsed: 100, + }); + expect(mockCallback).toHaveBeenCalledTimes(2); + }); + + it('should return true when deleting non-existent ID (JavaScript delete behavior)', () => { + const result = clearCallReducerData('non-existent'); + expect(result).toBe(true); + }); + }); + + describe('clearAllCallReducerData', () => { + it('should clear all call data', () => { + const mockCallback1 = jest.fn(); + const mockCallback2 = jest.fn(); + + // Set up call data for multiple IDs + callWithReducer({ + id: 'test1', + callback: mockCallback1, + callLimit: 100, + elapsed: 50, + }); + + callWithReducer({ + id: 'test2', + callback: mockCallback2, + callLimit: 100, + elapsed: 50, + }); + + clearAllCallReducerData(); + + // Both should behave as first calls + callWithReducer({ + id: 'test1', + callback: mockCallback1, + callLimit: 100, + elapsed: 100, + }); + + callWithReducer({ + id: 'test2', + callback: mockCallback2, + callLimit: 100, + elapsed: 100, + }); + + expect(mockCallback1).toHaveBeenCalledTimes(2); + expect(mockCallback2).toHaveBeenCalledTimes(2); + }); + }); +}); \ No newline at end of file diff --git a/src/__tests__/dispose-utils.test.ts b/src/__tests__/dispose-utils.test.ts new file mode 100644 index 0000000..7d88d96 --- /dev/null +++ b/src/__tests__/dispose-utils.test.ts @@ -0,0 +1,213 @@ +import { disposeMaterials, deepDispose } from '../dispose-utils.js'; + +// Mock Three.js objects with proper type casting +const createMockMaterial = (hasMap = false): any => ({ + isMaterial: true, + map: hasMap ? { dispose: jest.fn() } : null, + dispose: jest.fn(), +}); + +const createMockGeometry = (): any => ({ + dispose: jest.fn(), +}); + +const createMockMesh = (hasMaterial = true, hasGeometry = true): any => ({ + isMesh: true, + material: hasMaterial ? createMockMaterial() : null, + geometry: hasGeometry ? createMockGeometry() : null, + parent: { + remove: jest.fn(), + }, +}); + +const createMockObject3D = (children: any[] = []): any => ({ + children, + parent: { + remove: jest.fn(), + }, +}); + +describe('DisposeUtils', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + describe('disposeMaterials', () => { + it('should dispose single material without map', () => { + const material = createMockMaterial(); + + disposeMaterials(material as any); + + expect(material.dispose).toHaveBeenCalledTimes(1); + }); + + it('should dispose single material with map', () => { + const material = createMockMaterial(true); + const mapDisposeSpy = material.map!.dispose; + + disposeMaterials(material as any); + + expect(mapDisposeSpy).toHaveBeenCalledTimes(1); + expect(material.map).toBeNull(); + expect(material.dispose).toHaveBeenCalledTimes(1); + }); + + it('should dispose array of materials', () => { + const material1 = createMockMaterial(); + const material2 = createMockMaterial(true); + const material2MapDispose = material2.map!.dispose; + const materials = [material1, material2]; + + disposeMaterials(materials as any); + + expect(material1.dispose).toHaveBeenCalledTimes(1); + expect(material2MapDispose).toHaveBeenCalledTimes(1); + expect(material2.dispose).toHaveBeenCalledTimes(1); + expect(material2.map).toBeNull(); + }); + + it('should handle nested arrays of materials', () => { + const material1 = createMockMaterial(); + const material2 = createMockMaterial(true); + const material2MapDispose = material2.map!.dispose; + const nestedMaterials = [[material1], [material2]]; + + disposeMaterials(nestedMaterials as any); + + expect(material1.dispose).toHaveBeenCalledTimes(1); + expect(material2MapDispose).toHaveBeenCalledTimes(1); + expect(material2.dispose).toHaveBeenCalledTimes(1); + }); + }); + + describe('deepDispose', () => { + it('should dispose mesh with material and geometry', () => { + const mesh = createMockMesh(); + const materialDispose = mesh.material!.dispose; + const geometryDispose = mesh.geometry!.dispose; + + deepDispose(mesh as any); + + expect(materialDispose).toHaveBeenCalledTimes(1); + expect(geometryDispose).toHaveBeenCalledTimes(1); + expect(mesh.material).toBeNull(); + expect(mesh.geometry).toBeNull(); + expect(mesh.parent.remove).toHaveBeenCalledWith(mesh); + }); + + it('should dispose mesh with material that has map', () => { + const mesh = { + isMesh: true, + material: createMockMaterial(true), + geometry: createMockGeometry(), + parent: { + remove: jest.fn(), + }, + }; + const materialMapDispose = mesh.material.map!.dispose; + const materialDispose = mesh.material.dispose; + const geometryDispose = mesh.geometry.dispose; + + deepDispose(mesh as any); + + expect(materialMapDispose).toHaveBeenCalledTimes(1); + expect(materialDispose).toHaveBeenCalledTimes(1); + expect(geometryDispose).toHaveBeenCalledTimes(1); + expect(mesh.parent.remove).toHaveBeenCalledWith(mesh); + }); + + it('should dispose mesh with array of materials', () => { + const material1 = createMockMaterial(); + const material2 = createMockMaterial(true); + const material2MapDispose = material2.map!.dispose; + const mesh = { + isMesh: true, + material: [material1, material2], + geometry: createMockGeometry(), + parent: { + remove: jest.fn(), + }, + }; + const geometryDispose = mesh.geometry.dispose; + + deepDispose(mesh as any); + + expect(material1.dispose).toHaveBeenCalledTimes(1); + expect(material2MapDispose).toHaveBeenCalledTimes(1); + expect(material2.dispose).toHaveBeenCalledTimes(1); + expect(geometryDispose).toHaveBeenCalledTimes(1); + expect(mesh.parent.remove).toHaveBeenCalledWith(mesh); + }); + + it('should handle mesh without material', () => { + const mesh = createMockMesh(false, true); + const geometryDispose = mesh.geometry!.dispose; + + deepDispose(mesh as any); + + expect(geometryDispose).toHaveBeenCalledTimes(1); + expect(mesh.parent.remove).toHaveBeenCalledWith(mesh); + }); + + it('should handle mesh without geometry', () => { + const mesh = createMockMesh(true, false); + const materialDispose = mesh.material!.dispose; + + deepDispose(mesh as any); + + expect(materialDispose).toHaveBeenCalledTimes(1); + expect(mesh.parent.remove).toHaveBeenCalledWith(mesh); + }); + + it('should recursively dispose children in Object3D', () => { + const childMesh1 = createMockMesh(); + const childMesh2 = createMockMesh(); + const child1MaterialDispose = childMesh1.material!.dispose; + const child1GeometryDispose = childMesh1.geometry!.dispose; + const child2MaterialDispose = childMesh2.material!.dispose; + const child2GeometryDispose = childMesh2.geometry!.dispose; + const container = createMockObject3D([childMesh1, childMesh2]); + + deepDispose(container as any); + + expect(child1MaterialDispose).toHaveBeenCalledTimes(1); + expect(child1GeometryDispose).toHaveBeenCalledTimes(1); + expect(child2MaterialDispose).toHaveBeenCalledTimes(1); + expect(child2GeometryDispose).toHaveBeenCalledTimes(1); + expect(container.parent.remove).toHaveBeenCalledWith(container); + }); + + it('should handle nested container hierarchy', () => { + const mesh = createMockMesh(); + const materialDispose = mesh.material!.dispose; + const geometryDispose = mesh.geometry!.dispose; + const subContainer = createMockObject3D([mesh]); + const mainContainer = createMockObject3D([subContainer]); + + deepDispose(mainContainer as any); + + expect(materialDispose).toHaveBeenCalledTimes(1); + expect(geometryDispose).toHaveBeenCalledTimes(1); + expect(subContainer.parent.remove).toHaveBeenCalledWith(subContainer); + expect(mainContainer.parent.remove).toHaveBeenCalledWith(mainContainer); + }); + + it('should handle container without parent', () => { + const mesh = createMockMesh(); + const materialDispose = mesh.material!.dispose; + const geometryDispose = mesh.geometry!.dispose; + mesh.parent = null; + + expect(() => deepDispose(mesh as any)).not.toThrow(); + expect(materialDispose).toHaveBeenCalledTimes(1); + expect(geometryDispose).toHaveBeenCalledTimes(1); + }); + + it('should handle empty container', () => { + const container = createMockObject3D([]); + + expect(() => deepDispose(container as any)).not.toThrow(); + expect(container.parent.remove).toHaveBeenCalledWith(container); + }); + }); +}); \ No newline at end of file diff --git a/src/__tests__/geom-utils.test.ts b/src/__tests__/geom-utils.test.ts new file mode 100644 index 0000000..9bf628f --- /dev/null +++ b/src/__tests__/geom-utils.test.ts @@ -0,0 +1,172 @@ +import { sign, isPointInATriangle, yFromTriangle } from '../geom-utils.js'; +import * as THREE from 'three'; + +describe('GeomUtils', () => { + describe('sign', () => { + it('should calculate positive sign for counter-clockwise points', () => { + const point1 = new THREE.Vector3(0, 0, 0); + const point2 = new THREE.Vector3(1, 0, 0); + const point3 = new THREE.Vector3(0, 0, 1); + + const result = sign(point1, point2, point3); + + expect(result).toBeGreaterThan(0); + }); + + it('should calculate negative sign for clockwise points', () => { + const point1 = new THREE.Vector3(0, 0, 0); + const point2 = new THREE.Vector3(0, 0, 1); + const point3 = new THREE.Vector3(1, 0, 0); + + const result = sign(point1, point2, point3); + + expect(result).toBeLessThan(0); + }); + + it('should return zero for collinear points', () => { + const point1 = new THREE.Vector3(0, 0, 0); + const point2 = new THREE.Vector3(1, 0, 1); + const point3 = new THREE.Vector3(2, 0, 2); + + const result = sign(point1, point2, point3); + + expect(result).toBe(0); + }); + + it('should handle points with different y coordinates', () => { + const point1 = new THREE.Vector3(0, 5, 0); + const point2 = new THREE.Vector3(1, 10, 0); + const point3 = new THREE.Vector3(0, 15, 1); + + const result = sign(point1, point2, point3); + + expect(typeof result).toBe('number'); + expect(result).toBeGreaterThan(0); + }); + }); + + describe('isPointInATriangle', () => { + it('should return true for point inside triangle', () => { + const point = new THREE.Vector3(0.5, 0, 0.25); + const triangleA = new THREE.Vector3(0, 0, 0); + const triangleB = new THREE.Vector3(1, 0, 0); + const triangleC = new THREE.Vector3(0.5, 0, 1); + + const result = isPointInATriangle(point, triangleA, triangleB, triangleC); + + expect(result).toBe(true); + }); + + it('should return false for point outside triangle', () => { + const point = new THREE.Vector3(2, 0, 2); + const triangleA = new THREE.Vector3(0, 0, 0); + const triangleB = new THREE.Vector3(1, 0, 0); + const triangleC = new THREE.Vector3(0.5, 0, 1); + + const result = isPointInATriangle(point, triangleA, triangleB, triangleC); + + expect(result).toBe(false); + }); + + it('should return true for point on triangle vertex', () => { + const point = new THREE.Vector3(0, 0, 0); + const triangleA = new THREE.Vector3(0, 0, 0); + const triangleB = new THREE.Vector3(1, 0, 0); + const triangleC = new THREE.Vector3(0.5, 0, 1); + + const result = isPointInATriangle(point, triangleA, triangleB, triangleC); + + expect(result).toBe(true); + }); + + it('should return true for point on triangle edge', () => { + const point = new THREE.Vector3(0.5, 0, 0); + const triangleA = new THREE.Vector3(0, 0, 0); + const triangleB = new THREE.Vector3(1, 0, 0); + const triangleC = new THREE.Vector3(0.5, 0, 1); + + const result = isPointInATriangle(point, triangleA, triangleB, triangleC); + + expect(result).toBe(true); + }); + + it('should handle triangle with different orientations', () => { + const point = new THREE.Vector3(0.5, 0, 0.25); + const triangleA = new THREE.Vector3(1, 0, 0); + const triangleB = new THREE.Vector3(0, 0, 0); + const triangleC = new THREE.Vector3(0.5, 0, 1); + + const result = isPointInATriangle(point, triangleA, triangleB, triangleC); + + expect(result).toBe(true); + }); + }); + + describe('yFromTriangle', () => { + it('should calculate correct Y coordinate from triangle plane', () => { + // Create a simple triangle in XZ plane with known Y values + const triangleA = new THREE.Vector3(0, 0, 0); + const triangleB = new THREE.Vector3(2, 0, 0); + const triangleC = new THREE.Vector3(1, 2, 1); + + // Point at the center should have Y value of 1 + const point = new THREE.Vector3(1, 0, 0.5); + + const result = yFromTriangle(point, triangleA, triangleB, triangleC); + + expect(typeof result).toBe('number'); + expect(isFinite(result)).toBe(true); + }); + + it('should handle horizontal triangle (all Y coordinates same)', () => { + const triangleA = new THREE.Vector3(0, 5, 0); + const triangleB = new THREE.Vector3(1, 5, 0); + const triangleC = new THREE.Vector3(0.5, 5, 1); + + const point = new THREE.Vector3(0.5, 0, 0.25); + + const result = yFromTriangle(point, triangleA, triangleB, triangleC); + + expect(result).toBe(5); + }); + + it('should calculate Y for point at triangle vertex', () => { + const triangleA = new THREE.Vector3(0, 1, 0); + const triangleB = new THREE.Vector3(2, 3, 0); + const triangleC = new THREE.Vector3(1, 2, 2); + + // Point at vertex A should return Y coordinate of vertex A + const point = new THREE.Vector3(0, 0, 0); + + const result = yFromTriangle(point, triangleA, triangleB, triangleC); + + expect(result).toBe(1); + }); + + it('should handle degenerate triangle (collinear points)', () => { + const triangleA = new THREE.Vector3(0, 0, 0); + const triangleB = new THREE.Vector3(1, 1, 0); + const triangleC = new THREE.Vector3(2, 2, 0); + + const point = new THREE.Vector3(0.5, 0, 0); + + const result = yFromTriangle(point, triangleA, triangleB, triangleC); + + // Should handle division by zero gracefully + expect(typeof result).toBe('number'); + }); + + it('should handle negative coordinates', () => { + const triangleA = new THREE.Vector3(-1, -1, -1); + const triangleB = new THREE.Vector3(1, -1, -1); + const triangleC = new THREE.Vector3(0, 1, 1); + + const point = new THREE.Vector3(0, 0, 0); + + const result = yFromTriangle(point, triangleA, triangleB, triangleC); + + expect(typeof result).toBe('number'); + expect(isFinite(result)).toBe(true); + }); + }); +}); \ No newline at end of file diff --git a/src/__tests__/object-utils.test.ts b/src/__tests__/object-utils.test.ts new file mode 100644 index 0000000..ca5916b --- /dev/null +++ b/src/__tests__/object-utils.test.ts @@ -0,0 +1,277 @@ +import { patchObject, deepMerge, getObjectDiff, ObjectOperationConfig } from '../object-utils.js'; + +describe('ObjectUtils', () => { + describe('patchObject', () => { + it('should patch simple object properties', () => { + const objectA = { a: 1, b: 2, c: 3 }; + const objectB = { b: 5, c: 6 }; + + const result = patchObject(objectA, objectB); + + expect(result).toEqual({ a: 1, b: 5, c: 6 }); + }); + + it('should handle zero and false values correctly', () => { + const objectA = { a: 1, b: true, c: 'test' }; + const objectB = { a: 0, b: false, c: null }; + + const result = patchObject(objectA, objectB); + + expect(result).toEqual({ a: 0, b: false, c: 'test' }); + }); + + it('should handle nested objects', () => { + const objectA = { + level1: { + a: 1, + b: 2, + level2: { + x: 10, + y: 20 + } + } + }; + const objectB = { + level1: { + b: 5, + level2: { + y: 25, + z: 30 + } + } + }; + + const result = patchObject(objectA, objectB); + + expect(result.level1.a).toBe(1); + expect(result.level1.b).toBe(5); + expect(result.level1.level2.x).toBe(10); + expect(result.level1.level2.y).toBe(25); + }); + + it('should skip properties when specified in config', () => { + const objectA = { a: 1, b: 2, c: 3 }; + const objectB = { a: 10, b: 20, c: 30 }; + const config: ObjectOperationConfig = { + skippedProperties: ['b'] + }; + + const result = patchObject(objectA, objectB, config); + + expect(result).toEqual({ a: 10, c: 30 }); + }); + + it('should apply to first object when specified in config', () => { + const objectA = { a: 1, b: 2, c: 3 }; + const objectB = { b: 5, c: 6 }; + const config: ObjectOperationConfig = { + applyToFirstObject: true + }; + + const result = patchObject(objectA, objectB, config); + + expect(result).toEqual({ a: 1, b: 5, c: 6 }); + expect(objectA).toEqual({ a: 1, b: 5, c: 6 }); // Should modify original + }); + + it('should handle arrays correctly (not merge them)', () => { + const objectA = { arr: [1, 2, 3], other: 'test' }; + const objectB = { arr: [4, 5], other: 'updated' }; + + const result = patchObject(objectA, objectB); + + expect(result.arr).toEqual([4, 5]); + expect(result.other).toBe('updated'); + }); + }); + + describe('deepMerge', () => { + it('should merge simple objects', () => { + const objectA = { a: 1, b: 2 }; + const objectB = { c: 3, d: 4 }; + + const result = deepMerge(objectA, objectB); + + expect(result).toEqual({ a: 1, b: 2, c: 3, d: 4 }); + }); + + it('should handle overlapping properties', () => { + const objectA = { a: 1, b: 2, c: 3 }; + const objectB = { b: 20, c: 30, d: 40 }; + + const result = deepMerge(objectA, objectB); + + expect(result).toEqual({ a: 1, b: 20, c: 30, d: 40 }); + }); + + it('should handle zero and false values correctly', () => { + const objectA = { a: 1, b: true, c: 'test' }; + const objectB = { a: 0, b: false, c: 'test' }; + + const result = deepMerge(objectA, objectB) as any; + + expect(result.a).toBe(0); + expect(result.b).toBe(false); + expect(result.c).toBe('test'); + }); + + it('should handle nested objects', () => { + const objectA = { + level1: { + a: 1, + level2: { x: 10 } + } + }; + const objectB = { + level1: { + b: 2, + level2: { y: 20 } + } + }; + + const result = deepMerge(objectA, objectB) as any; + + expect(result.level1.a).toBe(1); + expect(result.level1.b).toBe(2); + expect(result.level1.level2.x).toBe(10); + expect(result.level1.level2.y).toBe(20); + }); + + it('should handle null/undefined objects', () => { + const objectA = { a: 1, b: 2 }; + const objectB = null; + + const result = deepMerge(objectA, objectB); + + expect(result).toEqual({ a: 1, b: 2 }); + }); + + it('should skip properties when specified in config', () => { + const objectA = { a: 1, b: 2 }; + const objectB = { b: 20, c: 3 }; + const config: ObjectOperationConfig = { + skippedProperties: ['b'] + }; + + const result = deepMerge(objectA, objectB, config); + + expect(result).toEqual({ a: 1, c: 3 }); + }); + + it('should apply to first object when specified in config', () => { + const objectA = { a: 1, b: 2 }; + const objectB = { c: 3, d: 4 }; + const config: ObjectOperationConfig = { + applyToFirstObject: true + }; + + const result = deepMerge(objectA, objectB, config); + + expect(result).toEqual({ a: 1, b: 2, c: 3, d: 4 }); + expect(objectA).toEqual({ a: 1, b: 2, c: 3, d: 4 }); // Should modify original + }); + }); + + describe('getObjectDiff', () => { + it('should return empty object when objects are identical', () => { + const objectA = { a: 1, b: 2, c: 3 }; + const objectB = { a: 1, b: 2, c: 3 }; + + const result = getObjectDiff(objectA, objectB); + + expect(result).toEqual({}); + }); + + it('should return differences between objects', () => { + const objectA = { a: 1, b: 2, c: 3 }; + const objectB = { a: 1, b: 20, c: 3 }; + + const result = getObjectDiff(objectA, objectB); + + expect(result).toEqual({ b: 20 }); + }); + + it('should handle zero values correctly', () => { + const objectA = { a: 1, b: 'original', c: 'test' }; + const objectB = { a: 0, b: 'changed', c: 'test' }; + + const result = getObjectDiff(objectA, objectB); + + expect(result).toEqual({ a: 0, b: 'changed' }); + }); + + it('should handle false values (treated as falsy)', () => { + const objectA = { a: true, b: 'value' }; + const objectB = { a: false, b: 'value' }; + + const result = getObjectDiff(objectA, objectB); + + // false is falsy, so it falls back to objectA value, no diff + expect(result).toEqual({}); + }); + + it('should handle nested objects', () => { + const objectA = { + level1: { + a: 1, + b: 2, + level2: { + x: 10, + y: 20 + } + } + }; + const objectB = { + level1: { + a: 1, + b: 5, + level2: { + x: 15, + y: 20 + } + } + }; + + const result = getObjectDiff(objectA, objectB); + + expect(result).toEqual({ + level1: { + b: 5, + level2: { + x: 15 + } + } + }); + }); + + it('should handle missing properties in objectB', () => { + const objectA = { a: 1, b: 2, c: 3 }; + const objectB = { a: 1, c: 30 }; + + const result = getObjectDiff(objectA, objectB); + + expect(result).toEqual({ c: 30 }); + }); + + it('should skip properties when specified in config', () => { + const objectA = { a: 1, b: 2, c: 3 }; + const objectB = { a: 10, b: 20, c: 30 }; + const config: ObjectOperationConfig = { + skippedProperties: ['b'] + }; + + const result = getObjectDiff(objectA, objectB, config); + + expect(result).toEqual({ a: 10, c: 30 }); + }); + + it('should handle arrays correctly', () => { + const objectA = { arr: [1, 2, 3], other: 'same' }; + const objectB = { arr: [4, 5], other: 'same' }; + + const result = getObjectDiff(objectA, objectB); + + expect(result).toEqual({ arr: [4, 5] }); + }); + }); +}); \ No newline at end of file diff --git a/src/__tests__/time-utils.test.ts b/src/__tests__/time-utils.test.ts index 6fdf368..d2031d1 100644 --- a/src/__tests__/time-utils.test.ts +++ b/src/__tests__/time-utils.test.ts @@ -30,5 +30,37 @@ describe('TimeUtils', () => { const result = formatTime(time, TimePattern.HH_MM_SS); expect(result).toBe('00:59:59'); }); + + it('should handle hours overflow correctly', () => { + const time = 7261000; // 2 hours, 1 minute, 1 second + const result = formatTime(time, TimePattern.HH_MM_SS); + expect(result).toBe('02:01:01'); + }); + + it('should handle milliseconds precision in MM_SS_MS pattern', () => { + const time = 1001; // 1 second, 1 millisecond + const result = formatTime(time, TimePattern.MM_SS_MS); + expect(result).toBe('00:01.001'); + }); + + it('should pad single digit values correctly', () => { + const time = 9009; // 9 seconds, 9 milliseconds + const result = formatTime(time, TimePattern.MM_SS_MS); + expect(result).toBe('00:09.009'); + }); + + it('should handle very large hour values', () => { + const time = 36061000; // 10 hours, 1 minute, 1 second + const result = formatTime(time, TimePattern.HH_MM_SS); + expect(result).toBe('10:01:01'); + }); + }); + + describe('TimePattern constants', () => { + it('should have correct TimePattern values', () => { + expect(TimePattern.HH_MM_SS).toBe('HH:MM:SS'); + expect(TimePattern.MM_SS).toBe('MM:SS'); + expect(TimePattern.MM_SS_MS).toBe('MM:SS.MS'); + }); }); }); diff --git a/src/__tests__/token.test.ts b/src/__tests__/token.test.ts index 6fcca0a..b0d94c0 100644 --- a/src/__tests__/token.test.ts +++ b/src/__tests__/token.test.ts @@ -24,5 +24,35 @@ describe('TokenUtils', () => { expect(ids.size).toBe(10); }); + + it('should generate IDs consistently across multiple test runs', () => { + const firstBatch = [getUniqueId(), getUniqueId(), getUniqueId()]; + const secondBatch = [getUniqueId(), getUniqueId(), getUniqueId()]; + + // Should always be incrementally increasing + expect(secondBatch[0]).toBe(firstBatch[2] + 1); + expect(secondBatch[1]).toBe(firstBatch[2] + 2); + expect(secondBatch[2]).toBe(firstBatch[2] + 3); + }); + + it('should handle rapid successive calls', () => { + const rapidIds = []; + for (let i = 0; i < 100; i++) { + rapidIds.push(getUniqueId()); + } + + // Check that all IDs are unique and sequential + for (let i = 1; i < rapidIds.length; i++) { + expect(rapidIds[i]).toBe(rapidIds[i - 1] + 1); + } + }); + + it('should return positive integer values', () => { + for (let i = 0; i < 5; i++) { + const id = getUniqueId(); + expect(Number.isInteger(id)).toBe(true); + expect(id).toBeGreaterThan(0); + } + }); }); }); diff --git a/src/__tests__/vector3-utils.test.ts b/src/__tests__/vector3-utils.test.ts new file mode 100644 index 0000000..b5e9c6e --- /dev/null +++ b/src/__tests__/vector3-utils.test.ts @@ -0,0 +1,88 @@ +import { absVector3 } from '../vector3-utils.js'; +import * as THREE from 'three'; + +describe('Vector3Utils', () => { + describe('absVector3', () => { + it('should convert all negative values to positive', () => { + const vector = new THREE.Vector3(-5, -10, -15); + + const result = absVector3(vector); + + expect(result.x).toBe(5); + expect(result.y).toBe(10); + expect(result.z).toBe(15); + }); + + it('should keep positive values unchanged', () => { + const vector = new THREE.Vector3(3, 7, 12); + + const result = absVector3(vector); + + expect(result.x).toBe(3); + expect(result.y).toBe(7); + expect(result.z).toBe(12); + }); + + it('should handle mixed positive and negative values', () => { + const vector = new THREE.Vector3(-8, 4, -2); + + const result = absVector3(vector); + + expect(result.x).toBe(8); + expect(result.y).toBe(4); + expect(result.z).toBe(2); + }); + + it('should handle zero values', () => { + const vector = new THREE.Vector3(0, -0, 0); + + const result = absVector3(vector); + + expect(result.x).toBe(0); + expect(result.y).toBe(0); + expect(result.z).toBe(0); + }); + + it('should modify the original vector (mutating function)', () => { + const vector = new THREE.Vector3(-3, -6, -9); + const originalVector = vector; + + const result = absVector3(vector); + + expect(result).toBe(originalVector); // Should return the same instance + expect(vector.x).toBe(3); + expect(vector.y).toBe(6); + expect(vector.z).toBe(9); + }); + + it('should handle floating point values', () => { + const vector = new THREE.Vector3(-1.5, 2.7, -3.14159); + + const result = absVector3(vector); + + expect(result.x).toBe(1.5); + expect(result.y).toBe(2.7); + expect(result.z).toBe(3.14159); + }); + + it('should handle very small negative values', () => { + const vector = new THREE.Vector3(-0.001, -0.0001, -0.00001); + + const result = absVector3(vector); + + expect(result.x).toBe(0.001); + expect(result.y).toBe(0.0001); + expect(result.z).toBe(0.00001); + }); + + it('should handle very large values', () => { + const vector = new THREE.Vector3(-1000000, 999999, -123456.789); + + const result = absVector3(vector); + + expect(result.x).toBe(1000000); + expect(result.y).toBe(999999); + expect(result.z).toBe(123456.789); + }); + }); +}); \ No newline at end of file From a38231b899f4eeb8c881d6a9f7248bab4e06755e Mon Sep 17 00:00:00 2001 From: Krisztian Somoracz Date: Thu, 16 Oct 2025 22:18:25 +0200 Subject: [PATCH 20/20] style: improve test file formatting and import consistency --- src/__tests__/callback-utils.test.ts | 394 ++++++++++----------- src/__tests__/dispose-utils.test.ts | 362 +++++++++---------- src/__tests__/geom-utils.test.ts | 240 ++++++------- src/__tests__/object-utils.test.ts | 505 ++++++++++++++------------- src/__tests__/vector3-utils.test.ts | 122 +++---- 5 files changed, 814 insertions(+), 809 deletions(-) diff --git a/src/__tests__/callback-utils.test.ts b/src/__tests__/callback-utils.test.ts index 95c8647..41815bc 100644 --- a/src/__tests__/callback-utils.test.ts +++ b/src/__tests__/callback-utils.test.ts @@ -1,211 +1,211 @@ import { - callWithReducer, - clearCallReducerData, - clearAllCallReducerData, - CallLimits + callWithReducer, + clearCallReducerData, + clearAllCallReducerData, + CallLimits, } from '../callback-utils.js'; describe('CallbackUtils', () => { + beforeEach(() => { + clearAllCallReducerData(); + jest.clearAllMocks(); + }); + + describe('CallLimits', () => { + it('should have correct constant values', () => { + expect(CallLimits.NO_LIMIT).toBe(-1); + expect(CallLimits.CALL_1_PER_SECONDS).toBe(1000); + expect(CallLimits.CALL_15_PER_SECONDS).toBe(1000 / 15); + expect(CallLimits.CALL_30_PER_SECONDS).toBe(1000 / 30); + expect(CallLimits.CALL_45_PER_SECONDS).toBe(1000 / 45); + expect(CallLimits.CALL_60_PER_SECONDS).toBe(1000 / 60); + expect(CallLimits.CALL_120_PER_SECONDS).toBe(1000 / 120); + }); + }); + + describe('callWithReducer', () => { + const mockCallback = jest.fn(); + beforeEach(() => { - clearAllCallReducerData(); - jest.clearAllMocks(); + mockCallback.mockClear(); }); - describe('CallLimits', () => { - it('should have correct constant values', () => { - expect(CallLimits.NO_LIMIT).toBe(-1); - expect(CallLimits.CALL_1_PER_SECONDS).toBe(1000); - expect(CallLimits.CALL_15_PER_SECONDS).toBe(1000 / 15); - expect(CallLimits.CALL_30_PER_SECONDS).toBe(1000 / 30); - expect(CallLimits.CALL_45_PER_SECONDS).toBe(1000 / 45); - expect(CallLimits.CALL_60_PER_SECONDS).toBe(1000 / 60); - expect(CallLimits.CALL_120_PER_SECONDS).toBe(1000 / 120); - }); + it('should not call callback when elapsed is 0 or falsy', () => { + callWithReducer({ + id: 'test', + callback: mockCallback, + callLimit: CallLimits.CALL_30_PER_SECONDS, + elapsed: 0, + }); + + expect(mockCallback).not.toHaveBeenCalled(); }); - describe('callWithReducer', () => { - const mockCallback = jest.fn(); - - beforeEach(() => { - mockCallback.mockClear(); - }); - - it('should not call callback when elapsed is 0 or falsy', () => { - callWithReducer({ - id: 'test', - callback: mockCallback, - callLimit: CallLimits.CALL_30_PER_SECONDS, - elapsed: 0, - }); - - expect(mockCallback).not.toHaveBeenCalled(); - }); - - it('should call callback immediately with NO_LIMIT', () => { - callWithReducer({ - id: 'test', - callback: mockCallback, - callLimit: CallLimits.NO_LIMIT, - elapsed: 100, - }); - - expect(mockCallback).toHaveBeenCalledTimes(1); - }); - - it('should call callback with parameter when provided', () => { - const param = { test: 'data' }; - - callWithReducer({ - id: 'test', - callback: mockCallback, - callLimit: CallLimits.NO_LIMIT, - elapsed: 100, - callbackParam: param, - }); - - expect(mockCallback).toHaveBeenCalledWith(param); - }); - - it('should respect call limit timing', () => { - const callLimit = 100; // 100ms limit - - // First call should work (elapsed > 0 is required) - callWithReducer({ - id: 'test', - callback: mockCallback, - callLimit, - elapsed: 50, - }); - expect(mockCallback).toHaveBeenCalledTimes(1); - - // Second call within limit should not trigger - callWithReducer({ - id: 'test', - callback: mockCallback, - callLimit, - elapsed: 100, - }); - expect(mockCallback).toHaveBeenCalledTimes(1); - - // Third call after limit should trigger - callWithReducer({ - id: 'test', - callback: mockCallback, - callLimit, - elapsed: 200, - }); - expect(mockCallback).toHaveBeenCalledTimes(2); - }); - - it('should handle forceCallCount correctly', () => { - const callLimit = 0.1; // 0.1s limit (100ms in seconds) - - callWithReducer({ - id: 'test', - callback: mockCallback, - callLimit, - elapsed: 250, - forceCallCount: true, - }); - - // Should call multiple times based on elapsed time (250ms / 100ms = 2+ calls) - expect(mockCallback).toHaveBeenCalledTimes(2); - }); - - it('should handle multiple different IDs independently', () => { - const mockCallback1 = jest.fn(); - const mockCallback2 = jest.fn(); - const callLimit = 100; - - callWithReducer({ - id: 'test1', - callback: mockCallback1, - callLimit, - elapsed: 50, - }); - - callWithReducer({ - id: 'test2', - callback: mockCallback2, - callLimit, - elapsed: 50, - }); - - expect(mockCallback1).toHaveBeenCalledTimes(1); - expect(mockCallback2).toHaveBeenCalledTimes(1); - }); + it('should call callback immediately with NO_LIMIT', () => { + callWithReducer({ + id: 'test', + callback: mockCallback, + callLimit: CallLimits.NO_LIMIT, + elapsed: 100, + }); + + expect(mockCallback).toHaveBeenCalledTimes(1); + }); + + it('should call callback with parameter when provided', () => { + const param = { test: 'data' }; + + callWithReducer({ + id: 'test', + callback: mockCallback, + callLimit: CallLimits.NO_LIMIT, + elapsed: 100, + callbackParam: param, + }); + + expect(mockCallback).toHaveBeenCalledWith(param); }); - describe('clearCallReducerData', () => { - it('should clear data for specific ID', () => { - const mockCallback = jest.fn(); - - // Set up some call data - callWithReducer({ - id: 'test', - callback: mockCallback, - callLimit: 100, - elapsed: 50, - }); - - const result = clearCallReducerData('test'); - expect(result).toBe(true); - - // Next call should behave as if it's the first call - callWithReducer({ - id: 'test', - callback: mockCallback, - callLimit: 100, - elapsed: 100, - }); - expect(mockCallback).toHaveBeenCalledTimes(2); - }); - - it('should return true when deleting non-existent ID (JavaScript delete behavior)', () => { - const result = clearCallReducerData('non-existent'); - expect(result).toBe(true); - }); + it('should respect call limit timing', () => { + const callLimit = 100; // 100ms limit + + // First call should work (elapsed > 0 is required) + callWithReducer({ + id: 'test', + callback: mockCallback, + callLimit, + elapsed: 50, + }); + expect(mockCallback).toHaveBeenCalledTimes(1); + + // Second call within limit should not trigger + callWithReducer({ + id: 'test', + callback: mockCallback, + callLimit, + elapsed: 100, + }); + expect(mockCallback).toHaveBeenCalledTimes(1); + + // Third call after limit should trigger + callWithReducer({ + id: 'test', + callback: mockCallback, + callLimit, + elapsed: 200, + }); + expect(mockCallback).toHaveBeenCalledTimes(2); }); - describe('clearAllCallReducerData', () => { - it('should clear all call data', () => { - const mockCallback1 = jest.fn(); - const mockCallback2 = jest.fn(); - - // Set up call data for multiple IDs - callWithReducer({ - id: 'test1', - callback: mockCallback1, - callLimit: 100, - elapsed: 50, - }); - - callWithReducer({ - id: 'test2', - callback: mockCallback2, - callLimit: 100, - elapsed: 50, - }); - - clearAllCallReducerData(); - - // Both should behave as first calls - callWithReducer({ - id: 'test1', - callback: mockCallback1, - callLimit: 100, - elapsed: 100, - }); - - callWithReducer({ - id: 'test2', - callback: mockCallback2, - callLimit: 100, - elapsed: 100, - }); - - expect(mockCallback1).toHaveBeenCalledTimes(2); - expect(mockCallback2).toHaveBeenCalledTimes(2); - }); + it('should handle forceCallCount correctly', () => { + const callLimit = 0.1; // 0.1s limit (100ms in seconds) + + callWithReducer({ + id: 'test', + callback: mockCallback, + callLimit, + elapsed: 250, + forceCallCount: true, + }); + + // Should call multiple times based on elapsed time (250ms / 100ms = 2+ calls) + expect(mockCallback).toHaveBeenCalledTimes(2); + }); + + it('should handle multiple different IDs independently', () => { + const mockCallback1 = jest.fn(); + const mockCallback2 = jest.fn(); + const callLimit = 100; + + callWithReducer({ + id: 'test1', + callback: mockCallback1, + callLimit, + elapsed: 50, + }); + + callWithReducer({ + id: 'test2', + callback: mockCallback2, + callLimit, + elapsed: 50, + }); + + expect(mockCallback1).toHaveBeenCalledTimes(1); + expect(mockCallback2).toHaveBeenCalledTimes(1); + }); + }); + + describe('clearCallReducerData', () => { + it('should clear data for specific ID', () => { + const mockCallback = jest.fn(); + + // Set up some call data + callWithReducer({ + id: 'test', + callback: mockCallback, + callLimit: 100, + elapsed: 50, + }); + + const result = clearCallReducerData('test'); + expect(result).toBe(true); + + // Next call should behave as if it's the first call + callWithReducer({ + id: 'test', + callback: mockCallback, + callLimit: 100, + elapsed: 100, + }); + expect(mockCallback).toHaveBeenCalledTimes(2); + }); + + it('should return true when deleting non-existent ID (JavaScript delete behavior)', () => { + const result = clearCallReducerData('non-existent'); + expect(result).toBe(true); + }); + }); + + describe('clearAllCallReducerData', () => { + it('should clear all call data', () => { + const mockCallback1 = jest.fn(); + const mockCallback2 = jest.fn(); + + // Set up call data for multiple IDs + callWithReducer({ + id: 'test1', + callback: mockCallback1, + callLimit: 100, + elapsed: 50, + }); + + callWithReducer({ + id: 'test2', + callback: mockCallback2, + callLimit: 100, + elapsed: 50, + }); + + clearAllCallReducerData(); + + // Both should behave as first calls + callWithReducer({ + id: 'test1', + callback: mockCallback1, + callLimit: 100, + elapsed: 100, + }); + + callWithReducer({ + id: 'test2', + callback: mockCallback2, + callLimit: 100, + elapsed: 100, + }); + + expect(mockCallback1).toHaveBeenCalledTimes(2); + expect(mockCallback2).toHaveBeenCalledTimes(2); }); -}); \ No newline at end of file + }); +}); diff --git a/src/__tests__/dispose-utils.test.ts b/src/__tests__/dispose-utils.test.ts index 7d88d96..a4e4176 100644 --- a/src/__tests__/dispose-utils.test.ts +++ b/src/__tests__/dispose-utils.test.ts @@ -2,212 +2,212 @@ import { disposeMaterials, deepDispose } from '../dispose-utils.js'; // Mock Three.js objects with proper type casting const createMockMaterial = (hasMap = false): any => ({ - isMaterial: true, - map: hasMap ? { dispose: jest.fn() } : null, - dispose: jest.fn(), + isMaterial: true, + map: hasMap ? { dispose: jest.fn() } : null, + dispose: jest.fn(), }); const createMockGeometry = (): any => ({ - dispose: jest.fn(), + dispose: jest.fn(), }); const createMockMesh = (hasMaterial = true, hasGeometry = true): any => ({ - isMesh: true, - material: hasMaterial ? createMockMaterial() : null, - geometry: hasGeometry ? createMockGeometry() : null, - parent: { - remove: jest.fn(), - }, + isMesh: true, + material: hasMaterial ? createMockMaterial() : null, + geometry: hasGeometry ? createMockGeometry() : null, + parent: { + remove: jest.fn(), + }, }); const createMockObject3D = (children: any[] = []): any => ({ - children, - parent: { - remove: jest.fn(), - }, + children, + parent: { + remove: jest.fn(), + }, }); describe('DisposeUtils', () => { - beforeEach(() => { - jest.clearAllMocks(); + beforeEach(() => { + jest.clearAllMocks(); + }); + + describe('disposeMaterials', () => { + it('should dispose single material without map', () => { + const material = createMockMaterial(); + + disposeMaterials(material as any); + + expect(material.dispose).toHaveBeenCalledTimes(1); }); - describe('disposeMaterials', () => { - it('should dispose single material without map', () => { - const material = createMockMaterial(); + it('should dispose single material with map', () => { + const material = createMockMaterial(true); + const mapDisposeSpy = material.map!.dispose; + + disposeMaterials(material as any); - disposeMaterials(material as any); + expect(mapDisposeSpy).toHaveBeenCalledTimes(1); + expect(material.map).toBeNull(); + expect(material.dispose).toHaveBeenCalledTimes(1); + }); - expect(material.dispose).toHaveBeenCalledTimes(1); - }); + it('should dispose array of materials', () => { + const material1 = createMockMaterial(); + const material2 = createMockMaterial(true); + const material2MapDispose = material2.map!.dispose; + const materials = [material1, material2]; - it('should dispose single material with map', () => { - const material = createMockMaterial(true); - const mapDisposeSpy = material.map!.dispose; + disposeMaterials(materials as any); - disposeMaterials(material as any); + expect(material1.dispose).toHaveBeenCalledTimes(1); + expect(material2MapDispose).toHaveBeenCalledTimes(1); + expect(material2.dispose).toHaveBeenCalledTimes(1); + expect(material2.map).toBeNull(); + }); - expect(mapDisposeSpy).toHaveBeenCalledTimes(1); - expect(material.map).toBeNull(); - expect(material.dispose).toHaveBeenCalledTimes(1); - }); + it('should handle nested arrays of materials', () => { + const material1 = createMockMaterial(); + const material2 = createMockMaterial(true); + const material2MapDispose = material2.map!.dispose; + const nestedMaterials = [[material1], [material2]]; - it('should dispose array of materials', () => { - const material1 = createMockMaterial(); - const material2 = createMockMaterial(true); - const material2MapDispose = material2.map!.dispose; - const materials = [material1, material2]; + disposeMaterials(nestedMaterials as any); - disposeMaterials(materials as any); + expect(material1.dispose).toHaveBeenCalledTimes(1); + expect(material2MapDispose).toHaveBeenCalledTimes(1); + expect(material2.dispose).toHaveBeenCalledTimes(1); + }); + }); - expect(material1.dispose).toHaveBeenCalledTimes(1); - expect(material2MapDispose).toHaveBeenCalledTimes(1); - expect(material2.dispose).toHaveBeenCalledTimes(1); - expect(material2.map).toBeNull(); - }); + describe('deepDispose', () => { + it('should dispose mesh with material and geometry', () => { + const mesh = createMockMesh(); + const materialDispose = mesh.material!.dispose; + const geometryDispose = mesh.geometry!.dispose; - it('should handle nested arrays of materials', () => { - const material1 = createMockMaterial(); - const material2 = createMockMaterial(true); - const material2MapDispose = material2.map!.dispose; - const nestedMaterials = [[material1], [material2]]; + deepDispose(mesh as any); - disposeMaterials(nestedMaterials as any); + expect(materialDispose).toHaveBeenCalledTimes(1); + expect(geometryDispose).toHaveBeenCalledTimes(1); + expect(mesh.material).toBeNull(); + expect(mesh.geometry).toBeNull(); + expect(mesh.parent.remove).toHaveBeenCalledWith(mesh); + }); - expect(material1.dispose).toHaveBeenCalledTimes(1); - expect(material2MapDispose).toHaveBeenCalledTimes(1); - expect(material2.dispose).toHaveBeenCalledTimes(1); - }); + it('should dispose mesh with material that has map', () => { + const mesh = { + isMesh: true, + material: createMockMaterial(true), + geometry: createMockGeometry(), + parent: { + remove: jest.fn(), + }, + }; + const materialMapDispose = mesh.material.map!.dispose; + const materialDispose = mesh.material.dispose; + const geometryDispose = mesh.geometry.dispose; + + deepDispose(mesh as any); + + expect(materialMapDispose).toHaveBeenCalledTimes(1); + expect(materialDispose).toHaveBeenCalledTimes(1); + expect(geometryDispose).toHaveBeenCalledTimes(1); + expect(mesh.parent.remove).toHaveBeenCalledWith(mesh); }); - describe('deepDispose', () => { - it('should dispose mesh with material and geometry', () => { - const mesh = createMockMesh(); - const materialDispose = mesh.material!.dispose; - const geometryDispose = mesh.geometry!.dispose; - - deepDispose(mesh as any); - - expect(materialDispose).toHaveBeenCalledTimes(1); - expect(geometryDispose).toHaveBeenCalledTimes(1); - expect(mesh.material).toBeNull(); - expect(mesh.geometry).toBeNull(); - expect(mesh.parent.remove).toHaveBeenCalledWith(mesh); - }); - - it('should dispose mesh with material that has map', () => { - const mesh = { - isMesh: true, - material: createMockMaterial(true), - geometry: createMockGeometry(), - parent: { - remove: jest.fn(), - }, - }; - const materialMapDispose = mesh.material.map!.dispose; - const materialDispose = mesh.material.dispose; - const geometryDispose = mesh.geometry.dispose; - - deepDispose(mesh as any); - - expect(materialMapDispose).toHaveBeenCalledTimes(1); - expect(materialDispose).toHaveBeenCalledTimes(1); - expect(geometryDispose).toHaveBeenCalledTimes(1); - expect(mesh.parent.remove).toHaveBeenCalledWith(mesh); - }); - - it('should dispose mesh with array of materials', () => { - const material1 = createMockMaterial(); - const material2 = createMockMaterial(true); - const material2MapDispose = material2.map!.dispose; - const mesh = { - isMesh: true, - material: [material1, material2], - geometry: createMockGeometry(), - parent: { - remove: jest.fn(), - }, - }; - const geometryDispose = mesh.geometry.dispose; - - deepDispose(mesh as any); - - expect(material1.dispose).toHaveBeenCalledTimes(1); - expect(material2MapDispose).toHaveBeenCalledTimes(1); - expect(material2.dispose).toHaveBeenCalledTimes(1); - expect(geometryDispose).toHaveBeenCalledTimes(1); - expect(mesh.parent.remove).toHaveBeenCalledWith(mesh); - }); - - it('should handle mesh without material', () => { - const mesh = createMockMesh(false, true); - const geometryDispose = mesh.geometry!.dispose; - - deepDispose(mesh as any); - - expect(geometryDispose).toHaveBeenCalledTimes(1); - expect(mesh.parent.remove).toHaveBeenCalledWith(mesh); - }); - - it('should handle mesh without geometry', () => { - const mesh = createMockMesh(true, false); - const materialDispose = mesh.material!.dispose; - - deepDispose(mesh as any); - - expect(materialDispose).toHaveBeenCalledTimes(1); - expect(mesh.parent.remove).toHaveBeenCalledWith(mesh); - }); - - it('should recursively dispose children in Object3D', () => { - const childMesh1 = createMockMesh(); - const childMesh2 = createMockMesh(); - const child1MaterialDispose = childMesh1.material!.dispose; - const child1GeometryDispose = childMesh1.geometry!.dispose; - const child2MaterialDispose = childMesh2.material!.dispose; - const child2GeometryDispose = childMesh2.geometry!.dispose; - const container = createMockObject3D([childMesh1, childMesh2]); - - deepDispose(container as any); - - expect(child1MaterialDispose).toHaveBeenCalledTimes(1); - expect(child1GeometryDispose).toHaveBeenCalledTimes(1); - expect(child2MaterialDispose).toHaveBeenCalledTimes(1); - expect(child2GeometryDispose).toHaveBeenCalledTimes(1); - expect(container.parent.remove).toHaveBeenCalledWith(container); - }); - - it('should handle nested container hierarchy', () => { - const mesh = createMockMesh(); - const materialDispose = mesh.material!.dispose; - const geometryDispose = mesh.geometry!.dispose; - const subContainer = createMockObject3D([mesh]); - const mainContainer = createMockObject3D([subContainer]); - - deepDispose(mainContainer as any); - - expect(materialDispose).toHaveBeenCalledTimes(1); - expect(geometryDispose).toHaveBeenCalledTimes(1); - expect(subContainer.parent.remove).toHaveBeenCalledWith(subContainer); - expect(mainContainer.parent.remove).toHaveBeenCalledWith(mainContainer); - }); - - it('should handle container without parent', () => { - const mesh = createMockMesh(); - const materialDispose = mesh.material!.dispose; - const geometryDispose = mesh.geometry!.dispose; - mesh.parent = null; - - expect(() => deepDispose(mesh as any)).not.toThrow(); - expect(materialDispose).toHaveBeenCalledTimes(1); - expect(geometryDispose).toHaveBeenCalledTimes(1); - }); - - it('should handle empty container', () => { - const container = createMockObject3D([]); - - expect(() => deepDispose(container as any)).not.toThrow(); - expect(container.parent.remove).toHaveBeenCalledWith(container); - }); + it('should dispose mesh with array of materials', () => { + const material1 = createMockMaterial(); + const material2 = createMockMaterial(true); + const material2MapDispose = material2.map!.dispose; + const mesh = { + isMesh: true, + material: [material1, material2], + geometry: createMockGeometry(), + parent: { + remove: jest.fn(), + }, + }; + const geometryDispose = mesh.geometry.dispose; + + deepDispose(mesh as any); + + expect(material1.dispose).toHaveBeenCalledTimes(1); + expect(material2MapDispose).toHaveBeenCalledTimes(1); + expect(material2.dispose).toHaveBeenCalledTimes(1); + expect(geometryDispose).toHaveBeenCalledTimes(1); + expect(mesh.parent.remove).toHaveBeenCalledWith(mesh); }); -}); \ No newline at end of file + + it('should handle mesh without material', () => { + const mesh = createMockMesh(false, true); + const geometryDispose = mesh.geometry!.dispose; + + deepDispose(mesh as any); + + expect(geometryDispose).toHaveBeenCalledTimes(1); + expect(mesh.parent.remove).toHaveBeenCalledWith(mesh); + }); + + it('should handle mesh without geometry', () => { + const mesh = createMockMesh(true, false); + const materialDispose = mesh.material!.dispose; + + deepDispose(mesh as any); + + expect(materialDispose).toHaveBeenCalledTimes(1); + expect(mesh.parent.remove).toHaveBeenCalledWith(mesh); + }); + + it('should recursively dispose children in Object3D', () => { + const childMesh1 = createMockMesh(); + const childMesh2 = createMockMesh(); + const child1MaterialDispose = childMesh1.material!.dispose; + const child1GeometryDispose = childMesh1.geometry!.dispose; + const child2MaterialDispose = childMesh2.material!.dispose; + const child2GeometryDispose = childMesh2.geometry!.dispose; + const container = createMockObject3D([childMesh1, childMesh2]); + + deepDispose(container as any); + + expect(child1MaterialDispose).toHaveBeenCalledTimes(1); + expect(child1GeometryDispose).toHaveBeenCalledTimes(1); + expect(child2MaterialDispose).toHaveBeenCalledTimes(1); + expect(child2GeometryDispose).toHaveBeenCalledTimes(1); + expect(container.parent.remove).toHaveBeenCalledWith(container); + }); + + it('should handle nested container hierarchy', () => { + const mesh = createMockMesh(); + const materialDispose = mesh.material!.dispose; + const geometryDispose = mesh.geometry!.dispose; + const subContainer = createMockObject3D([mesh]); + const mainContainer = createMockObject3D([subContainer]); + + deepDispose(mainContainer as any); + + expect(materialDispose).toHaveBeenCalledTimes(1); + expect(geometryDispose).toHaveBeenCalledTimes(1); + expect(subContainer.parent.remove).toHaveBeenCalledWith(subContainer); + expect(mainContainer.parent.remove).toHaveBeenCalledWith(mainContainer); + }); + + it('should handle container without parent', () => { + const mesh = createMockMesh(); + const materialDispose = mesh.material!.dispose; + const geometryDispose = mesh.geometry!.dispose; + mesh.parent = null; + + expect(() => deepDispose(mesh as any)).not.toThrow(); + expect(materialDispose).toHaveBeenCalledTimes(1); + expect(geometryDispose).toHaveBeenCalledTimes(1); + }); + + it('should handle empty container', () => { + const container = createMockObject3D([]); + + expect(() => deepDispose(container as any)).not.toThrow(); + expect(container.parent.remove).toHaveBeenCalledWith(container); + }); + }); +}); diff --git a/src/__tests__/geom-utils.test.ts b/src/__tests__/geom-utils.test.ts index 9bf628f..f4bbb64 100644 --- a/src/__tests__/geom-utils.test.ts +++ b/src/__tests__/geom-utils.test.ts @@ -1,172 +1,172 @@ -import { sign, isPointInATriangle, yFromTriangle } from '../geom-utils.js'; import * as THREE from 'three'; +import { sign, isPointInATriangle, yFromTriangle } from '../geom-utils.js'; describe('GeomUtils', () => { - describe('sign', () => { - it('should calculate positive sign for counter-clockwise points', () => { - const point1 = new THREE.Vector3(0, 0, 0); - const point2 = new THREE.Vector3(1, 0, 0); - const point3 = new THREE.Vector3(0, 0, 1); + describe('sign', () => { + it('should calculate positive sign for counter-clockwise points', () => { + const point1 = new THREE.Vector3(0, 0, 0); + const point2 = new THREE.Vector3(1, 0, 0); + const point3 = new THREE.Vector3(0, 0, 1); - const result = sign(point1, point2, point3); + const result = sign(point1, point2, point3); - expect(result).toBeGreaterThan(0); - }); + expect(result).toBeGreaterThan(0); + }); - it('should calculate negative sign for clockwise points', () => { - const point1 = new THREE.Vector3(0, 0, 0); - const point2 = new THREE.Vector3(0, 0, 1); - const point3 = new THREE.Vector3(1, 0, 0); + it('should calculate negative sign for clockwise points', () => { + const point1 = new THREE.Vector3(0, 0, 0); + const point2 = new THREE.Vector3(0, 0, 1); + const point3 = new THREE.Vector3(1, 0, 0); - const result = sign(point1, point2, point3); + const result = sign(point1, point2, point3); - expect(result).toBeLessThan(0); - }); + expect(result).toBeLessThan(0); + }); - it('should return zero for collinear points', () => { - const point1 = new THREE.Vector3(0, 0, 0); - const point2 = new THREE.Vector3(1, 0, 1); - const point3 = new THREE.Vector3(2, 0, 2); + it('should return zero for collinear points', () => { + const point1 = new THREE.Vector3(0, 0, 0); + const point2 = new THREE.Vector3(1, 0, 1); + const point3 = new THREE.Vector3(2, 0, 2); - const result = sign(point1, point2, point3); + const result = sign(point1, point2, point3); - expect(result).toBe(0); - }); + expect(result).toBe(0); + }); - it('should handle points with different y coordinates', () => { - const point1 = new THREE.Vector3(0, 5, 0); - const point2 = new THREE.Vector3(1, 10, 0); - const point3 = new THREE.Vector3(0, 15, 1); + it('should handle points with different y coordinates', () => { + const point1 = new THREE.Vector3(0, 5, 0); + const point2 = new THREE.Vector3(1, 10, 0); + const point3 = new THREE.Vector3(0, 15, 1); - const result = sign(point1, point2, point3); + const result = sign(point1, point2, point3); - expect(typeof result).toBe('number'); - expect(result).toBeGreaterThan(0); - }); + expect(typeof result).toBe('number'); + expect(result).toBeGreaterThan(0); }); + }); - describe('isPointInATriangle', () => { - it('should return true for point inside triangle', () => { - const point = new THREE.Vector3(0.5, 0, 0.25); - const triangleA = new THREE.Vector3(0, 0, 0); - const triangleB = new THREE.Vector3(1, 0, 0); - const triangleC = new THREE.Vector3(0.5, 0, 1); + describe('isPointInATriangle', () => { + it('should return true for point inside triangle', () => { + const point = new THREE.Vector3(0.5, 0, 0.25); + const triangleA = new THREE.Vector3(0, 0, 0); + const triangleB = new THREE.Vector3(1, 0, 0); + const triangleC = new THREE.Vector3(0.5, 0, 1); - const result = isPointInATriangle(point, triangleA, triangleB, triangleC); + const result = isPointInATriangle(point, triangleA, triangleB, triangleC); - expect(result).toBe(true); - }); + expect(result).toBe(true); + }); - it('should return false for point outside triangle', () => { - const point = new THREE.Vector3(2, 0, 2); - const triangleA = new THREE.Vector3(0, 0, 0); - const triangleB = new THREE.Vector3(1, 0, 0); - const triangleC = new THREE.Vector3(0.5, 0, 1); + it('should return false for point outside triangle', () => { + const point = new THREE.Vector3(2, 0, 2); + const triangleA = new THREE.Vector3(0, 0, 0); + const triangleB = new THREE.Vector3(1, 0, 0); + const triangleC = new THREE.Vector3(0.5, 0, 1); - const result = isPointInATriangle(point, triangleA, triangleB, triangleC); + const result = isPointInATriangle(point, triangleA, triangleB, triangleC); - expect(result).toBe(false); - }); + expect(result).toBe(false); + }); - it('should return true for point on triangle vertex', () => { - const point = new THREE.Vector3(0, 0, 0); - const triangleA = new THREE.Vector3(0, 0, 0); - const triangleB = new THREE.Vector3(1, 0, 0); - const triangleC = new THREE.Vector3(0.5, 0, 1); + it('should return true for point on triangle vertex', () => { + const point = new THREE.Vector3(0, 0, 0); + const triangleA = new THREE.Vector3(0, 0, 0); + const triangleB = new THREE.Vector3(1, 0, 0); + const triangleC = new THREE.Vector3(0.5, 0, 1); - const result = isPointInATriangle(point, triangleA, triangleB, triangleC); + const result = isPointInATriangle(point, triangleA, triangleB, triangleC); - expect(result).toBe(true); - }); + expect(result).toBe(true); + }); - it('should return true for point on triangle edge', () => { - const point = new THREE.Vector3(0.5, 0, 0); - const triangleA = new THREE.Vector3(0, 0, 0); - const triangleB = new THREE.Vector3(1, 0, 0); - const triangleC = new THREE.Vector3(0.5, 0, 1); + it('should return true for point on triangle edge', () => { + const point = new THREE.Vector3(0.5, 0, 0); + const triangleA = new THREE.Vector3(0, 0, 0); + const triangleB = new THREE.Vector3(1, 0, 0); + const triangleC = new THREE.Vector3(0.5, 0, 1); - const result = isPointInATriangle(point, triangleA, triangleB, triangleC); + const result = isPointInATriangle(point, triangleA, triangleB, triangleC); - expect(result).toBe(true); - }); + expect(result).toBe(true); + }); - it('should handle triangle with different orientations', () => { - const point = new THREE.Vector3(0.5, 0, 0.25); - const triangleA = new THREE.Vector3(1, 0, 0); - const triangleB = new THREE.Vector3(0, 0, 0); - const triangleC = new THREE.Vector3(0.5, 0, 1); + it('should handle triangle with different orientations', () => { + const point = new THREE.Vector3(0.5, 0, 0.25); + const triangleA = new THREE.Vector3(1, 0, 0); + const triangleB = new THREE.Vector3(0, 0, 0); + const triangleC = new THREE.Vector3(0.5, 0, 1); - const result = isPointInATriangle(point, triangleA, triangleB, triangleC); + const result = isPointInATriangle(point, triangleA, triangleB, triangleC); - expect(result).toBe(true); - }); + expect(result).toBe(true); }); + }); - describe('yFromTriangle', () => { - it('should calculate correct Y coordinate from triangle plane', () => { - // Create a simple triangle in XZ plane with known Y values - const triangleA = new THREE.Vector3(0, 0, 0); - const triangleB = new THREE.Vector3(2, 0, 0); - const triangleC = new THREE.Vector3(1, 2, 1); + describe('yFromTriangle', () => { + it('should calculate correct Y coordinate from triangle plane', () => { + // Create a simple triangle in XZ plane with known Y values + const triangleA = new THREE.Vector3(0, 0, 0); + const triangleB = new THREE.Vector3(2, 0, 0); + const triangleC = new THREE.Vector3(1, 2, 1); - // Point at the center should have Y value of 1 - const point = new THREE.Vector3(1, 0, 0.5); + // Point at the center should have Y value of 1 + const point = new THREE.Vector3(1, 0, 0.5); - const result = yFromTriangle(point, triangleA, triangleB, triangleC); + const result = yFromTriangle(point, triangleA, triangleB, triangleC); - expect(typeof result).toBe('number'); - expect(isFinite(result)).toBe(true); - }); + expect(typeof result).toBe('number'); + expect(isFinite(result)).toBe(true); + }); - it('should handle horizontal triangle (all Y coordinates same)', () => { - const triangleA = new THREE.Vector3(0, 5, 0); - const triangleB = new THREE.Vector3(1, 5, 0); - const triangleC = new THREE.Vector3(0.5, 5, 1); + it('should handle horizontal triangle (all Y coordinates same)', () => { + const triangleA = new THREE.Vector3(0, 5, 0); + const triangleB = new THREE.Vector3(1, 5, 0); + const triangleC = new THREE.Vector3(0.5, 5, 1); - const point = new THREE.Vector3(0.5, 0, 0.25); + const point = new THREE.Vector3(0.5, 0, 0.25); - const result = yFromTriangle(point, triangleA, triangleB, triangleC); + const result = yFromTriangle(point, triangleA, triangleB, triangleC); - expect(result).toBe(5); - }); + expect(result).toBe(5); + }); - it('should calculate Y for point at triangle vertex', () => { - const triangleA = new THREE.Vector3(0, 1, 0); - const triangleB = new THREE.Vector3(2, 3, 0); - const triangleC = new THREE.Vector3(1, 2, 2); + it('should calculate Y for point at triangle vertex', () => { + const triangleA = new THREE.Vector3(0, 1, 0); + const triangleB = new THREE.Vector3(2, 3, 0); + const triangleC = new THREE.Vector3(1, 2, 2); - // Point at vertex A should return Y coordinate of vertex A - const point = new THREE.Vector3(0, 0, 0); + // Point at vertex A should return Y coordinate of vertex A + const point = new THREE.Vector3(0, 0, 0); - const result = yFromTriangle(point, triangleA, triangleB, triangleC); + const result = yFromTriangle(point, triangleA, triangleB, triangleC); - expect(result).toBe(1); - }); + expect(result).toBe(1); + }); - it('should handle degenerate triangle (collinear points)', () => { - const triangleA = new THREE.Vector3(0, 0, 0); - const triangleB = new THREE.Vector3(1, 1, 0); - const triangleC = new THREE.Vector3(2, 2, 0); + it('should handle degenerate triangle (collinear points)', () => { + const triangleA = new THREE.Vector3(0, 0, 0); + const triangleB = new THREE.Vector3(1, 1, 0); + const triangleC = new THREE.Vector3(2, 2, 0); - const point = new THREE.Vector3(0.5, 0, 0); + const point = new THREE.Vector3(0.5, 0, 0); - const result = yFromTriangle(point, triangleA, triangleB, triangleC); + const result = yFromTriangle(point, triangleA, triangleB, triangleC); - // Should handle division by zero gracefully - expect(typeof result).toBe('number'); - }); + // Should handle division by zero gracefully + expect(typeof result).toBe('number'); + }); - it('should handle negative coordinates', () => { - const triangleA = new THREE.Vector3(-1, -1, -1); - const triangleB = new THREE.Vector3(1, -1, -1); - const triangleC = new THREE.Vector3(0, 1, 1); + it('should handle negative coordinates', () => { + const triangleA = new THREE.Vector3(-1, -1, -1); + const triangleB = new THREE.Vector3(1, -1, -1); + const triangleC = new THREE.Vector3(0, 1, 1); - const point = new THREE.Vector3(0, 0, 0); + const point = new THREE.Vector3(0, 0, 0); - const result = yFromTriangle(point, triangleA, triangleB, triangleC); + const result = yFromTriangle(point, triangleA, triangleB, triangleC); - expect(typeof result).toBe('number'); - expect(isFinite(result)).toBe(true); - }); + expect(typeof result).toBe('number'); + expect(isFinite(result)).toBe(true); }); -}); \ No newline at end of file + }); +}); diff --git a/src/__tests__/object-utils.test.ts b/src/__tests__/object-utils.test.ts index ca5916b..1838d78 100644 --- a/src/__tests__/object-utils.test.ts +++ b/src/__tests__/object-utils.test.ts @@ -1,277 +1,282 @@ -import { patchObject, deepMerge, getObjectDiff, ObjectOperationConfig } from '../object-utils.js'; +import { + patchObject, + deepMerge, + getObjectDiff, + ObjectOperationConfig, +} from '../object-utils.js'; describe('ObjectUtils', () => { - describe('patchObject', () => { - it('should patch simple object properties', () => { - const objectA = { a: 1, b: 2, c: 3 }; - const objectB = { b: 5, c: 6 }; - - const result = patchObject(objectA, objectB); - - expect(result).toEqual({ a: 1, b: 5, c: 6 }); - }); - - it('should handle zero and false values correctly', () => { - const objectA = { a: 1, b: true, c: 'test' }; - const objectB = { a: 0, b: false, c: null }; - - const result = patchObject(objectA, objectB); - - expect(result).toEqual({ a: 0, b: false, c: 'test' }); - }); - - it('should handle nested objects', () => { - const objectA = { - level1: { - a: 1, - b: 2, - level2: { - x: 10, - y: 20 - } - } - }; - const objectB = { - level1: { - b: 5, - level2: { - y: 25, - z: 30 - } - } - }; - - const result = patchObject(objectA, objectB); - - expect(result.level1.a).toBe(1); - expect(result.level1.b).toBe(5); - expect(result.level1.level2.x).toBe(10); - expect(result.level1.level2.y).toBe(25); - }); - - it('should skip properties when specified in config', () => { - const objectA = { a: 1, b: 2, c: 3 }; - const objectB = { a: 10, b: 20, c: 30 }; - const config: ObjectOperationConfig = { - skippedProperties: ['b'] - }; - - const result = patchObject(objectA, objectB, config); - - expect(result).toEqual({ a: 10, c: 30 }); - }); - - it('should apply to first object when specified in config', () => { - const objectA = { a: 1, b: 2, c: 3 }; - const objectB = { b: 5, c: 6 }; - const config: ObjectOperationConfig = { - applyToFirstObject: true - }; - - const result = patchObject(objectA, objectB, config); - - expect(result).toEqual({ a: 1, b: 5, c: 6 }); - expect(objectA).toEqual({ a: 1, b: 5, c: 6 }); // Should modify original - }); - - it('should handle arrays correctly (not merge them)', () => { - const objectA = { arr: [1, 2, 3], other: 'test' }; - const objectB = { arr: [4, 5], other: 'updated' }; - - const result = patchObject(objectA, objectB); - - expect(result.arr).toEqual([4, 5]); - expect(result.other).toBe('updated'); - }); + describe('patchObject', () => { + it('should patch simple object properties', () => { + const objectA = { a: 1, b: 2, c: 3 }; + const objectB = { b: 5, c: 6 }; + + const result = patchObject(objectA, objectB); + + expect(result).toEqual({ a: 1, b: 5, c: 6 }); + }); + + it('should handle zero and false values correctly', () => { + const objectA = { a: 1, b: true, c: 'test' }; + const objectB = { a: 0, b: false, c: null }; + + const result = patchObject(objectA, objectB); + + expect(result).toEqual({ a: 0, b: false, c: 'test' }); + }); + + it('should handle nested objects', () => { + const objectA = { + level1: { + a: 1, + b: 2, + level2: { + x: 10, + y: 20, + }, + }, + }; + const objectB = { + level1: { + b: 5, + level2: { + y: 25, + z: 30, + }, + }, + }; + + const result = patchObject(objectA, objectB); + + expect(result.level1.a).toBe(1); + expect(result.level1.b).toBe(5); + expect(result.level1.level2.x).toBe(10); + expect(result.level1.level2.y).toBe(25); + }); + + it('should skip properties when specified in config', () => { + const objectA = { a: 1, b: 2, c: 3 }; + const objectB = { a: 10, b: 20, c: 30 }; + const config: ObjectOperationConfig = { + skippedProperties: ['b'], + }; + + const result = patchObject(objectA, objectB, config); + + expect(result).toEqual({ a: 10, c: 30 }); + }); + + it('should apply to first object when specified in config', () => { + const objectA = { a: 1, b: 2, c: 3 }; + const objectB = { b: 5, c: 6 }; + const config: ObjectOperationConfig = { + applyToFirstObject: true, + }; + + const result = patchObject(objectA, objectB, config); + + expect(result).toEqual({ a: 1, b: 5, c: 6 }); + expect(objectA).toEqual({ a: 1, b: 5, c: 6 }); // Should modify original + }); + + it('should handle arrays correctly (not merge them)', () => { + const objectA = { arr: [1, 2, 3], other: 'test' }; + const objectB = { arr: [4, 5], other: 'updated' }; + + const result = patchObject(objectA, objectB); + + expect(result.arr).toEqual([4, 5]); + expect(result.other).toBe('updated'); + }); + }); + + describe('deepMerge', () => { + it('should merge simple objects', () => { + const objectA = { a: 1, b: 2 }; + const objectB = { c: 3, d: 4 }; + + const result = deepMerge(objectA, objectB); + + expect(result).toEqual({ a: 1, b: 2, c: 3, d: 4 }); + }); + + it('should handle overlapping properties', () => { + const objectA = { a: 1, b: 2, c: 3 }; + const objectB = { b: 20, c: 30, d: 40 }; + + const result = deepMerge(objectA, objectB); + + expect(result).toEqual({ a: 1, b: 20, c: 30, d: 40 }); + }); + + it('should handle zero and false values correctly', () => { + const objectA = { a: 1, b: true, c: 'test' }; + const objectB = { a: 0, b: false, c: 'test' }; + + const result = deepMerge(objectA, objectB) as any; + + expect(result.a).toBe(0); + expect(result.b).toBe(false); + expect(result.c).toBe('test'); + }); + + it('should handle nested objects', () => { + const objectA = { + level1: { + a: 1, + level2: { x: 10 }, + }, + }; + const objectB = { + level1: { + b: 2, + level2: { y: 20 }, + }, + }; + + const result = deepMerge(objectA, objectB) as any; + + expect(result.level1.a).toBe(1); + expect(result.level1.b).toBe(2); + expect(result.level1.level2.x).toBe(10); + expect(result.level1.level2.y).toBe(20); + }); + + it('should handle null/undefined objects', () => { + const objectA = { a: 1, b: 2 }; + const objectB = null; + + const result = deepMerge(objectA, objectB); + + expect(result).toEqual({ a: 1, b: 2 }); + }); + + it('should skip properties when specified in config', () => { + const objectA = { a: 1, b: 2 }; + const objectB = { b: 20, c: 3 }; + const config: ObjectOperationConfig = { + skippedProperties: ['b'], + }; + + const result = deepMerge(objectA, objectB, config); + + expect(result).toEqual({ a: 1, c: 3 }); }); - describe('deepMerge', () => { - it('should merge simple objects', () => { - const objectA = { a: 1, b: 2 }; - const objectB = { c: 3, d: 4 }; + it('should apply to first object when specified in config', () => { + const objectA = { a: 1, b: 2 }; + const objectB = { c: 3, d: 4 }; + const config: ObjectOperationConfig = { + applyToFirstObject: true, + }; - const result = deepMerge(objectA, objectB); + const result = deepMerge(objectA, objectB, config); - expect(result).toEqual({ a: 1, b: 2, c: 3, d: 4 }); - }); + expect(result).toEqual({ a: 1, b: 2, c: 3, d: 4 }); + expect(objectA).toEqual({ a: 1, b: 2, c: 3, d: 4 }); // Should modify original + }); + }); - it('should handle overlapping properties', () => { - const objectA = { a: 1, b: 2, c: 3 }; - const objectB = { b: 20, c: 30, d: 40 }; + describe('getObjectDiff', () => { + it('should return empty object when objects are identical', () => { + const objectA = { a: 1, b: 2, c: 3 }; + const objectB = { a: 1, b: 2, c: 3 }; - const result = deepMerge(objectA, objectB); + const result = getObjectDiff(objectA, objectB); - expect(result).toEqual({ a: 1, b: 20, c: 30, d: 40 }); - }); + expect(result).toEqual({}); + }); - it('should handle zero and false values correctly', () => { - const objectA = { a: 1, b: true, c: 'test' }; - const objectB = { a: 0, b: false, c: 'test' }; + it('should return differences between objects', () => { + const objectA = { a: 1, b: 2, c: 3 }; + const objectB = { a: 1, b: 20, c: 3 }; - const result = deepMerge(objectA, objectB) as any; + const result = getObjectDiff(objectA, objectB); - expect(result.a).toBe(0); - expect(result.b).toBe(false); - expect(result.c).toBe('test'); - }); + expect(result).toEqual({ b: 20 }); + }); - it('should handle nested objects', () => { - const objectA = { - level1: { - a: 1, - level2: { x: 10 } - } - }; - const objectB = { - level1: { - b: 2, - level2: { y: 20 } - } - }; + it('should handle zero values correctly', () => { + const objectA = { a: 1, b: 'original', c: 'test' }; + const objectB = { a: 0, b: 'changed', c: 'test' }; - const result = deepMerge(objectA, objectB) as any; + const result = getObjectDiff(objectA, objectB); - expect(result.level1.a).toBe(1); - expect(result.level1.b).toBe(2); - expect(result.level1.level2.x).toBe(10); - expect(result.level1.level2.y).toBe(20); - }); + expect(result).toEqual({ a: 0, b: 'changed' }); + }); - it('should handle null/undefined objects', () => { - const objectA = { a: 1, b: 2 }; - const objectB = null; + it('should handle false values (treated as falsy)', () => { + const objectA = { a: true, b: 'value' }; + const objectB = { a: false, b: 'value' }; - const result = deepMerge(objectA, objectB); + const result = getObjectDiff(objectA, objectB); - expect(result).toEqual({ a: 1, b: 2 }); - }); + // false is falsy, so it falls back to objectA value, no diff + expect(result).toEqual({}); + }); + + it('should handle nested objects', () => { + const objectA = { + level1: { + a: 1, + b: 2, + level2: { + x: 10, + y: 20, + }, + }, + }; + const objectB = { + level1: { + a: 1, + b: 5, + level2: { + x: 15, + y: 20, + }, + }, + }; + + const result = getObjectDiff(objectA, objectB); + + expect(result).toEqual({ + level1: { + b: 5, + level2: { + x: 15, + }, + }, + }); + }); - it('should skip properties when specified in config', () => { - const objectA = { a: 1, b: 2 }; - const objectB = { b: 20, c: 3 }; - const config: ObjectOperationConfig = { - skippedProperties: ['b'] - }; + it('should handle missing properties in objectB', () => { + const objectA = { a: 1, b: 2, c: 3 }; + const objectB = { a: 1, c: 30 }; - const result = deepMerge(objectA, objectB, config); + const result = getObjectDiff(objectA, objectB); - expect(result).toEqual({ a: 1, c: 3 }); - }); + expect(result).toEqual({ c: 30 }); + }); - it('should apply to first object when specified in config', () => { - const objectA = { a: 1, b: 2 }; - const objectB = { c: 3, d: 4 }; - const config: ObjectOperationConfig = { - applyToFirstObject: true - }; + it('should skip properties when specified in config', () => { + const objectA = { a: 1, b: 2, c: 3 }; + const objectB = { a: 10, b: 20, c: 30 }; + const config: ObjectOperationConfig = { + skippedProperties: ['b'], + }; - const result = deepMerge(objectA, objectB, config); + const result = getObjectDiff(objectA, objectB, config); - expect(result).toEqual({ a: 1, b: 2, c: 3, d: 4 }); - expect(objectA).toEqual({ a: 1, b: 2, c: 3, d: 4 }); // Should modify original - }); + expect(result).toEqual({ a: 10, c: 30 }); }); - describe('getObjectDiff', () => { - it('should return empty object when objects are identical', () => { - const objectA = { a: 1, b: 2, c: 3 }; - const objectB = { a: 1, b: 2, c: 3 }; - - const result = getObjectDiff(objectA, objectB); - - expect(result).toEqual({}); - }); - - it('should return differences between objects', () => { - const objectA = { a: 1, b: 2, c: 3 }; - const objectB = { a: 1, b: 20, c: 3 }; - - const result = getObjectDiff(objectA, objectB); - - expect(result).toEqual({ b: 20 }); - }); - - it('should handle zero values correctly', () => { - const objectA = { a: 1, b: 'original', c: 'test' }; - const objectB = { a: 0, b: 'changed', c: 'test' }; - - const result = getObjectDiff(objectA, objectB); - - expect(result).toEqual({ a: 0, b: 'changed' }); - }); - - it('should handle false values (treated as falsy)', () => { - const objectA = { a: true, b: 'value' }; - const objectB = { a: false, b: 'value' }; - - const result = getObjectDiff(objectA, objectB); - - // false is falsy, so it falls back to objectA value, no diff - expect(result).toEqual({}); - }); - - it('should handle nested objects', () => { - const objectA = { - level1: { - a: 1, - b: 2, - level2: { - x: 10, - y: 20 - } - } - }; - const objectB = { - level1: { - a: 1, - b: 5, - level2: { - x: 15, - y: 20 - } - } - }; - - const result = getObjectDiff(objectA, objectB); - - expect(result).toEqual({ - level1: { - b: 5, - level2: { - x: 15 - } - } - }); - }); - - it('should handle missing properties in objectB', () => { - const objectA = { a: 1, b: 2, c: 3 }; - const objectB = { a: 1, c: 30 }; - - const result = getObjectDiff(objectA, objectB); - - expect(result).toEqual({ c: 30 }); - }); - - it('should skip properties when specified in config', () => { - const objectA = { a: 1, b: 2, c: 3 }; - const objectB = { a: 10, b: 20, c: 30 }; - const config: ObjectOperationConfig = { - skippedProperties: ['b'] - }; - - const result = getObjectDiff(objectA, objectB, config); - - expect(result).toEqual({ a: 10, c: 30 }); - }); - - it('should handle arrays correctly', () => { - const objectA = { arr: [1, 2, 3], other: 'same' }; - const objectB = { arr: [4, 5], other: 'same' }; - - const result = getObjectDiff(objectA, objectB); - - expect(result).toEqual({ arr: [4, 5] }); - }); + it('should handle arrays correctly', () => { + const objectA = { arr: [1, 2, 3], other: 'same' }; + const objectB = { arr: [4, 5], other: 'same' }; + + const result = getObjectDiff(objectA, objectB); + + expect(result).toEqual({ arr: [4, 5] }); }); -}); \ No newline at end of file + }); +}); diff --git a/src/__tests__/vector3-utils.test.ts b/src/__tests__/vector3-utils.test.ts index b5e9c6e..818a891 100644 --- a/src/__tests__/vector3-utils.test.ts +++ b/src/__tests__/vector3-utils.test.ts @@ -1,88 +1,88 @@ -import { absVector3 } from '../vector3-utils.js'; import * as THREE from 'three'; +import { absVector3 } from '../vector3-utils.js'; describe('Vector3Utils', () => { - describe('absVector3', () => { - it('should convert all negative values to positive', () => { - const vector = new THREE.Vector3(-5, -10, -15); + describe('absVector3', () => { + it('should convert all negative values to positive', () => { + const vector = new THREE.Vector3(-5, -10, -15); - const result = absVector3(vector); + const result = absVector3(vector); - expect(result.x).toBe(5); - expect(result.y).toBe(10); - expect(result.z).toBe(15); - }); + expect(result.x).toBe(5); + expect(result.y).toBe(10); + expect(result.z).toBe(15); + }); - it('should keep positive values unchanged', () => { - const vector = new THREE.Vector3(3, 7, 12); + it('should keep positive values unchanged', () => { + const vector = new THREE.Vector3(3, 7, 12); - const result = absVector3(vector); + const result = absVector3(vector); - expect(result.x).toBe(3); - expect(result.y).toBe(7); - expect(result.z).toBe(12); - }); + expect(result.x).toBe(3); + expect(result.y).toBe(7); + expect(result.z).toBe(12); + }); - it('should handle mixed positive and negative values', () => { - const vector = new THREE.Vector3(-8, 4, -2); + it('should handle mixed positive and negative values', () => { + const vector = new THREE.Vector3(-8, 4, -2); - const result = absVector3(vector); + const result = absVector3(vector); - expect(result.x).toBe(8); - expect(result.y).toBe(4); - expect(result.z).toBe(2); - }); + expect(result.x).toBe(8); + expect(result.y).toBe(4); + expect(result.z).toBe(2); + }); - it('should handle zero values', () => { - const vector = new THREE.Vector3(0, -0, 0); + it('should handle zero values', () => { + const vector = new THREE.Vector3(0, -0, 0); - const result = absVector3(vector); + const result = absVector3(vector); - expect(result.x).toBe(0); - expect(result.y).toBe(0); - expect(result.z).toBe(0); - }); + expect(result.x).toBe(0); + expect(result.y).toBe(0); + expect(result.z).toBe(0); + }); - it('should modify the original vector (mutating function)', () => { - const vector = new THREE.Vector3(-3, -6, -9); - const originalVector = vector; + it('should modify the original vector (mutating function)', () => { + const vector = new THREE.Vector3(-3, -6, -9); + const originalVector = vector; - const result = absVector3(vector); + const result = absVector3(vector); - expect(result).toBe(originalVector); // Should return the same instance - expect(vector.x).toBe(3); - expect(vector.y).toBe(6); - expect(vector.z).toBe(9); - }); + expect(result).toBe(originalVector); // Should return the same instance + expect(vector.x).toBe(3); + expect(vector.y).toBe(6); + expect(vector.z).toBe(9); + }); - it('should handle floating point values', () => { - const vector = new THREE.Vector3(-1.5, 2.7, -3.14159); + it('should handle floating point values', () => { + const vector = new THREE.Vector3(-1.5, 2.7, -3.14159); - const result = absVector3(vector); + const result = absVector3(vector); - expect(result.x).toBe(1.5); - expect(result.y).toBe(2.7); - expect(result.z).toBe(3.14159); - }); + expect(result.x).toBe(1.5); + expect(result.y).toBe(2.7); + expect(result.z).toBe(3.14159); + }); - it('should handle very small negative values', () => { - const vector = new THREE.Vector3(-0.001, -0.0001, -0.00001); + it('should handle very small negative values', () => { + const vector = new THREE.Vector3(-0.001, -0.0001, -0.00001); - const result = absVector3(vector); + const result = absVector3(vector); - expect(result.x).toBe(0.001); - expect(result.y).toBe(0.0001); - expect(result.z).toBe(0.00001); - }); + expect(result.x).toBe(0.001); + expect(result.y).toBe(0.0001); + expect(result.z).toBe(0.00001); + }); - it('should handle very large values', () => { - const vector = new THREE.Vector3(-1000000, 999999, -123456.789); + it('should handle very large values', () => { + const vector = new THREE.Vector3(-1000000, 999999, -123456.789); - const result = absVector3(vector); + const result = absVector3(vector); - expect(result.x).toBe(1000000); - expect(result.y).toBe(999999); - expect(result.z).toBe(123456.789); - }); + expect(result.x).toBe(1000000); + expect(result.y).toBe(999999); + expect(result.z).toBe(123456.789); }); -}); \ No newline at end of file + }); +});