diff --git a/.gitignore b/.gitignore index 51eccfb..cf336f8 100644 --- a/.gitignore +++ b/.gitignore @@ -45,4 +45,5 @@ Thumbs.db /.angular/cache /src/assets/__pycache__ /src/assets/tests -.claude/settings.local.json +/.claude +/.angular \ No newline at end of file diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100644 index 0000000..2312dc5 --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1 @@ +npx lint-staged diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..d2328d3 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,5 @@ +dist/ +node_modules/ +.angular/ +coverage/ +package-lock.json diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..459d2ac --- /dev/null +++ b/.prettierrc @@ -0,0 +1,9 @@ +{ + "singleQuote": true, + "trailingComma": "es5", + "printWidth": 120, + "tabWidth": 2, + "semi": true, + "bracketSpacing": true, + "arrowParens": "avoid" +} diff --git a/angular.json b/angular.json index a96d3a5..e758743 100644 --- a/angular.json +++ b/angular.json @@ -15,7 +15,7 @@ "prefix": "app", "architect": { "build": { - "builder": "@angular-devkit/build-angular:application", + "builder": "@angular/build:application", "options": { "outputPath": "dist/glyphspace", "index": "src/index.html", @@ -65,7 +65,7 @@ "defaultConfiguration": "production" }, "serve": { - "builder": "@angular-devkit/build-angular:dev-server", + "builder": "@angular/build:dev-server", "configurations": { "production": { "buildTarget": "glyphspace:build:production" @@ -77,10 +77,10 @@ "defaultConfiguration": "development" }, "extract-i18n": { - "builder": "@angular-devkit/build-angular:extract-i18n" + "builder": "@angular/build:extract-i18n" }, "test": { - "builder": "@angular-devkit/build-angular:karma", + "builder": "@angular/build:karma", "options": { "polyfills": [ "zone.js", @@ -100,11 +100,49 @@ "scripts": [], "webWorkerTsConfig": "tsconfig.worker.json" } + }, + "lint": { + "builder": "@angular-eslint/builder:lint", + "options": { + "lintFilePatterns": [ + "src/**/*.ts", + "src/**/*.html" + ] + } } } } }, "cli": { - "analytics": false + "analytics": false, + "schematicCollections": [ + "angular-eslint" + ] + }, + "schematics": { + "@schematics/angular:component": { + "type": "component" + }, + "@schematics/angular:directive": { + "type": "directive" + }, + "@schematics/angular:service": { + "type": "service" + }, + "@schematics/angular:guard": { + "typeSeparator": "." + }, + "@schematics/angular:interceptor": { + "typeSeparator": "." + }, + "@schematics/angular:module": { + "typeSeparator": "." + }, + "@schematics/angular:pipe": { + "typeSeparator": "." + }, + "@schematics/angular:resolver": { + "typeSeparator": "." + } } -} \ No newline at end of file +} diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 0000000..8f0ad64 --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,60 @@ +// @ts-check +const eslint = require("@eslint/js"); +const { defineConfig } = require("eslint/config"); +const tseslint = require("typescript-eslint"); +const angular = require("angular-eslint"); +const prettierConfig = require("eslint-config-prettier"); + +module.exports = defineConfig([ + { + files: ["**/*.ts"], + extends: [ + eslint.configs.recommended, + tseslint.configs.recommended, + tseslint.configs.stylistic, + angular.configs.tsRecommended, + ], + processor: angular.processInlineTemplates, + rules: { + "@angular-eslint/directive-selector": [ + "error", + { + type: "attribute", + prefix: "app", + style: "camelCase", + }, + ], + "@angular-eslint/component-selector": [ + "error", + { + type: "element", + prefix: ["app", "glyph"], + style: "kebab-case", + }, + ], + "@typescript-eslint/no-explicit-any": "warn", + "@typescript-eslint/no-non-null-assertion": "warn", + "@typescript-eslint/no-unused-vars": ["warn", { argsIgnorePattern: "^_" }], + "@typescript-eslint/no-empty-function": "warn", + "@typescript-eslint/ban-ts-comment": "warn", + "@angular-eslint/prefer-inject": "off", + "@angular-eslint/no-empty-lifecycle-method": "warn", + "@angular-eslint/no-output-native": "warn", + "eqeqeq": ["warn", "smart"], + }, + }, + { + files: ["**/*.html"], + extends: [ + angular.configs.templateRecommended, + angular.configs.templateAccessibility, + ], + rules: { + "@angular-eslint/template/label-has-associated-control": "warn", + "@angular-eslint/template/eqeqeq": "warn", + "@angular-eslint/template/click-events-have-key-events": "warn", + "@angular-eslint/template/interactive-supports-focus": "warn", + }, + }, + prettierConfig, +]); diff --git a/package-lock.json b/package-lock.json index 1e21873..12f4818 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,20 +8,16 @@ "name": "glyphspace", "version": "0.0.0", "dependencies": { - "@angular/common": "^19.2.0", - "@angular/compiler": "^19.2.0", - "@angular/core": "^19.2.0", - "@angular/forms": "^19.2.0", - "@angular/platform-browser": "^19.2.0", - "@angular/platform-browser-dynamic": "^19.2.0", - "@angular/platform-server": "^19.2.0", - "@angular/router": "^19.2.0", + "@angular/common": "^21.1.4", + "@angular/compiler": "^21.1.4", + "@angular/core": "^21.1.4", + "@angular/forms": "^21.1.4", + "@angular/platform-browser": "^21.1.4", + "@angular/platform-browser-dynamic": "^21.1.4", "@saehrimnir/druidjs": "^0.7.3", "d3": "^7.9.0", "d3-force": "^3.0.0", - "express": "^4.18.2", "material-icons": "^1.13.14", - "parquet-wasm": "^0.7.1", "pyodide": "^0.28.0", "rxjs": "~7.8.0", "three": "^0.176.0", @@ -29,24 +25,238 @@ "zone.js": "~0.15.0" }, "devDependencies": { - "@angular-devkit/build-angular": "^19.2.13", - "@angular/cli": "^19.2.13", - "@angular/compiler-cli": "^19.2.0", + "@angular/build": "^21.1.4", + "@angular/cli": "^21.1.4", + "@angular/compiler-cli": "^21.1.4", "@types/d3": "^7.4.3", "@types/d3-force": "^3.0.10", "@types/d3-quadtree": "^3.0.6", - "@types/express": "^4.17.17", "@types/jasmine": "~5.1.0", "@types/node": "^18.18.0", "@types/three": "^0.176.0", - "@types/uuid": "^10.0.0", + "angular-eslint": "21.0.1", + "eslint": "^9.39.1", + "eslint-config-prettier": "^10.1.8", + "husky": "^9.1.7", "jasmine-core": "~5.6.0", "karma": "~6.4.0", "karma-chrome-launcher": "~3.2.0", "karma-coverage": "~2.2.0", "karma-jasmine": "~5.1.0", "karma-jasmine-html-reporter": "~2.1.0", - "typescript": "~5.7.2" + "lint-staged": "^16.2.7", + "prettier": "^3.8.1", + "typescript": "~5.9.3", + "typescript-eslint": "8.46.4" + } + }, + "node_modules/@algolia/abtesting": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@algolia/abtesting/-/abtesting-1.12.2.tgz", + "integrity": "sha512-oWknd6wpfNrmRcH0vzed3UPX0i17o4kYLM5OMITyMVM2xLgaRbIafoxL0e8mcrNNb0iORCJA0evnNDKRYth5WQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.46.2", + "@algolia/requester-browser-xhr": "5.46.2", + "@algolia/requester-fetch": "5.46.2", + "@algolia/requester-node-http": "5.46.2" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-abtesting": { + "version": "5.46.2", + "resolved": "https://registry.npmjs.org/@algolia/client-abtesting/-/client-abtesting-5.46.2.tgz", + "integrity": "sha512-oRSUHbylGIuxrlzdPA8FPJuwrLLRavOhAmFGgdAvMcX47XsyM+IOGa9tc7/K5SPvBqn4nhppOCEz7BrzOPWc4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.46.2", + "@algolia/requester-browser-xhr": "5.46.2", + "@algolia/requester-fetch": "5.46.2", + "@algolia/requester-node-http": "5.46.2" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-analytics": { + "version": "5.46.2", + "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-5.46.2.tgz", + "integrity": "sha512-EPBN2Oruw0maWOF4OgGPfioTvd+gmiNwx0HmD9IgmlS+l75DatcBkKOPNJN+0z3wBQWUO5oq602ATxIfmTQ8bA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.46.2", + "@algolia/requester-browser-xhr": "5.46.2", + "@algolia/requester-fetch": "5.46.2", + "@algolia/requester-node-http": "5.46.2" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-common": { + "version": "5.46.2", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.46.2.tgz", + "integrity": "sha512-Hj8gswSJNKZ0oyd0wWissqyasm+wTz1oIsv5ZmLarzOZAp3vFEda8bpDQ8PUhO+DfkbiLyVnAxsPe4cGzWtqkg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-insights": { + "version": "5.46.2", + "resolved": "https://registry.npmjs.org/@algolia/client-insights/-/client-insights-5.46.2.tgz", + "integrity": "sha512-6dBZko2jt8FmQcHCbmNLB0kCV079Mx/DJcySTL3wirgDBUH7xhY1pOuUTLMiGkqM5D8moVZTvTdRKZUJRkrwBA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.46.2", + "@algolia/requester-browser-xhr": "5.46.2", + "@algolia/requester-fetch": "5.46.2", + "@algolia/requester-node-http": "5.46.2" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-personalization": { + "version": "5.46.2", + "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-5.46.2.tgz", + "integrity": "sha512-1waE2Uqh/PHNeDXGn/PM/WrmYOBiUGSVxAWqiJIj73jqPqvfzZgzdakHscIVaDl6Cp+j5dwjsZ5LCgaUr6DtmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.46.2", + "@algolia/requester-browser-xhr": "5.46.2", + "@algolia/requester-fetch": "5.46.2", + "@algolia/requester-node-http": "5.46.2" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-query-suggestions": { + "version": "5.46.2", + "resolved": "https://registry.npmjs.org/@algolia/client-query-suggestions/-/client-query-suggestions-5.46.2.tgz", + "integrity": "sha512-EgOzTZkyDcNL6DV0V/24+oBJ+hKo0wNgyrOX/mePBM9bc9huHxIY2352sXmoZ648JXXY2x//V1kropF/Spx83w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.46.2", + "@algolia/requester-browser-xhr": "5.46.2", + "@algolia/requester-fetch": "5.46.2", + "@algolia/requester-node-http": "5.46.2" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-search": { + "version": "5.46.2", + "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.46.2.tgz", + "integrity": "sha512-ZsOJqu4HOG5BlvIFnMU0YKjQ9ZI6r3C31dg2jk5kMWPSdhJpYL9xa5hEe7aieE+707dXeMI4ej3diy6mXdZpgA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.46.2", + "@algolia/requester-browser-xhr": "5.46.2", + "@algolia/requester-fetch": "5.46.2", + "@algolia/requester-node-http": "5.46.2" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/ingestion": { + "version": "1.46.2", + "resolved": "https://registry.npmjs.org/@algolia/ingestion/-/ingestion-1.46.2.tgz", + "integrity": "sha512-1Uw2OslTWiOFDtt83y0bGiErJYy5MizadV0nHnOoHFWMoDqWW0kQoMFI65pXqRSkVvit5zjXSLik2xMiyQJDWQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.46.2", + "@algolia/requester-browser-xhr": "5.46.2", + "@algolia/requester-fetch": "5.46.2", + "@algolia/requester-node-http": "5.46.2" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/monitoring": { + "version": "1.46.2", + "resolved": "https://registry.npmjs.org/@algolia/monitoring/-/monitoring-1.46.2.tgz", + "integrity": "sha512-xk9f+DPtNcddWN6E7n1hyNNsATBCHIqAvVGG2EAGHJc4AFYL18uM/kMTiOKXE/LKDPyy1JhIerrh9oYb7RBrgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.46.2", + "@algolia/requester-browser-xhr": "5.46.2", + "@algolia/requester-fetch": "5.46.2", + "@algolia/requester-node-http": "5.46.2" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/recommend": { + "version": "5.46.2", + "resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-5.46.2.tgz", + "integrity": "sha512-NApbTPj9LxGzNw4dYnZmj2BoXiAc8NmbbH6qBNzQgXklGklt/xldTvu+FACN6ltFsTzoNU6j2mWNlHQTKGC5+Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.46.2", + "@algolia/requester-browser-xhr": "5.46.2", + "@algolia/requester-fetch": "5.46.2", + "@algolia/requester-node-http": "5.46.2" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/requester-browser-xhr": { + "version": "5.46.2", + "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.46.2.tgz", + "integrity": "sha512-ekotpCwpSp033DIIrsTpYlGUCF6momkgupRV/FA3m62SreTSZUKjgK6VTNyG7TtYfq9YFm/pnh65bATP/ZWJEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.46.2" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/requester-fetch": { + "version": "5.46.2", + "resolved": "https://registry.npmjs.org/@algolia/requester-fetch/-/requester-fetch-5.46.2.tgz", + "integrity": "sha512-gKE+ZFi/6y7saTr34wS0SqYFDcjHW4Wminv8PDZEi0/mE99+hSrbKgJWxo2ztb5eqGirQTgIh1AMVacGGWM1iw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.46.2" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/requester-node-http": { + "version": "5.46.2", + "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.46.2.tgz", + "integrity": "sha512-ciPihkletp7ttweJ8Zt+GukSVLp2ANJHU+9ttiSxsJZThXc4Y2yJ8HGVWesW5jN1zrsZsezN71KrMx/iZsOYpg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.46.2" + }, + "engines": { + "node": ">= 14.0.0" } }, "node_modules/@ampproject/remapping": { @@ -63,211 +273,223 @@ } }, "node_modules/@angular-devkit/architect": { - "version": "0.1902.15", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1902.15.tgz", - "integrity": "sha512-RbqhStc6ZoRv57ZqLB36VOkBkAdU3nNezCvIs0AJV5V4+vLPMrb0hpIB0sF+9yMlMjWsolnRsj0/Fil+zQG3bw==", + "version": "0.2101.4", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.2101.4.tgz", + "integrity": "sha512-3yyebORk+ovtO+LfDjIGbGCZhCMDAsyn9vkCljARj3sSshS4blOQBar0g+V3kYAweLT5Gf+rTKbN5jneOkBAFQ==", "dev": true, + "license": "MIT", "dependencies": { - "@angular-devkit/core": "19.2.15", - "rxjs": "7.8.1" + "@angular-devkit/core": "21.1.4", + "rxjs": "7.8.2" + }, + "bin": { + "architect": "bin/cli.js" }, "engines": { - "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "node": "^20.19.0 || ^22.12.0 || >=24.0.0", "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", "yarn": ">= 1.13.0" } }, - "node_modules/@angular-devkit/architect/node_modules/rxjs": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", - "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "node_modules/@angular-devkit/architect/node_modules/@angular-devkit/core": { + "version": "21.1.4", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-21.1.4.tgz", + "integrity": "sha512-ObPTI5gYCB1jGxTRhcqZ6oQVUBFVJ8GH4LksVuAiz0nFX7xxpzARWvlhq943EtnlovVlUd9I8fM3RQqjfGVVAQ==", "dev": true, + "license": "MIT", "dependencies": { - "tslib": "^2.1.0" + "ajv": "8.17.1", + "ajv-formats": "3.0.1", + "jsonc-parser": "3.3.1", + "picomatch": "4.0.3", + "rxjs": "7.8.2", + "source-map": "0.7.6" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "chokidar": "^5.0.0" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } } }, - "node_modules/@angular-devkit/build-angular": { - "version": "19.2.15", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-19.2.15.tgz", - "integrity": "sha512-mqudAcyrSp/E7ZQdQoHfys0/nvQuwyJDaAzj3qL3HUStuUzb5ULNOj2f6sFBo+xYo+/WT8IzmzDN9DCqDgvFaA==", + "node_modules/@angular-devkit/schematics": { + "version": "21.1.4", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-21.1.4.tgz", + "integrity": "sha512-Nqq0ioCUxrbEX+L4KOarETcZZJNnJ1mAJ0ubO4VM91qnn8RBBM9SnQ91590TfC34Szk/wh+3+Uj6KUvTJNuegQ==", "dev": true, + "license": "MIT", "dependencies": { - "@ampproject/remapping": "2.3.0", - "@angular-devkit/architect": "0.1902.15", - "@angular-devkit/build-webpack": "0.1902.15", - "@angular-devkit/core": "19.2.15", - "@angular/build": "19.2.15", - "@babel/core": "7.26.10", - "@babel/generator": "7.26.10", - "@babel/helper-annotate-as-pure": "7.25.9", - "@babel/helper-split-export-declaration": "7.24.7", - "@babel/plugin-transform-async-generator-functions": "7.26.8", - "@babel/plugin-transform-async-to-generator": "7.25.9", - "@babel/plugin-transform-runtime": "7.26.10", - "@babel/preset-env": "7.26.9", - "@babel/runtime": "7.26.10", - "@discoveryjs/json-ext": "0.6.3", - "@ngtools/webpack": "19.2.15", - "@vitejs/plugin-basic-ssl": "1.2.0", - "ansi-colors": "4.1.3", - "autoprefixer": "10.4.20", - "babel-loader": "9.2.1", - "browserslist": "^4.21.5", - "copy-webpack-plugin": "12.0.2", - "css-loader": "7.1.2", - "esbuild-wasm": "0.25.4", - "fast-glob": "3.3.3", - "http-proxy-middleware": "3.0.5", - "istanbul-lib-instrument": "6.0.3", + "@angular-devkit/core": "21.1.4", "jsonc-parser": "3.3.1", - "karma-source-map-support": "1.4.0", - "less": "4.2.2", - "less-loader": "12.2.0", - "license-webpack-plugin": "4.0.2", - "loader-utils": "3.3.1", - "mini-css-extract-plugin": "2.9.2", - "open": "10.1.0", - "ora": "5.4.1", - "picomatch": "4.0.2", - "piscina": "4.8.0", - "postcss": "8.5.2", - "postcss-loader": "8.1.1", - "resolve-url-loader": "5.0.0", - "rxjs": "7.8.1", - "sass": "1.85.0", - "sass-loader": "16.0.5", - "semver": "7.7.1", - "source-map-loader": "5.0.0", - "source-map-support": "0.5.21", - "terser": "5.39.0", - "tree-kill": "1.2.2", - "tslib": "2.8.1", - "webpack": "5.98.0", - "webpack-dev-middleware": "7.4.2", - "webpack-dev-server": "5.2.2", - "webpack-merge": "6.0.1", - "webpack-subresource-integrity": "5.1.0" + "magic-string": "0.30.21", + "ora": "9.0.0", + "rxjs": "7.8.2" }, "engines": { - "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "node": "^20.19.0 || ^22.12.0 || >=24.0.0", "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", "yarn": ">= 1.13.0" + } + }, + "node_modules/@angular-devkit/schematics/node_modules/@angular-devkit/core": { + "version": "21.1.4", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-21.1.4.tgz", + "integrity": "sha512-ObPTI5gYCB1jGxTRhcqZ6oQVUBFVJ8GH4LksVuAiz0nFX7xxpzARWvlhq943EtnlovVlUd9I8fM3RQqjfGVVAQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "8.17.1", + "ajv-formats": "3.0.1", + "jsonc-parser": "3.3.1", + "picomatch": "4.0.3", + "rxjs": "7.8.2", + "source-map": "0.7.6" }, - "optionalDependencies": { - "esbuild": "0.25.4" + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" }, "peerDependencies": { - "@angular/compiler-cli": "^19.0.0 || ^19.2.0-next.0", - "@angular/localize": "^19.0.0 || ^19.2.0-next.0", - "@angular/platform-server": "^19.0.0 || ^19.2.0-next.0", - "@angular/service-worker": "^19.0.0 || ^19.2.0-next.0", - "@angular/ssr": "^19.2.15", - "@web/test-runner": "^0.20.0", - "browser-sync": "^3.0.2", - "jest": "^29.5.0", - "jest-environment-jsdom": "^29.5.0", - "karma": "^6.3.0", - "ng-packagr": "^19.0.0 || ^19.2.0-next.0", - "protractor": "^7.0.0", - "tailwindcss": "^2.0.0 || ^3.0.0 || ^4.0.0", - "typescript": ">=5.5 <5.9" + "chokidar": "^5.0.0" }, "peerDependenciesMeta": { - "@angular/localize": { - "optional": true - }, - "@angular/platform-server": { - "optional": true - }, - "@angular/service-worker": { - "optional": true - }, - "@angular/ssr": { - "optional": true - }, - "@web/test-runner": { - "optional": true - }, - "browser-sync": { - "optional": true - }, - "jest": { - "optional": true - }, - "jest-environment-jsdom": { - "optional": true - }, - "karma": { - "optional": true - }, - "ng-packagr": { - "optional": true - }, - "protractor": { - "optional": true - }, - "tailwindcss": { + "chokidar": { "optional": true } } }, - "node_modules/@angular-devkit/build-angular/node_modules/rxjs": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", - "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "node_modules/@angular-eslint/builder": { + "version": "21.0.1", + "resolved": "https://registry.npmjs.org/@angular-eslint/builder/-/builder-21.0.1.tgz", + "integrity": "sha512-6BqpmW0XvjTOs2YOHwzeZcQ32eL8vs8SCHjt1cQnq1+libOVDXky1eb/jRs7ouyA49UagLDoM34K1kjrYo8P3Q==", "dev": true, + "license": "MIT", "dependencies": { - "tslib": "^2.1.0" + "@angular-devkit/architect": ">= 0.2100.0 < 0.2200.0", + "@angular-devkit/core": ">= 21.0.0 < 22.0.0" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": "*" } }, - "node_modules/@angular-devkit/build-webpack": { - "version": "0.1902.15", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1902.15.tgz", - "integrity": "sha512-pIfZeizWsViXx8bsMoBLZw7Tl7uFf7bM7hAfmNwk0bb0QGzx5k1BiW6IKWyaG+Dg6U4UCrlNpIiut2b78HwQZw==", + "node_modules/@angular-eslint/builder/node_modules/@angular-devkit/core": { + "version": "21.1.4", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-21.1.4.tgz", + "integrity": "sha512-ObPTI5gYCB1jGxTRhcqZ6oQVUBFVJ8GH4LksVuAiz0nFX7xxpzARWvlhq943EtnlovVlUd9I8fM3RQqjfGVVAQ==", "dev": true, + "license": "MIT", "dependencies": { - "@angular-devkit/architect": "0.1902.15", - "rxjs": "7.8.1" + "ajv": "8.17.1", + "ajv-formats": "3.0.1", + "jsonc-parser": "3.3.1", + "picomatch": "4.0.3", + "rxjs": "7.8.2", + "source-map": "0.7.6" }, "engines": { - "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "node": "^20.19.0 || ^22.12.0 || >=24.0.0", "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", "yarn": ">= 1.13.0" }, "peerDependencies": { - "webpack": "^5.30.0", - "webpack-dev-server": "^5.0.2" + "chokidar": "^5.0.0" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } } }, - "node_modules/@angular-devkit/build-webpack/node_modules/rxjs": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", - "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "node_modules/@angular-eslint/bundled-angular-compiler": { + "version": "21.0.1", + "resolved": "https://registry.npmjs.org/@angular-eslint/bundled-angular-compiler/-/bundled-angular-compiler-21.0.1.tgz", + "integrity": "sha512-Kb59SopkJ2sDgZSysL+ZqcfqM2cbK+gciAyHljkrCUsqo66eEq5KCZUU//RVoo4MHi+qL/dFy54JG/+A/35xcQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@angular-eslint/eslint-plugin": { + "version": "21.0.1", + "resolved": "https://registry.npmjs.org/@angular-eslint/eslint-plugin/-/eslint-plugin-21.0.1.tgz", + "integrity": "sha512-tSb5qgIwoMrX3Z17dSsHrNFWrgBWafxK7IQudU0RXxdzq6joq1qDrzHwLT3Jn+Y6ocn0jdavAefEGHAhomCjcQ==", "dev": true, + "license": "MIT", "dependencies": { - "tslib": "^2.1.0" + "@angular-eslint/bundled-angular-compiler": "21.0.1", + "@angular-eslint/utils": "21.0.1", + "ts-api-utils": "^2.1.0" + }, + "peerDependencies": { + "@typescript-eslint/utils": "^7.11.0 || ^8.0.0", + "eslint": "^8.57.0 || ^9.0.0", + "typescript": "*" + } + }, + "node_modules/@angular-eslint/eslint-plugin-template": { + "version": "21.0.1", + "resolved": "https://registry.npmjs.org/@angular-eslint/eslint-plugin-template/-/eslint-plugin-template-21.0.1.tgz", + "integrity": "sha512-DF1WEMalbV1hNKxbu3nwK1yUa+E2FQpNz0KDORU65/vdCffeuftCetobrsAS7zDgJ6FO+Fsb+ZeCzNKEhhh1vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@angular-eslint/bundled-angular-compiler": "21.0.1", + "@angular-eslint/utils": "21.0.1", + "aria-query": "5.3.2", + "axobject-query": "4.1.0" + }, + "peerDependencies": { + "@angular-eslint/template-parser": "21.0.1", + "@typescript-eslint/types": "^7.11.0 || ^8.0.0", + "@typescript-eslint/utils": "^7.11.0 || ^8.0.0", + "eslint": "^8.57.0 || ^9.0.0", + "typescript": "*" } }, - "node_modules/@angular-devkit/core": { - "version": "19.2.15", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-19.2.15.tgz", - "integrity": "sha512-pU2RZYX6vhd7uLSdLwPnuBcr0mXJSjp3EgOXKsrlQFQZevc+Qs+2JdXgIElnOT/aDqtRtriDmLlSbtdE8n3ZbA==", + "node_modules/@angular-eslint/schematics": { + "version": "21.0.1", + "resolved": "https://registry.npmjs.org/@angular-eslint/schematics/-/schematics-21.0.1.tgz", + "integrity": "sha512-IdtGdRPuJctHuiZ8v8SN3MqWiUa3cD9Q5jFvIRkAkjpHXXmTk5PYelSjUP8UX/zfUfFkxHXghasTmJd2+252OQ==", "dev": true, + "license": "MIT", + "dependencies": { + "@angular-devkit/core": ">= 21.0.0 < 22.0.0", + "@angular-devkit/schematics": ">= 21.0.0 < 22.0.0", + "@angular-eslint/eslint-plugin": "21.0.1", + "@angular-eslint/eslint-plugin-template": "21.0.1", + "ignore": "7.0.5", + "semver": "7.7.3", + "strip-json-comments": "3.1.1" + } + }, + "node_modules/@angular-eslint/schematics/node_modules/@angular-devkit/core": { + "version": "21.1.4", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-21.1.4.tgz", + "integrity": "sha512-ObPTI5gYCB1jGxTRhcqZ6oQVUBFVJ8GH4LksVuAiz0nFX7xxpzARWvlhq943EtnlovVlUd9I8fM3RQqjfGVVAQ==", + "dev": true, + "license": "MIT", "dependencies": { "ajv": "8.17.1", "ajv-formats": "3.0.1", "jsonc-parser": "3.3.1", - "picomatch": "4.0.2", - "rxjs": "7.8.1", - "source-map": "0.7.4" + "picomatch": "4.0.3", + "rxjs": "7.8.2", + "source-map": "0.7.6" }, "engines": { - "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "node": "^20.19.0 || ^22.12.0 || >=24.0.0", "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", "yarn": ">= 1.13.0" }, "peerDependencies": { - "chokidar": "^4.0.0" + "chokidar": "^5.0.0" }, "peerDependenciesMeta": { "chokidar": { @@ -275,101 +497,136 @@ } } }, - "node_modules/@angular-devkit/core/node_modules/rxjs": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", - "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "node_modules/@angular-eslint/template-parser": { + "version": "21.0.1", + "resolved": "https://registry.npmjs.org/@angular-eslint/template-parser/-/template-parser-21.0.1.tgz", + "integrity": "sha512-1KocmjmBP0qlKQGRhRGN0MGvLxf1q2KDWbvzn7ZGdQrIDLC/hFJ8YmnOWsPrM9RxiZi0o5BxCCu9D7KlbthxIg==", "dev": true, + "license": "MIT", "dependencies": { - "tslib": "^2.1.0" + "@angular-eslint/bundled-angular-compiler": "21.0.1", + "eslint-scope": "^9.0.0" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": "*" } }, - "node_modules/@angular-devkit/schematics": { - "version": "19.2.15", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-19.2.15.tgz", - "integrity": "sha512-kNOJ+3vekJJCQKWihNmxBkarJzNW09kP5a9E1SRNiQVNOUEeSwcRR0qYotM65nx821gNzjjhJXnAZ8OazWldrg==", + "node_modules/@angular-eslint/template-parser/node_modules/eslint-scope": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-9.1.0.tgz", + "integrity": "sha512-CkWE42hOJsNj9FJRaoMX9waUFYhqY4jmyLFdAdzZr6VaCg3ynLYx4WnOdkaIifGfH4gsUcBTn4OZbHXkpLD0FQ==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "@angular-devkit/core": "19.2.15", - "jsonc-parser": "3.3.1", - "magic-string": "0.30.17", - "ora": "5.4.1", - "rxjs": "7.8.1" + "@types/esrecurse": "^4.3.1", + "@types/estree": "^1.0.8", + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" }, "engines": { - "node": "^18.19.1 || ^20.11.1 || >=22.0.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@angular-eslint/template-parser/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/@angular-devkit/schematics/node_modules/rxjs": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", - "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "node_modules/@angular-eslint/utils": { + "version": "21.0.1", + "resolved": "https://registry.npmjs.org/@angular-eslint/utils/-/utils-21.0.1.tgz", + "integrity": "sha512-tovWIDiEsfSAsPWH+/wL9Hfl/Hc+2j2IP+Z85I6uWTbynLVdyURx8gmJjKBUTSCmcyrgBnTbnnlr4DTM6/aFOg==", "dev": true, + "license": "MIT", "dependencies": { - "tslib": "^2.1.0" + "@angular-eslint/bundled-angular-compiler": "21.0.1" + }, + "peerDependencies": { + "@typescript-eslint/utils": "^7.11.0 || ^8.0.0", + "eslint": "^8.57.0 || ^9.0.0", + "typescript": "*" } }, "node_modules/@angular/build": { - "version": "19.2.15", - "resolved": "https://registry.npmjs.org/@angular/build/-/build-19.2.15.tgz", - "integrity": "sha512-iE4fp4d5ALu702uoL6/YkjM2JlGEXZ5G+RVzq3W2jg/Ft6ISAQnRKB6mymtetDD6oD7i87e8uSu9kFVNBauX2w==", + "version": "21.1.4", + "resolved": "https://registry.npmjs.org/@angular/build/-/build-21.1.4.tgz", + "integrity": "sha512-7CAAQPWFMMqod40ox5MOVB/CnoBXFDehyQhs0hls6lu7bOy/M0EDy0v6bERkyNGRz1mihWWBiCV8XzEinrlq1A==", "dev": true, + "license": "MIT", "dependencies": { "@ampproject/remapping": "2.3.0", - "@angular-devkit/architect": "0.1902.15", - "@babel/core": "7.26.10", - "@babel/helper-annotate-as-pure": "7.25.9", + "@angular-devkit/architect": "0.2101.4", + "@babel/core": "7.28.5", + "@babel/helper-annotate-as-pure": "7.27.3", "@babel/helper-split-export-declaration": "7.24.7", - "@babel/plugin-syntax-import-attributes": "7.26.0", - "@inquirer/confirm": "5.1.6", - "@vitejs/plugin-basic-ssl": "1.2.0", - "beasties": "0.3.2", - "browserslist": "^4.23.0", - "esbuild": "0.25.4", - "fast-glob": "3.3.3", + "@inquirer/confirm": "5.1.21", + "@vitejs/plugin-basic-ssl": "2.1.0", + "beasties": "0.3.5", + "browserslist": "^4.26.0", + "esbuild": "0.27.2", "https-proxy-agent": "7.0.6", "istanbul-lib-instrument": "6.0.3", - "listr2": "8.2.5", - "magic-string": "0.30.17", + "jsonc-parser": "3.3.1", + "listr2": "9.0.5", + "magic-string": "0.30.21", "mrmime": "2.0.1", - "parse5-html-rewriting-stream": "7.0.0", - "picomatch": "4.0.2", - "piscina": "4.8.0", - "rollup": "4.34.8", - "sass": "1.85.0", - "semver": "7.7.1", + "parse5-html-rewriting-stream": "8.0.0", + "picomatch": "4.0.3", + "piscina": "5.1.4", + "rolldown": "1.0.0-beta.58", + "sass": "1.97.1", + "semver": "7.7.3", "source-map-support": "0.5.21", - "vite": "6.2.7", - "watchpack": "2.4.2" + "tinyglobby": "0.2.15", + "undici": "7.20.0", + "vite": "7.3.0", + "watchpack": "2.5.0" }, "engines": { - "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "node": "^20.19.0 || ^22.12.0 || >=24.0.0", "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", "yarn": ">= 1.13.0" }, "optionalDependencies": { - "lmdb": "3.2.6" + "lmdb": "3.4.4" }, "peerDependencies": { - "@angular/compiler": "^19.0.0 || ^19.2.0-next.0", - "@angular/compiler-cli": "^19.0.0 || ^19.2.0-next.0", - "@angular/localize": "^19.0.0 || ^19.2.0-next.0", - "@angular/platform-server": "^19.0.0 || ^19.2.0-next.0", - "@angular/service-worker": "^19.0.0 || ^19.2.0-next.0", - "@angular/ssr": "^19.2.15", + "@angular/compiler": "^21.0.0", + "@angular/compiler-cli": "^21.0.0", + "@angular/core": "^21.0.0", + "@angular/localize": "^21.0.0", + "@angular/platform-browser": "^21.0.0", + "@angular/platform-server": "^21.0.0", + "@angular/service-worker": "^21.0.0", + "@angular/ssr": "^21.1.4", "karma": "^6.4.0", "less": "^4.2.0", - "ng-packagr": "^19.0.0 || ^19.2.0-next.0", + "ng-packagr": "^21.0.0", "postcss": "^8.4.0", "tailwindcss": "^2.0.0 || ^3.0.0 || ^4.0.0", - "typescript": ">=5.5 <5.9" + "tslib": "^2.3.0", + "typescript": ">=5.9 <6.0", + "vitest": "^4.0.8" }, "peerDependenciesMeta": { + "@angular/core": { + "optional": true + }, "@angular/localize": { "optional": true }, + "@angular/platform-browser": { + "optional": true + }, "@angular/platform-server": { "optional": true }, @@ -393,715 +650,983 @@ }, "tailwindcss": { "optional": true + }, + "vitest": { + "optional": true } } }, - "node_modules/@angular/cli": { - "version": "19.2.15", - "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-19.2.15.tgz", - "integrity": "sha512-YRIpARHWSOnWkHusUWTQgeUrPWMjWvtQrOkjWc6stF36z2KUzKMEng6EzUvH6sZolNSwVwOFpODEP0ut4aBkvQ==", + "node_modules/@angular/build/node_modules/@esbuild/aix-ppc64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.2.tgz", + "integrity": "sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==", + "cpu": [ + "ppc64" + ], "dev": true, - "dependencies": { - "@angular-devkit/architect": "0.1902.15", - "@angular-devkit/core": "19.2.15", - "@angular-devkit/schematics": "19.2.15", - "@inquirer/prompts": "7.3.2", - "@listr2/prompt-adapter-inquirer": "2.0.18", - "@schematics/angular": "19.2.15", - "@yarnpkg/lockfile": "1.1.0", - "ini": "5.0.0", - "jsonc-parser": "3.3.1", - "listr2": "8.2.5", - "npm-package-arg": "12.0.2", - "npm-pick-manifest": "10.0.0", - "pacote": "20.0.0", - "resolve": "1.22.10", - "semver": "7.7.1", - "symbol-observable": "4.0.0", - "yargs": "17.7.2" - }, - "bin": { - "ng": "bin/ng.js" - }, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], "engines": { - "node": "^18.19.1 || ^20.11.1 || >=22.0.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" + "node": ">=18" } }, - "node_modules/@angular/common": { - "version": "19.2.14", - "resolved": "https://registry.npmjs.org/@angular/common/-/common-19.2.14.tgz", - "integrity": "sha512-NcNklcuyqaTjOVGf7aru8APX9mjsnZ01gFZrn47BxHozhaR0EMRrotYQTdi8YdVjPkeYFYanVntSLfhyobq/jg==", - "dependencies": { - "tslib": "^2.3.0" - }, + "node_modules/@angular/build/node_modules/@esbuild/android-arm": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.2.tgz", + "integrity": "sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], "engines": { - "node": "^18.19.1 || ^20.11.1 || >=22.0.0" - }, - "peerDependencies": { - "@angular/core": "19.2.14", - "rxjs": "^6.5.3 || ^7.4.0" + "node": ">=18" } }, - "node_modules/@angular/compiler": { - "version": "19.2.14", - "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-19.2.14.tgz", - "integrity": "sha512-ZqJDYOdhgKpVGNq3+n/Gbxma8DVYElDsoRe0tvNtjkWBVdaOxdZZUqmJ3kdCBsqD/aqTRvRBu0KGo9s2fCChkA==", - "dependencies": { - "tslib": "^2.3.0" - }, + "node_modules/@angular/build/node_modules/@esbuild/android-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.2.tgz", + "integrity": "sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], "engines": { - "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + "node": ">=18" } }, - "node_modules/@angular/compiler-cli": { - "version": "19.2.14", - "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-19.2.14.tgz", - "integrity": "sha512-e9/h86ETjoIK2yTLE9aUeMCKujdg/du2pq7run/aINjop4RtnNOw+ZlSTUa6R65lP5CVwDup1kPytpAoifw8cA==", + "node_modules/@angular/build/node_modules/@esbuild/android-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.2.tgz", + "integrity": "sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==", + "cpu": [ + "x64" + ], "dev": true, - "dependencies": { - "@babel/core": "7.26.9", - "@jridgewell/sourcemap-codec": "^1.4.14", - "chokidar": "^4.0.0", - "convert-source-map": "^1.5.1", - "reflect-metadata": "^0.2.0", - "semver": "^7.0.0", - "tslib": "^2.3.0", - "yargs": "^17.2.1" - }, - "bin": { - "ng-xi18n": "bundles/src/bin/ng_xi18n.js", - "ngc": "bundles/src/bin/ngc.js", - "ngcc": "bundles/ngcc/index.js" - }, - "engines": { - "node": "^18.19.1 || ^20.11.1 || >=22.0.0" - }, - "peerDependencies": { - "@angular/compiler": "19.2.14", - "typescript": ">=5.5 <5.9" - } - }, - "node_modules/@angular/compiler-cli/node_modules/@babel/core": { - "version": "7.26.9", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.9.tgz", - "integrity": "sha512-lWBYIrF7qK5+GjY5Uy+/hEgp8OJWOD/rpy74GplYRhEauvbHDeFB8t5hPOZxCZ0Oxf4Cc36tK51/l3ymJysrKw==", - "dev": true, - "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.26.2", - "@babel/generator": "^7.26.9", - "@babel/helper-compilation-targets": "^7.26.5", - "@babel/helper-module-transforms": "^7.26.0", - "@babel/helpers": "^7.26.9", - "@babel/parser": "^7.26.9", - "@babel/template": "^7.26.9", - "@babel/traverse": "^7.26.9", - "@babel/types": "^7.26.9", - "convert-source-map": "^2.0.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" - }, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" + "node": ">=18" } }, - "node_modules/@angular/compiler-cli/node_modules/@babel/core/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 - }, - "node_modules/@angular/compiler-cli/node_modules/@babel/core/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "node_modules/@angular/build/node_modules/@esbuild/darwin-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.2.tgz", + "integrity": "sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==", + "cpu": [ + "arm64" + ], "dev": true, - "bin": { - "semver": "bin/semver.js" + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" } }, - "node_modules/@angular/core": { - "version": "19.2.14", - "resolved": "https://registry.npmjs.org/@angular/core/-/core-19.2.14.tgz", - "integrity": "sha512-EVErpW9tGqJ/wNcAN3G/ErH8pHCJ8mM1E6bsJ8UJIpDTZkpqqYjBMtZS9YWH5n3KwUd1tAkAB2w8FK125AjDUQ==", - "dependencies": { - "tslib": "^2.3.0" - }, + "node_modules/@angular/build/node_modules/@esbuild/darwin-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.2.tgz", + "integrity": "sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": "^18.19.1 || ^20.11.1 || >=22.0.0" - }, - "peerDependencies": { - "rxjs": "^6.5.3 || ^7.4.0", - "zone.js": "~0.15.0" + "node": ">=18" } }, - "node_modules/@angular/forms": { - "version": "19.2.14", - "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-19.2.14.tgz", - "integrity": "sha512-hWtDOj2B0AuRTf+nkMJeodnFpDpmEK9OIhIv1YxcRe73ooaxrIdjgugkElO8I9Tj0E4/7m117ezhWDUkbqm1zA==", - "dependencies": { - "tslib": "^2.3.0" - }, + "node_modules/@angular/build/node_modules/@esbuild/freebsd-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.2.tgz", + "integrity": "sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], "engines": { - "node": "^18.19.1 || ^20.11.1 || >=22.0.0" - }, - "peerDependencies": { - "@angular/common": "19.2.14", - "@angular/core": "19.2.14", - "@angular/platform-browser": "19.2.14", - "rxjs": "^6.5.3 || ^7.4.0" + "node": ">=18" } }, - "node_modules/@angular/platform-browser": { - "version": "19.2.14", - "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-19.2.14.tgz", - "integrity": "sha512-hzkT5nmA64oVBQl6PRjdL4dIFT1n7lfM9rm5cAoS+6LUUKRgiE2d421Kpn/Hz3jaCJfo+calMIdtSMIfUJBmww==", - "dependencies": { - "tslib": "^2.3.0" - }, + "node_modules/@angular/build/node_modules/@esbuild/freebsd-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.2.tgz", + "integrity": "sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], "engines": { - "node": "^18.19.1 || ^20.11.1 || >=22.0.0" - }, - "peerDependencies": { - "@angular/animations": "19.2.14", - "@angular/common": "19.2.14", - "@angular/core": "19.2.14" - }, - "peerDependenciesMeta": { - "@angular/animations": { - "optional": true - } + "node": ">=18" } }, - "node_modules/@angular/platform-browser-dynamic": { - "version": "19.2.14", - "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-19.2.14.tgz", - "integrity": "sha512-Hfz0z1KDQmIdnFXVFCwCPykuIsHPkr1uW2aY396eARwZ6PK8i0Aadcm1ZOnpd3MR1bMyDrJo30VRS5kx89QWvA==", - "dependencies": { - "tslib": "^2.3.0" - }, + "node_modules/@angular/build/node_modules/@esbuild/linux-arm": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.2.tgz", + "integrity": "sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": "^18.19.1 || ^20.11.1 || >=22.0.0" - }, - "peerDependencies": { - "@angular/common": "19.2.14", - "@angular/compiler": "19.2.14", - "@angular/core": "19.2.14", - "@angular/platform-browser": "19.2.14" + "node": ">=18" } }, - "node_modules/@angular/platform-server": { - "version": "19.2.14", - "resolved": "https://registry.npmjs.org/@angular/platform-server/-/platform-server-19.2.14.tgz", - "integrity": "sha512-vmnRTDhlhahna6HbmzJh+qelXkyy1wBiJrOhnLR3UVeoBMBOTTjnTKtInfVrgZTMYcV9H8us480cvtSWzYsddA==", - "dependencies": { - "tslib": "^2.3.0", - "xhr2": "^0.2.0" - }, + "node_modules/@angular/build/node_modules/@esbuild/linux-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.2.tgz", + "integrity": "sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": "^18.19.1 || ^20.11.1 || >=22.0.0" - }, - "peerDependencies": { - "@angular/common": "19.2.14", - "@angular/compiler": "19.2.14", - "@angular/core": "19.2.14", - "@angular/platform-browser": "19.2.14", - "rxjs": "^6.5.3 || ^7.4.0" + "node": ">=18" } }, - "node_modules/@angular/router": { - "version": "19.2.14", - "resolved": "https://registry.npmjs.org/@angular/router/-/router-19.2.14.tgz", - "integrity": "sha512-cBTWY9Jx7YhbmDYDb7Hqz4Q7UNIMlKTkdKToJd2pbhIXyoS+kHVQrySmyca+jgvYMjWnIjsAEa3dpje12D4mFw==", - "dependencies": { - "tslib": "^2.3.0" - }, + "node_modules/@angular/build/node_modules/@esbuild/linux-ia32": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.2.tgz", + "integrity": "sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": "^18.19.1 || ^20.11.1 || >=22.0.0" - }, - "peerDependencies": { - "@angular/common": "19.2.14", - "@angular/core": "19.2.14", - "@angular/platform-browser": "19.2.14", - "rxjs": "^6.5.3 || ^7.4.0" + "node": ">=18" } }, - "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==", + "node_modules/@angular/build/node_modules/@esbuild/linux-loong64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.2.tgz", + "integrity": "sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==", + "cpu": [ + "loong64" + ], "dev": true, - "dependencies": { - "@babel/helper-validator-identifier": "^7.27.1", - "js-tokens": "^4.0.0", - "picocolors": "^1.1.1" - }, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6.9.0" + "node": ">=18" } }, - "node_modules/@babel/compat-data": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.0.tgz", - "integrity": "sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw==", + "node_modules/@angular/build/node_modules/@esbuild/linux-mips64el": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.2.tgz", + "integrity": "sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==", + "cpu": [ + "mips64el" + ], "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6.9.0" + "node": ">=18" } }, - "node_modules/@babel/core": { - "version": "7.26.10", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.10.tgz", - "integrity": "sha512-vMqyb7XCDMPvJFFOaT9kxtiRh42GwlZEg1/uIgtZshS5a/8OaduUfCi7kynKgc3Tw/6Uo2D+db9qBttghhmxwQ==", - "dev": true, - "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.26.2", - "@babel/generator": "^7.26.10", - "@babel/helper-compilation-targets": "^7.26.5", - "@babel/helper-module-transforms": "^7.26.0", - "@babel/helpers": "^7.26.10", - "@babel/parser": "^7.26.10", - "@babel/template": "^7.26.9", - "@babel/traverse": "^7.26.10", - "@babel/types": "^7.26.10", - "convert-source-map": "^2.0.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" - }, + "node_modules/@angular/build/node_modules/@esbuild/linux-ppc64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.2.tgz", + "integrity": "sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" + "node": ">=18" } }, - "node_modules/@babel/core/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 - }, - "node_modules/@babel/core/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "node_modules/@angular/build/node_modules/@esbuild/linux-riscv64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.2.tgz", + "integrity": "sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==", + "cpu": [ + "riscv64" + ], "dev": true, - "bin": { - "semver": "bin/semver.js" + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" } }, - "node_modules/@babel/generator": { - "version": "7.26.10", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.10.tgz", - "integrity": "sha512-rRHT8siFIXQrAYOYqZQVsAr8vJ+cBNqcVAY6m5V8/4QqzaPl+zDBe6cLEPRDuNOUf3ww8RfJVlOyQMoSI+5Ang==", + "node_modules/@angular/build/node_modules/@esbuild/linux-s390x": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.2.tgz", + "integrity": "sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==", + "cpu": [ + "s390x" + ], "dev": true, - "dependencies": { - "@babel/parser": "^7.26.10", - "@babel/types": "^7.26.10", - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25", - "jsesc": "^3.0.2" - }, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6.9.0" + "node": ">=18" } }, - "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.9.tgz", - "integrity": "sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==", + "node_modules/@angular/build/node_modules/@esbuild/linux-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.2.tgz", + "integrity": "sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==", + "cpu": [ + "x64" + ], "dev": true, - "dependencies": { - "@babel/types": "^7.25.9" - }, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6.9.0" + "node": ">=18" } }, - "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==", + "node_modules/@angular/build/node_modules/@esbuild/netbsd-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.2.tgz", + "integrity": "sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==", + "cpu": [ + "arm64" + ], "dev": true, - "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" - }, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], "engines": { - "node": ">=6.9.0" + "node": ">=18" } }, - "node_modules/@babel/helper-compilation-targets/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "node_modules/@angular/build/node_modules/@esbuild/netbsd-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.2.tgz", + "integrity": "sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==", + "cpu": [ + "x64" + ], "dev": true, - "bin": { - "semver": "bin/semver.js" + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" } }, - "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.27.1.tgz", - "integrity": "sha512-QwGAmuvM17btKU5VqXfb+Giw4JcN0hjuufz3DYnpeVDvZLAObloM77bhMXiqry3Iio+Ai4phVRDwl6WU10+r5A==", + "node_modules/@angular/build/node_modules/@esbuild/openbsd-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.2.tgz", + "integrity": "sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==", + "cpu": [ + "arm64" + ], "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.1", - "@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.27.1", - "semver": "^6.3.1" - }, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" + "node": ">=18" } }, - "node_modules/@babel/helper-create-class-features-plugin/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==", + "node_modules/@angular/build/node_modules/@esbuild/openbsd-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.2.tgz", + "integrity": "sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==", + "cpu": [ + "x64" + ], "dev": true, - "dependencies": { - "@babel/types": "^7.27.3" - }, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], "engines": { - "node": ">=6.9.0" + "node": ">=18" } }, - "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "node_modules/@angular/build/node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.2.tgz", + "integrity": "sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==", + "cpu": [ + "arm64" + ], "dev": true, - "bin": { - "semver": "bin/semver.js" + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" } }, - "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==", + "node_modules/@angular/build/node_modules/@esbuild/sunos-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.2.tgz", + "integrity": "sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==", + "cpu": [ + "x64" + ], "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.1", - "regexpu-core": "^6.2.0", - "semver": "^6.3.1" - }, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" + "node": ">=18" } }, - "node_modules/@babel/helper-create-regexp-features-plugin/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==", + "node_modules/@angular/build/node_modules/@esbuild/win32-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.2.tgz", + "integrity": "sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==", + "cpu": [ + "arm64" + ], "dev": true, - "dependencies": { - "@babel/types": "^7.27.3" - }, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">=6.9.0" + "node": ">=18" } }, - "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "node_modules/@angular/build/node_modules/@esbuild/win32-ia32": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.2.tgz", + "integrity": "sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==", + "cpu": [ + "ia32" + ], "dev": true, - "bin": { - "semver": "bin/semver.js" + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" } }, - "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==", + "node_modules/@angular/build/node_modules/@esbuild/win32-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.2.tgz", + "integrity": "sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==", + "cpu": [ + "x64" + ], "dev": true, - "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" + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" } }, - "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==", + "node_modules/@angular/build/node_modules/@vitejs/plugin-basic-ssl": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-basic-ssl/-/plugin-basic-ssl-2.1.0.tgz", + "integrity": "sha512-dOxxrhgyDIEUADhb/8OlV9JIqYLgos03YorAueTIeOUskLJSEsfwCByjbu98ctXitUN3znXKp0bYD/WHSudCeA==", "dev": true, + "license": "MIT", "engines": { - "node": ">=6.9.0" + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "peerDependencies": { + "vite": "^6.0.0 || ^7.0.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==", + "node_modules/@angular/build/node_modules/esbuild": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.2.tgz", + "integrity": "sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.2", + "@esbuild/android-arm": "0.27.2", + "@esbuild/android-arm64": "0.27.2", + "@esbuild/android-x64": "0.27.2", + "@esbuild/darwin-arm64": "0.27.2", + "@esbuild/darwin-x64": "0.27.2", + "@esbuild/freebsd-arm64": "0.27.2", + "@esbuild/freebsd-x64": "0.27.2", + "@esbuild/linux-arm": "0.27.2", + "@esbuild/linux-arm64": "0.27.2", + "@esbuild/linux-ia32": "0.27.2", + "@esbuild/linux-loong64": "0.27.2", + "@esbuild/linux-mips64el": "0.27.2", + "@esbuild/linux-ppc64": "0.27.2", + "@esbuild/linux-riscv64": "0.27.2", + "@esbuild/linux-s390x": "0.27.2", + "@esbuild/linux-x64": "0.27.2", + "@esbuild/netbsd-arm64": "0.27.2", + "@esbuild/netbsd-x64": "0.27.2", + "@esbuild/openbsd-arm64": "0.27.2", + "@esbuild/openbsd-x64": "0.27.2", + "@esbuild/openharmony-arm64": "0.27.2", + "@esbuild/sunos-x64": "0.27.2", + "@esbuild/win32-arm64": "0.27.2", + "@esbuild/win32-ia32": "0.27.2", + "@esbuild/win32-x64": "0.27.2" + } + }, + "node_modules/@angular/build/node_modules/vite": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.0.tgz", + "integrity": "sha512-dZwN5L1VlUBewiP6H9s2+B3e3Jg96D0vzN+Ry73sOefebhYr9f94wwkMNN/9ouoU8pV1BqA1d1zGk8928cx0rg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/traverse": "^7.27.1", - "@babel/types": "^7.27.1" + "esbuild": "^0.27.0", + "fdir": "^6.5.0", + "picomatch": "^4.0.3", + "postcss": "^8.5.6", + "rollup": "^4.43.0", + "tinyglobby": "^0.2.15" + }, + "bin": { + "vite": "bin/vite.js" }, "engines": { - "node": ">=6.9.0" + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "lightningcss": "^1.21.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } } }, - "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, - "dependencies": { - "@babel/traverse": "^7.27.1", - "@babel/types": "^7.27.1" + "node_modules/@angular/cli": { + "version": "21.1.4", + "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-21.1.4.tgz", + "integrity": "sha512-XsMHgxTvHGiXXrhYZz3zMZYhYU0gHdpoHKGiEKXwcx+S1KoYbIssyg6oF2Kq49ZaE0OYCTKjnvgDce6ZqdkJ/A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@angular-devkit/architect": "0.2101.4", + "@angular-devkit/core": "21.1.4", + "@angular-devkit/schematics": "21.1.4", + "@inquirer/prompts": "7.10.1", + "@listr2/prompt-adapter-inquirer": "3.0.5", + "@modelcontextprotocol/sdk": "1.26.0", + "@schematics/angular": "21.1.4", + "@yarnpkg/lockfile": "1.1.0", + "algoliasearch": "5.46.2", + "ini": "6.0.0", + "jsonc-parser": "3.3.1", + "listr2": "9.0.5", + "npm-package-arg": "13.0.2", + "pacote": "21.0.4", + "parse5-html-rewriting-stream": "8.0.0", + "resolve": "1.22.11", + "semver": "7.7.3", + "yargs": "18.0.0", + "zod": "4.3.5" + }, + "bin": { + "ng": "bin/ng.js" }, "engines": { - "node": ">=6.9.0" + "node": "^20.19.0 || ^22.12.0 || >=24.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" } }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.27.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.27.3.tgz", - "integrity": "sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg==", + "node_modules/@angular/cli/node_modules/@angular-devkit/core": { + "version": "21.1.4", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-21.1.4.tgz", + "integrity": "sha512-ObPTI5gYCB1jGxTRhcqZ6oQVUBFVJ8GH4LksVuAiz0nFX7xxpzARWvlhq943EtnlovVlUd9I8fM3RQqjfGVVAQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-module-imports": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1", - "@babel/traverse": "^7.27.3" + "ajv": "8.17.1", + "ajv-formats": "3.0.1", + "jsonc-parser": "3.3.1", + "picomatch": "4.0.3", + "rxjs": "7.8.2", + "source-map": "0.7.6" }, "engines": { - "node": ">=6.9.0" + "node": "^20.19.0 || ^22.12.0 || >=24.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" }, "peerDependencies": { - "@babel/core": "^7.0.0" + "chokidar": "^5.0.0" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } } }, - "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, + "node_modules/@angular/common": { + "version": "21.1.4", + "resolved": "https://registry.npmjs.org/@angular/common/-/common-21.1.4.tgz", + "integrity": "sha512-1uOxPrHO9PFZBU/JavzYzjxAm+5x7vD2z6AeUndqdT4LjqOBIePswxFDRqM9dlfF8FIwnnfmNFipiC/yQjJSnA==", + "license": "MIT", "dependencies": { - "@babel/types": "^7.27.1" + "tslib": "^2.3.0" }, "engines": { - "node": ">=6.9.0" + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "@angular/core": "21.1.4", + "rxjs": "^6.5.3 || ^7.4.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, + "node_modules/@angular/compiler": { + "version": "21.1.4", + "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-21.1.4.tgz", + "integrity": "sha512-H0qtASeqOTaS44ioF4DYE/yNqwzUmEJpMYrcNEUFEwA20/DkLzyoaEx4y1CjIxtXxuhtge95PNymDBOLWSjIdg==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, "engines": { - "node": ">=6.9.0" + "node": "^20.19.0 || ^22.12.0 || >=24.0.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==", + "node_modules/@angular/compiler-cli": { + "version": "21.1.4", + "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-21.1.4.tgz", + "integrity": "sha512-Uw8KmpVCo58/f5wf6pY8ZS5fodv65hn5jxms8Nv/K7/LVe3i1nNFrHyneBx5+a7qkz93nSV4rdwBVnMvjIyr+g==", "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" + "@babel/core": "7.28.5", + "@jridgewell/sourcemap-codec": "^1.4.14", + "chokidar": "^5.0.0", + "convert-source-map": "^1.5.1", + "reflect-metadata": "^0.2.0", + "semver": "^7.0.0", + "tslib": "^2.3.0", + "yargs": "^18.0.0" + }, + "bin": { + "ng-xi18n": "bundles/src/bin/ng_xi18n.js", + "ngc": "bundles/src/bin/ngc.js" }, "engines": { - "node": ">=6.9.0" + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" }, "peerDependencies": { - "@babel/core": "^7.0.0" + "@angular/compiler": "21.1.4", + "typescript": ">=5.9 <6.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/@babel/helper-remap-async-to-generator/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==", + "node_modules/@angular/compiler-cli/node_modules/chokidar": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-5.0.0.tgz", + "integrity": "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.27.3" + "readdirp": "^5.0.0" }, "engines": { - "node": ">=6.9.0" + "node": ">= 20.19.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "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==", + "node_modules/@angular/compiler-cli/node_modules/readdirp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-5.0.0.tgz", + "integrity": "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==", "dev": true, + "license": "MIT", + "engines": { + "node": ">= 20.19.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@angular/core": { + "version": "21.1.4", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-21.1.4.tgz", + "integrity": "sha512-QBDO5SaVYTVQ0fIN9Qd7US9cUCgs2vM9x6K18PTUKmygIkHVHTFdzwm4MO5gpCOFzJseGbS+dNzqn+v0PaKf9g==", + "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" + "tslib": "^2.3.0" }, "engines": { - "node": ">=6.9.0" + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" }, "peerDependencies": { - "@babel/core": "^7.0.0" + "@angular/compiler": "21.1.4", + "rxjs": "^6.5.3 || ^7.4.0", + "zone.js": "~0.15.0 || ~0.16.0" + }, + "peerDependenciesMeta": { + "@angular/compiler": { + "optional": true + }, + "zone.js": { + "optional": true + } } }, - "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, + "node_modules/@angular/forms": { + "version": "21.1.4", + "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-21.1.4.tgz", + "integrity": "sha512-duVT/eOncmFNBYRlK/F7WDg6GD1vL1mxUrDdnp7M9J8JvNrKH0PvdfzuOAmjbB8/bsvUNTLFXCV4+43Mc2Hqsw==", + "license": "MIT", "dependencies": { - "@babel/traverse": "^7.27.1", - "@babel/types": "^7.27.1" + "@standard-schema/spec": "^1.0.0", + "tslib": "^2.3.0" }, "engines": { - "node": ">=6.9.0" + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "@angular/common": "21.1.4", + "@angular/core": "21.1.4", + "@angular/platform-browser": "21.1.4", + "rxjs": "^6.5.3 || ^7.4.0" } }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", - "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", - "dev": true, + "node_modules/@angular/platform-browser": { + "version": "21.1.4", + "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-21.1.4.tgz", + "integrity": "sha512-S6Iw5CkORih5omh+MQY35w0bUBxdSFAPLDg386S6/9fEUjDClo61hvXNKxaNh9g7tnh1LD7zmTmKrqufnhnFDQ==", + "license": "MIT", "dependencies": { - "@babel/types": "^7.24.7" + "tslib": "^2.3.0" }, "engines": { - "node": ">=6.9.0" + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "@angular/animations": "21.1.4", + "@angular/common": "21.1.4", + "@angular/core": "21.1.4" + }, + "peerDependenciesMeta": { + "@angular/animations": { + "optional": true + } } }, - "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, + "node_modules/@angular/platform-browser-dynamic": { + "version": "21.1.4", + "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-21.1.4.tgz", + "integrity": "sha512-lThgNDFHPQyrx0liNX3x8wHcgp1sd/Dym19zm1PSQ67k6J4snwxZFhNlwFHVr1K86XvX/vilyeR2edPLe9lF3Q==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, "engines": { - "node": ">=6.9.0" + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "@angular/common": "21.1.4", + "@angular/compiler": "21.1.4", + "@angular/core": "21.1.4", + "@angular/platform-browser": "21.1.4" } }, - "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==", + "node_modules/@babel/code-frame": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", + "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.28.5", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, "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==", + "node_modules/@babel/compat-data": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.0.tgz", + "integrity": "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/helper-wrap-function": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.27.1.tgz", - "integrity": "sha512-NFJK2sHUvrjo8wAU/nQTWU890/zB2jj0qBcCbZbbf+005cAsv6tMjXz31fBign6M5ov1o0Bllu+9nbqkfsjjJQ==", + "node_modules/@babel/core": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.5.tgz", + "integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/template": "^7.27.1", - "@babel/traverse": "^7.27.1", - "@babel/types": "^7.27.1" + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.5", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-module-transforms": "^7.28.3", + "@babel/helpers": "^7.28.4", + "@babel/parser": "^7.28.5", + "@babel/template": "^7.27.2", + "@babel/traverse": "^7.28.5", + "@babel/types": "^7.28.5", + "@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/helpers": { - "version": "7.27.6", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.27.6.tgz", - "integrity": "sha512-muE8Tt8M22638HU31A3CgfSUciwz1fhATfoVai05aPXGor//CdWDCbnlY1yvBPo07njuVOCNGCSp/GTt12lIug==", + "node_modules/@babel/core/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 + }, + "node_modules/@babel/core/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, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.29.1", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz", + "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/template": "^7.27.2", - "@babel/types": "^7.27.6" + "@babel/parser": "^7.29.0", + "@babel/types": "^7.29.0", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/parser": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.0.tgz", - "integrity": "sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g==", + "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.28.0" - }, - "bin": { - "parser": "bin/babel-parser.js" + "@babel/types": "^7.27.3" }, "engines": { - "node": ">=6.0.0" + "node": ">=6.9.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==", + "node_modules/@babel/helper-compilation-targets": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz", + "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/traverse": "^7.27.1" + "@babel/compat-data": "^7.28.6", + "@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" - }, - "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==", + "node_modules/@babel/helper-compilation-targets/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, + "bin": { + "semver": "bin/semver.js" + } + }, + "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, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz", + "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/traverse": "^7.28.6", + "@babel/types": "^7.28.6" }, "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==", + "node_modules/@babel/helper-module-transforms": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz", + "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-module-imports": "^7.28.6", + "@babel/helper-validator-identifier": "^7.28.5", + "@babel/traverse": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -1110,2081 +1635,1863 @@ "@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==", + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", + "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", "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" + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.13.0" } }, - "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { + "node_modules/@babel/helper-string-parser": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.27.1.tgz", - "integrity": "sha512-6BpaYGDavZqkI6yT+KSPdpZFfpnd68UKXbcjI9pJ13pvHhPrCKWOOLp+ysvMeA+DxnhuPpgIaRpxRxo5A9t5jw==", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", "dev": true, - "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-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==", + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-import-assertions": { + "node_modules/@babel/helper-validator-option": { "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==", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", "dev": true, - "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.26.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.26.0.tgz", - "integrity": "sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A==", + "node_modules/@babel/helpers": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.6.tgz", + "integrity": "sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/template": "^7.28.6", + "@babel/types": "^7.28.6" }, "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==", + "node_modules/@babel/parser": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.0.tgz", + "integrity": "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/types": "^7.29.0" }, - "engines": { - "node": ">=6.9.0" + "bin": { + "parser": "bin/babel-parser.js" }, - "peerDependencies": { - "@babel/core": "^7.0.0" + "engines": { + "node": ">=6.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==", + "node_modules/@babel/template": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", + "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/code-frame": "^7.28.6", + "@babel/parser": "^7.28.6", + "@babel/types": "^7.28.6" }, "engines": { "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-async-generator-functions": { - "version": "7.26.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.26.8.tgz", - "integrity": "sha512-He9Ej2X7tNf2zdKMAGOsmg2MrFc+hfoAhd3po4cWfo/NWjzEAKa0oQruj1ROVUdl0e6fb6/kE/G3SSxE0lRJOg==", + "node_modules/@babel/traverse": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz", + "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.26.5", - "@babel/helper-remap-async-to-generator": "^7.25.9", - "@babel/traverse": "^7.26.8" + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/types": "^7.29.0", + "debug": "^4.3.1" }, "engines": { "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-async-to-generator": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.25.9.tgz", - "integrity": "sha512-NT7Ejn7Z/LjUH0Gv5KsBCxh7BH3fbLTV0ptHvpeMvrt3cPThHfJfst9Wrb7S8EvJ7vRTFI7z+VAvFVEQn/m5zQ==", + "node_modules/@babel/types": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", + "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-module-imports": "^7.25.9", - "@babel/helper-plugin-utils": "^7.25.9", - "@babel/helper-remap-async-to-generator": "^7.25.9" + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" }, "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==", + "node_modules/@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=0.1.90" } }, - "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.0.tgz", - "integrity": "sha512-gKKnwjpdx5sER/wl0WN0efUBFzF/56YZO0RJrSYP4CljXnP31ByY7fol89AzomdlLNzI36AvOTmYHsnZTCkq8Q==", + "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 + }, + "node_modules/@emnapi/core": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.8.1.tgz", + "integrity": "sha512-AvT9QFpxK0Zd8J0jopedNm+w/2fIzvtPKPjqyw9jwvBaReTTqPBk9Hixaz7KbjimP+QNz605/XnjFcDAL2pqBg==", "dev": true, + "license": "MIT", + "optional": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@emnapi/wasi-threads": "1.1.0", + "tslib": "^2.4.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==", + "node_modules/@emnapi/runtime": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.8.1.tgz", + "integrity": "sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==", "dev": true, + "license": "MIT", + "optional": true, "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" + "tslib": "^2.4.0" } }, - "node_modules/@babel/plugin-transform-class-static-block": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.27.1.tgz", - "integrity": "sha512-s734HmYU78MVzZ++joYM+NkJusItbdRcbm+AGRgJCt3iA+yux0QpD9cBVdz3tKyrjVYWRl7j0mHSmv4lhV0aoA==", + "node_modules/@emnapi/wasi-threads": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.1.0.tgz", + "integrity": "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==", "dev": true, + "license": "MIT", + "optional": true, "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.12.0" + "tslib": "^2.4.0" } }, - "node_modules/@babel/plugin-transform-classes": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.0.tgz", - "integrity": "sha512-IjM1IoJNw72AZFlj33Cu8X0q2XK/6AaVC3jQu+cgQ5lThWD5ajnuUAml80dqRmOhmPkTH8uAwnpMu9Rvj0LTRA==", + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", + "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", "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.0" + "eslint-visitor-keys": "^3.4.3" }, "engines": { - "node": ">=6.9.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, - "node_modules/@babel/plugin-transform-classes/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==", + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", "dev": true, - "dependencies": { - "@babel/types": "^7.27.3" - }, + "license": "MIT", "engines": { - "node": ">=6.9.0" + "node": "^12.0.0 || ^14.0.0 || >=16.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==", + "node_modules/@eslint/config-array": { + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz", + "integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/template": "^7.27.1" + "@eslint/object-schema": "^2.1.7", + "debug": "^4.3.1", + "minimatch": "^3.1.2" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.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==", + "node_modules/@eslint/config-helpers": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", + "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/traverse": "^7.28.0" + "@eslint/core": "^0.17.0" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.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==", + "node_modules/@eslint/core": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", + "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" + "@types/json-schema": "^7.0.15" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.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==", + "node_modules/@eslint/eslintrc": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.3.tgz", + "integrity": "sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "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.1", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" }, "engines": { - "node": ">=6.9.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "funding": { + "url": "https://opencollective.com/eslint" } }, - "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==", + "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": { - "@babel/helper-create-regexp-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "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==", + "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, - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, + "license": "MIT", "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">= 4" } }, - "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==", + "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, - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, + "license": "MIT" + }, + "node_modules/@eslint/js": { + "version": "9.39.2", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.2.tgz", + "integrity": "sha512-q1mjIoW1VX4IvSocvM/vbTiveKC4k9eLrajNEuSsmjymSDEbpGddtpfOoN7YGAqBK3NG+uqo8ia4PDTt8buCYA==", + "dev": true, + "license": "MIT", "engines": { - "node": ">=6.9.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "funding": { + "url": "https://eslint.org/donate" } }, - "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==", + "node_modules/@eslint/object-schema": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", + "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, + "license": "Apache-2.0", "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.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==", + "node_modules/@eslint/plugin-kit": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", + "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + "@eslint/core": "^0.17.0", + "levn": "^0.4.1" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.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==", + "node_modules/@hono/node-server": { + "version": "1.19.9", + "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.9.tgz", + "integrity": "sha512-vHL6w3ecZsky+8P5MD+eFfaGTyCeOHUIFYMGpQGbrBTSmNNoxv0if69rEZ5giu36weC5saFuznL411gRX7bJDw==", "dev": true, - "dependencies": { - "@babel/helper-compilation-targets": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/traverse": "^7.27.1" - }, + "license": "MIT", "engines": { - "node": ">=6.9.0" + "node": ">=18.14.1" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "hono": "^4" } }, - "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==", + "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, - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, + "license": "Apache-2.0", "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=18.18.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==", + "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": { - "@babel/helper-plugin-utils": "^7.27.1" + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.4.0" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=18.18.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==", + "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, - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, + "license": "Apache-2.0", "engines": { - "node": ">=6.9.0" + "node": ">=12.22" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" } }, - "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==", + "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, - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, + "license": "Apache-2.0", "engines": { - "node": ">=6.9.0" + "node": ">=18.18" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" } }, - "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==", + "node_modules/@inquirer/ansi": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/ansi/-/ansi-1.0.2.tgz", + "integrity": "sha512-S8qNSZiYzFd0wAcyG5AXCvUHC5Sr7xpZ9wZ2py9XR88jUz8wooStVx5M6dRzczbBWjic9NP7+rY0Xi7qqK/aMQ==", "dev": true, - "dependencies": { - "@babel/helper-module-transforms": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, + "license": "MIT", "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=18" } }, - "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==", + "node_modules/@inquirer/checkbox": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-4.3.2.tgz", + "integrity": "sha512-VXukHf0RR1doGe6Sm4F0Em7SWYLTHSsbGfJdS9Ja2bX5/D5uwVOEjr07cncLROdBvmnvCATYEWlHqYmXv2IlQA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-module-transforms": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" + "@inquirer/ansi": "^1.0.2", + "@inquirer/core": "^10.3.2", + "@inquirer/figures": "^1.0.15", + "@inquirer/type": "^3.0.10", + "yoctocolors-cjs": "^2.1.3" }, "engines": { - "node": ">=6.9.0" + "node": ">=18" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "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==", + "node_modules/@inquirer/confirm": { + "version": "5.1.21", + "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-5.1.21.tgz", + "integrity": "sha512-KR8edRkIsUayMXV+o3Gv+q4jlhENF9nMYUZs9PA2HzrXeHI8M5uDag70U7RJn9yyiMZSbtF5/UexBtAVtZGSbQ==", "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" + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10" }, "engines": { - "node": ">=6.9.0" + "node": ">=18" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "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==", + "node_modules/@inquirer/core": { + "version": "10.3.2", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.3.2.tgz", + "integrity": "sha512-43RTuEbfP8MbKzedNqBrlhhNKVwoK//vUFNW3Q3vZ88BLcrs4kYpGg+B2mm5p2K/HfygoCxuKwJJiv8PbGmE0A==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-module-transforms": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" + "@inquirer/ansi": "^1.0.2", + "@inquirer/figures": "^1.0.15", + "@inquirer/type": "^3.0.10", + "cli-width": "^4.1.0", + "mute-stream": "^2.0.0", + "signal-exit": "^4.1.0", + "wrap-ansi": "^6.2.0", + "yoctocolors-cjs": "^2.1.3" }, "engines": { - "node": ">=6.9.0" + "node": ">=18" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "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==", + "node_modules/@inquirer/editor": { + "version": "4.2.23", + "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-4.2.23.tgz", + "integrity": "sha512-aLSROkEwirotxZ1pBaP8tugXRFCxW94gwrQLxXfrZsKkfjOYC1aRvAZuhpJOb5cu4IBTJdsCigUlf2iCOu4ZDQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" + "@inquirer/core": "^10.3.2", + "@inquirer/external-editor": "^1.0.3", + "@inquirer/type": "^3.0.10" }, "engines": { - "node": ">=6.9.0" + "node": ">=18" }, "peerDependencies": { - "@babel/core": "^7.0.0" + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "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==", + "node_modules/@inquirer/expand": { + "version": "4.0.23", + "resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-4.0.23.tgz", + "integrity": "sha512-nRzdOyFYnpeYTTR2qFwEVmIWypzdAx/sIkCMeTNTcflFOovfqUk+HcFhQQVBftAh9gmGrpFj6QcGEqrDMDOiew==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10", + "yoctocolors-cjs": "^2.1.3" }, "engines": { - "node": ">=6.9.0" + "node": ">=18" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "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==", + "node_modules/@inquirer/external-editor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@inquirer/external-editor/-/external-editor-1.0.3.tgz", + "integrity": "sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "chardet": "^2.1.1", + "iconv-lite": "^0.7.0" }, "engines": { - "node": ">=6.9.0" + "node": ">=18" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "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==", + "node_modules/@inquirer/external-editor/node_modules/iconv-lite": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz", + "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "safer-buffer": ">= 2.1.2 < 3.0.0" }, "engines": { - "node": ">=6.9.0" + "node": ">=0.10.0" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/@babel/plugin-transform-object-rest-spread": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.28.0.tgz", - "integrity": "sha512-9VNGikXxzu5eCiQjdE4IZn8sb9q7Xsk5EXLDBKUYg1e/Tve8/05+KJEtcxGxAgCY5t/BpKQM+JEL/yT4tvgiUA==", + "node_modules/@inquirer/figures": { + "version": "1.0.15", + "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.15.tgz", + "integrity": "sha512-t2IEY+unGHOzAaVM5Xx6DEWKeXlDDcNPeDyUpsRc6CUhBfU3VQOEl+Vssh7VNp1dR8MdUJBWhuObjXCsVpjN5g==", "dev": true, - "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.0" - }, + "license": "MIT", "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=18" } }, - "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==", + "node_modules/@inquirer/input": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@inquirer/input/-/input-4.3.1.tgz", + "integrity": "sha512-kN0pAM4yPrLjJ1XJBjDxyfDduXOuQHrBB8aLDMueuwUGn+vNpF7Gq7TvyVxx8u4SHlFFj4trmj+a2cbpG4Jn1g==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-replace-supers": "^7.27.1" + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10" }, "engines": { - "node": ">=6.9.0" + "node": ">=18" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "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==", + "node_modules/@inquirer/number": { + "version": "3.0.23", + "resolved": "https://registry.npmjs.org/@inquirer/number/-/number-3.0.23.tgz", + "integrity": "sha512-5Smv0OK7K0KUzUfYUXDXQc9jrf8OHo4ktlEayFlelCjwMXz0299Y8OrI+lj7i4gCBY15UObk76q0QtxjzFcFcg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10" }, "engines": { - "node": ">=6.9.0" + "node": ">=18" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "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==", + "node_modules/@inquirer/password": { + "version": "4.0.23", + "resolved": "https://registry.npmjs.org/@inquirer/password/-/password-4.0.23.tgz", + "integrity": "sha512-zREJHjhT5vJBMZX/IUbyI9zVtVfOLiTO66MrF/3GFZYZ7T4YILW5MSkEYHceSii/KtRk+4i3RE7E1CUXA2jHcA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + "@inquirer/ansi": "^1.0.2", + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10" }, "engines": { - "node": ">=6.9.0" + "node": ">=18" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "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==", + "node_modules/@inquirer/prompts": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-7.10.1.tgz", + "integrity": "sha512-Dx/y9bCQcXLI5ooQ5KyvA4FTgeo2jYj/7plWfV5Ak5wDPKQZgudKez2ixyfz7tKXzcJciTxqLeK7R9HItwiByg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@inquirer/checkbox": "^4.3.2", + "@inquirer/confirm": "^5.1.21", + "@inquirer/editor": "^4.2.23", + "@inquirer/expand": "^4.0.23", + "@inquirer/input": "^4.3.1", + "@inquirer/number": "^3.0.23", + "@inquirer/password": "^4.0.23", + "@inquirer/rawlist": "^4.1.11", + "@inquirer/search": "^3.2.2", + "@inquirer/select": "^4.4.2" }, "engines": { - "node": ">=6.9.0" + "node": ">=18" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "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==", + "node_modules/@inquirer/rawlist": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-4.1.11.tgz", + "integrity": "sha512-+LLQB8XGr3I5LZN/GuAHo+GpDJegQwuPARLChlMICNdwW7OwV2izlCSCxN6cqpL0sMXmbKbFcItJgdQq5EBXTw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10", + "yoctocolors-cjs": "^2.1.3" }, "engines": { - "node": ">=6.9.0" + "node": ">=18" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "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==", + "node_modules/@inquirer/search": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@inquirer/search/-/search-3.2.2.tgz", + "integrity": "sha512-p2bvRfENXCZdWF/U2BXvnSI9h+tuA8iNqtUKb9UWbmLYCRQxd8WkvwWvYn+3NgYaNwdUkHytJMGG4MMLucI1kA==", "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" + "@inquirer/core": "^10.3.2", + "@inquirer/figures": "^1.0.15", + "@inquirer/type": "^3.0.10", + "yoctocolors-cjs": "^2.1.3" }, "engines": { - "node": ">=6.9.0" + "node": ">=18" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-private-property-in-object/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, - "dependencies": { - "@babel/types": "^7.27.3" + "@types/node": ">=18" }, - "engines": { - "node": ">=6.9.0" + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "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==", + "node_modules/@inquirer/select": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-4.4.2.tgz", + "integrity": "sha512-l4xMuJo55MAe+N7Qr4rX90vypFwCajSakx59qe/tMaC1aEHWLyw68wF4o0A4SLAY4E0nd+Vt+EyskeDIqu1M6w==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@inquirer/ansi": "^1.0.2", + "@inquirer/core": "^10.3.2", + "@inquirer/figures": "^1.0.15", + "@inquirer/type": "^3.0.10", + "yoctocolors-cjs": "^2.1.3" }, "engines": { - "node": ">=6.9.0" + "node": ">=18" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.28.0.tgz", - "integrity": "sha512-LOAozRVbqxEVjSKfhGnuLoE4Kz4Oc5UJzuvFUhSsQzdCdaAQu06mG8zDv2GFSerM62nImUZ7K92vxnQcLSDlCQ==", + "node_modules/@inquirer/type": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.10.tgz", + "integrity": "sha512-BvziSRxfz5Ov8ch0z/n3oijRSEcEsHnhggm4xFZe93DHcUCTlutlq9Ox4SVENAfcRD22UQq7T/atg9Wr3k09eA==", "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, + "license": "MIT", "engines": { - "node": ">=6.9.0" + "node": ">=18" }, "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, - "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" + "@types/node": ">=18" }, - "peerDependencies": { - "@babel/core": "^7.0.0" + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "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==", + "node_modules/@isaacs/cliui": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-9.0.0.tgz", + "integrity": "sha512-AokJm4tuBHillT+FpMtxQ60n8ObyXBatq7jD2/JA9dxbDDokKQm8KMht5ibGzLVU9IJDIKK4TPKgMHEYMn3lMg==", "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, + "license": "BlueOak-1.0.0", "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=18" } }, - "node_modules/@babel/plugin-transform-runtime": { - "version": "7.26.10", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.26.10.tgz", - "integrity": "sha512-NWaL2qG6HRpONTnj4JvDU6th4jYeZOJgu3QhmFTCihib0ermtOJqktA5BduGm3suhhVe9EMP9c9+mfJ/I9slqw==", + "node_modules/@isaacs/fs-minipass": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", + "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", "dev": true, + "license": "ISC", "dependencies": { - "@babel/helper-module-imports": "^7.25.9", - "@babel/helper-plugin-utils": "^7.26.5", - "babel-plugin-polyfill-corejs2": "^0.4.10", - "babel-plugin-polyfill-corejs3": "^0.11.0", - "babel-plugin-polyfill-regenerator": "^0.6.1", - "semver": "^6.3.1" + "minipass": "^7.0.4" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-runtime/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, - "bin": { - "semver": "bin/semver.js" + "node": ">=18.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==", + "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, - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=8" } }, - "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==", + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.12", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.12.tgz", + "integrity": "sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==", "dev": true, "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" + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" } }, - "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==", + "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": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" } }, - "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==", + "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, - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=6.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==", + "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, - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } + "license": "MIT" }, - "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==", + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.29", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.29.tgz", + "integrity": "sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "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==", + "node_modules/@listr2/prompt-adapter-inquirer": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@listr2/prompt-adapter-inquirer/-/prompt-adapter-inquirer-3.0.5.tgz", + "integrity": "sha512-WELs+hj6xcilkloBXYf9XXK8tYEnKsgLj01Xl5ONUJpKjmT5hGVUzNUS5tooUxs7pGMrw+jFD/41WpqW4V3LDA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" + "@inquirer/type": "^3.0.8" }, "engines": { - "node": ">=6.9.0" + "node": ">=20.0.0" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@inquirer/prompts": ">= 3 < 8", + "listr2": "9.0.5" } }, - "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==", + "node_modules/@lmdb/lmdb-darwin-arm64": { + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-arm64/-/lmdb-darwin-arm64-3.4.4.tgz", + "integrity": "sha512-XaKL705gDWd6XVls3ATDj13ZdML/LqSIxwgnYpG8xTzH2ifArx8fMMDdvqGE/Emd+W6R90W2fveZcJ0AyS8Y0w==", + "cpu": [ + "arm64" + ], "dev": true, - "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" - } + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] }, - "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==", + "node_modules/@lmdb/lmdb-darwin-x64": { + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-x64/-/lmdb-darwin-x64-3.4.4.tgz", + "integrity": "sha512-GPHGEVcwJlkD01GmIr7B4kvbIcUDS2+kBadVEd7lU4can1RZaZQLDDBJRrrNfS2Kavvl0VLI/cMv7UASAXGrww==", + "cpu": [ + "x64" + ], "dev": true, - "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.26.9", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.26.9.tgz", - "integrity": "sha512-vX3qPGE8sEKEAZCWk05k3cpTAE3/nOYca++JA+Rd0z2NCNzabmYvEiSShKzm10zdquOIAVXsy2Ei/DTW34KlKQ==", - "dev": true, - "dependencies": { - "@babel/compat-data": "^7.26.8", - "@babel/helper-compilation-targets": "^7.26.5", - "@babel/helper-plugin-utils": "^7.26.5", - "@babel/helper-validator-option": "^7.25.9", - "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.25.9", - "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.25.9", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.25.9", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.25.9", - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.25.9", - "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", - "@babel/plugin-syntax-import-assertions": "^7.26.0", - "@babel/plugin-syntax-import-attributes": "^7.26.0", - "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", - "@babel/plugin-transform-arrow-functions": "^7.25.9", - "@babel/plugin-transform-async-generator-functions": "^7.26.8", - "@babel/plugin-transform-async-to-generator": "^7.25.9", - "@babel/plugin-transform-block-scoped-functions": "^7.26.5", - "@babel/plugin-transform-block-scoping": "^7.25.9", - "@babel/plugin-transform-class-properties": "^7.25.9", - "@babel/plugin-transform-class-static-block": "^7.26.0", - "@babel/plugin-transform-classes": "^7.25.9", - "@babel/plugin-transform-computed-properties": "^7.25.9", - "@babel/plugin-transform-destructuring": "^7.25.9", - "@babel/plugin-transform-dotall-regex": "^7.25.9", - "@babel/plugin-transform-duplicate-keys": "^7.25.9", - "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.25.9", - "@babel/plugin-transform-dynamic-import": "^7.25.9", - "@babel/plugin-transform-exponentiation-operator": "^7.26.3", - "@babel/plugin-transform-export-namespace-from": "^7.25.9", - "@babel/plugin-transform-for-of": "^7.26.9", - "@babel/plugin-transform-function-name": "^7.25.9", - "@babel/plugin-transform-json-strings": "^7.25.9", - "@babel/plugin-transform-literals": "^7.25.9", - "@babel/plugin-transform-logical-assignment-operators": "^7.25.9", - "@babel/plugin-transform-member-expression-literals": "^7.25.9", - "@babel/plugin-transform-modules-amd": "^7.25.9", - "@babel/plugin-transform-modules-commonjs": "^7.26.3", - "@babel/plugin-transform-modules-systemjs": "^7.25.9", - "@babel/plugin-transform-modules-umd": "^7.25.9", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.25.9", - "@babel/plugin-transform-new-target": "^7.25.9", - "@babel/plugin-transform-nullish-coalescing-operator": "^7.26.6", - "@babel/plugin-transform-numeric-separator": "^7.25.9", - "@babel/plugin-transform-object-rest-spread": "^7.25.9", - "@babel/plugin-transform-object-super": "^7.25.9", - "@babel/plugin-transform-optional-catch-binding": "^7.25.9", - "@babel/plugin-transform-optional-chaining": "^7.25.9", - "@babel/plugin-transform-parameters": "^7.25.9", - "@babel/plugin-transform-private-methods": "^7.25.9", - "@babel/plugin-transform-private-property-in-object": "^7.25.9", - "@babel/plugin-transform-property-literals": "^7.25.9", - "@babel/plugin-transform-regenerator": "^7.25.9", - "@babel/plugin-transform-regexp-modifiers": "^7.26.0", - "@babel/plugin-transform-reserved-words": "^7.25.9", - "@babel/plugin-transform-shorthand-properties": "^7.25.9", - "@babel/plugin-transform-spread": "^7.25.9", - "@babel/plugin-transform-sticky-regex": "^7.25.9", - "@babel/plugin-transform-template-literals": "^7.26.8", - "@babel/plugin-transform-typeof-symbol": "^7.26.7", - "@babel/plugin-transform-unicode-escapes": "^7.25.9", - "@babel/plugin-transform-unicode-property-regex": "^7.25.9", - "@babel/plugin-transform-unicode-regex": "^7.25.9", - "@babel/plugin-transform-unicode-sets-regex": "^7.25.9", - "@babel/preset-modules": "0.1.6-no-external-plugins", - "babel-plugin-polyfill-corejs2": "^0.4.10", - "babel-plugin-polyfill-corejs3": "^0.11.0", - "babel-plugin-polyfill-regenerator": "^0.6.1", - "core-js-compat": "^3.40.0", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] }, - "node_modules/@babel/preset-env/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "node_modules/@lmdb/lmdb-linux-arm": { + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm/-/lmdb-linux-arm-3.4.4.tgz", + "integrity": "sha512-cmev5/dZr5ACKri9f6GU6lZCXTjMhV72xujlbOhFCgFXrt4W0TxGsmY8kA1BITvH60JBKE50cSxsiulybAbrrw==", + "cpu": [ + "arm" + ], "dev": true, - "bin": { - "semver": "bin/semver.js" - } + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "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==", + "node_modules/@lmdb/lmdb-linux-arm64": { + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm64/-/lmdb-linux-arm64-3.4.4.tgz", + "integrity": "sha512-mALqr7DE42HsiwVTKpQWxacjHoJk+e9p00RWIJqTACh/hpucxp/0lK/XMh5XzWnU/TDCZLukq1+vNqnNumTP/Q==", + "cpu": [ + "arm64" + ], "dev": true, - "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" - } + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@babel/runtime": { - "version": "7.26.10", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.10.tgz", - "integrity": "sha512-2WJMeRQPHKSPemqk/awGrAiuFfzBmOIPXKizAsVhWH9YJqLZ0H+HS4c8loHGgW6utJ3E/ejXQUsiGaQy2NZ9Fw==", + "node_modules/@lmdb/lmdb-linux-x64": { + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-x64/-/lmdb-linux-x64-3.4.4.tgz", + "integrity": "sha512-QjLs8OcmCNcraAcLoZyFlo0atzBJniQLLwhtR+ymQqS5kLYpV5RqwriL87BW+ZiR9ZiGgZx3evrz5vnWPtJ1fQ==", + "cpu": [ + "x64" + ], "dev": true, - "dependencies": { - "regenerator-runtime": "^0.14.0" - }, - "engines": { - "node": ">=6.9.0" - } + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "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==", + "node_modules/@lmdb/lmdb-win32-arm64": { + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-win32-arm64/-/lmdb-win32-arm64-3.4.4.tgz", + "integrity": "sha512-tr/pwHDlZ33forLGAr0tI04cRmP4SgF93yHbb+2zvZiDEyln5yMHhbKDySxY66aUOkhvBvTuHq9q/3YmTj6ZHQ==", + "cpu": [ + "arm64" + ], "dev": true, - "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/parser": "^7.27.2", - "@babel/types": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - } + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] }, - "node_modules/@babel/traverse": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.0.tgz", - "integrity": "sha512-mGe7UK5wWyh0bKRfupsUchrQGqvDbZDbKJw+kcRGSmdHVYrv+ltd0pnpDTVpiTqnaBru9iEvA8pz8W46v0Amwg==", + "node_modules/@lmdb/lmdb-win32-x64": { + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-win32-x64/-/lmdb-win32-x64-3.4.4.tgz", + "integrity": "sha512-KRzfocJzB/mgoTCqnMawuLSKheHRVTqWfSmouIgYpFs6Hx4zvZSvsZKSCEb5gHmICy7qsx9l06jk3MFTtiFVAQ==", + "cpu": [ + "x64" + ], "dev": true, - "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.28.0", - "@babel/helper-globals": "^7.28.0", - "@babel/parser": "^7.28.0", - "@babel/template": "^7.27.2", - "@babel/types": "^7.28.0", - "debug": "^4.3.1" + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@modelcontextprotocol/sdk": { + "version": "1.26.0", + "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.26.0.tgz", + "integrity": "sha512-Y5RmPncpiDtTXDbLKswIJzTqu2hyBKxTNsgKqKclDbhIgg1wgtf1fRuvxgTnRfcnxtvvgbIEcqUOzZrJ6iSReg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@hono/node-server": "^1.19.9", + "ajv": "^8.17.1", + "ajv-formats": "^3.0.1", + "content-type": "^1.0.5", + "cors": "^2.8.5", + "cross-spawn": "^7.0.5", + "eventsource": "^3.0.2", + "eventsource-parser": "^3.0.0", + "express": "^5.2.1", + "express-rate-limit": "^8.2.1", + "hono": "^4.11.4", + "jose": "^6.1.3", + "json-schema-typed": "^8.0.2", + "pkce-challenge": "^5.0.0", + "raw-body": "^3.0.0", + "zod": "^3.25 || ^4.0", + "zod-to-json-schema": "^3.25.1" }, "engines": { - "node": ">=6.9.0" + "node": ">=18" + }, + "peerDependencies": { + "@cfworker/json-schema": "^4.1.1", + "zod": "^3.25 || ^4.0" + }, + "peerDependenciesMeta": { + "@cfworker/json-schema": { + "optional": true + }, + "zod": { + "optional": false + } } }, - "node_modules/@babel/traverse/node_modules/@babel/generator": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.0.tgz", - "integrity": "sha512-lJjzvrbEeWrhB4P3QBsH7tey117PjLZnDbLiQEKjQ/fNJTjuq4HSqgFA+UNSwZT8D7dxxbnuSBMsa1lrWzKlQg==", + "node_modules/@modelcontextprotocol/sdk/node_modules/iconv-lite": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz", + "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/parser": "^7.28.0", - "@babel/types": "^7.28.0", - "@jridgewell/gen-mapping": "^0.3.12", - "@jridgewell/trace-mapping": "^0.3.28", - "jsesc": "^3.0.2" + "safer-buffer": ">= 2.1.2 < 3.0.0" }, "engines": { - "node": ">=6.9.0" + "node": ">=0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/@babel/types": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.0.tgz", - "integrity": "sha512-jYnje+JyZG5YThjHiF28oT4SIZLnYOcSBb6+SDaFIyzDVSkXQmQQYclJ2R+YxcdmK0AX6x1E5OQNtuh3jHDrUg==", + "node_modules/@modelcontextprotocol/sdk/node_modules/raw-body": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz", + "integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1" + "bytes": "~3.1.2", + "http-errors": "~2.0.1", + "iconv-lite": "~0.7.0", + "unpipe": "~1.0.0" }, "engines": { - "node": ">=6.9.0" + "node": ">= 0.10" } }, - "node_modules/@colors/colors": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", - "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", - "dev": true, - "engines": { - "node": ">=0.1.90" - } - }, - "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 - }, - "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==", + "node_modules/@msgpackr-extract/msgpackr-extract-darwin-arm64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-3.0.3.tgz", + "integrity": "sha512-QZHtlVgbAdy2zAqNA9Gu1UpIuI8Xvsd1v8ic6B2pZmeFnFcMWiPLfWXh7TVw4eGEZ/C9TH281KwhVoeQUKbyjw==", + "cpu": [ + "arm64" + ], "dev": true, - "engines": { - "node": ">=14.17.0" - } + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.4.tgz", - "integrity": "sha512-1VCICWypeQKhVbE9oW/sJaAmjLxhVqacdkvPLEjwlttjfwENRSClS8EjBz0KzRyFSCPDIkuXW34Je/vk7zdB7Q==", + "node_modules/@msgpackr-extract/msgpackr-extract-darwin-x64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-x64/-/msgpackr-extract-darwin-x64-3.0.3.tgz", + "integrity": "sha512-mdzd3AVzYKuUmiWOQ8GNhl64/IoFGol569zNRdkLReh6LRLHOXxU4U8eq0JwaD8iFHdVGqSy4IjFL4reoWCDFw==", "cpu": [ - "ppc64" + "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ - "aix" - ], - "engines": { - "node": ">=18" - } + "darwin" + ] }, - "node_modules/@esbuild/android-arm": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.4.tgz", - "integrity": "sha512-QNdQEps7DfFwE3hXiU4BZeOV68HHzYwGd0Nthhd3uCkkEKK7/R6MTgM0P7H7FAs5pU/DIWsviMmEGxEoxIZ+ZQ==", + "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm/-/msgpackr-extract-linux-arm-3.0.3.tgz", + "integrity": "sha512-fg0uy/dG/nZEXfYilKoRe7yALaNmHoYeIoJuJ7KJ+YyU2bvY8vPv27f7UKhGRpY6euFYqEVhxCFZgAUNQBM3nw==", "cpu": [ "arm" ], "dev": true, + "license": "MIT", "optional": true, "os": [ - "android" - ], - "engines": { - "node": ">=18" - } + "linux" + ] }, - "node_modules/@esbuild/android-arm64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.4.tgz", - "integrity": "sha512-bBy69pgfhMGtCnwpC/x5QhfxAz/cBgQ9enbtwjf6V9lnPI/hMyT9iWpR1arm0l3kttTr4L0KSLpKmLp/ilKS9A==", + "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm64/-/msgpackr-extract-linux-arm64-3.0.3.tgz", + "integrity": "sha512-YxQL+ax0XqBJDZiKimS2XQaf+2wDGVa1enVRGzEvLLVFeqa5kx2bWbtcSXgsxjQB7nRqqIGFIcLteF/sHeVtQg==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ - "android" - ], - "engines": { - "node": ">=18" - } + "linux" + ] }, - "node_modules/@esbuild/android-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.4.tgz", - "integrity": "sha512-TVhdVtQIFuVpIIR282btcGC2oGQoSfZfmBdTip2anCaVYcqWlZXGcdcKIUklfX2wj0JklNYgz39OBqh2cqXvcQ==", + "node_modules/@msgpackr-extract/msgpackr-extract-linux-x64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-x64/-/msgpackr-extract-linux-x64-3.0.3.tgz", + "integrity": "sha512-cvwNfbP07pKUfq1uH+S6KJ7dT9K8WOE4ZiAcsrSes+UY55E/0jLYc+vq+DO7jlmqRb5zAggExKm0H7O/CBaesg==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ - "android" - ], - "engines": { - "node": ">=18" - } + "linux" + ] }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.4.tgz", - "integrity": "sha512-Y1giCfM4nlHDWEfSckMzeWNdQS31BQGs9/rouw6Ub91tkK79aIMTH3q9xHvzH8d0wDru5Ci0kWB8b3up/nl16g==", + "node_modules/@msgpackr-extract/msgpackr-extract-win32-x64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-3.0.3.tgz", + "integrity": "sha512-x0fWaQtYp4E6sktbsdAqnehxDgEc/VwM7uLsRCYWaiGu0ykYdZPiS8zCWdnjHwyiumousxfBm4SO31eXqwEZhQ==", "cpu": [ - "arm64" + "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ - "darwin" - ], + "win32" + ] + }, + "node_modules/@napi-rs/nice": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice/-/nice-1.1.1.tgz", + "integrity": "sha512-xJIPs+bYuc9ASBl+cvGsKbGrJmS6fAKaSZCnT0lhahT5rhA2VVy9/EcIgd2JhtEuFOJNx7UHNn/qiTPTY4nrQw==", + "dev": true, + "license": "MIT", + "optional": true, "engines": { - "node": ">=18" + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "optionalDependencies": { + "@napi-rs/nice-android-arm-eabi": "1.1.1", + "@napi-rs/nice-android-arm64": "1.1.1", + "@napi-rs/nice-darwin-arm64": "1.1.1", + "@napi-rs/nice-darwin-x64": "1.1.1", + "@napi-rs/nice-freebsd-x64": "1.1.1", + "@napi-rs/nice-linux-arm-gnueabihf": "1.1.1", + "@napi-rs/nice-linux-arm64-gnu": "1.1.1", + "@napi-rs/nice-linux-arm64-musl": "1.1.1", + "@napi-rs/nice-linux-ppc64-gnu": "1.1.1", + "@napi-rs/nice-linux-riscv64-gnu": "1.1.1", + "@napi-rs/nice-linux-s390x-gnu": "1.1.1", + "@napi-rs/nice-linux-x64-gnu": "1.1.1", + "@napi-rs/nice-linux-x64-musl": "1.1.1", + "@napi-rs/nice-openharmony-arm64": "1.1.1", + "@napi-rs/nice-win32-arm64-msvc": "1.1.1", + "@napi-rs/nice-win32-ia32-msvc": "1.1.1", + "@napi-rs/nice-win32-x64-msvc": "1.1.1" } }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.4.tgz", - "integrity": "sha512-CJsry8ZGM5VFVeyUYB3cdKpd/H69PYez4eJh1W/t38vzutdjEjtP7hB6eLKBoOdxcAlCtEYHzQ/PJ/oU9I4u0A==", + "node_modules/@napi-rs/nice-android-arm-eabi": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-android-arm-eabi/-/nice-android-arm-eabi-1.1.1.tgz", + "integrity": "sha512-kjirL3N6TnRPv5iuHw36wnucNqXAO46dzK9oPb0wj076R5Xm8PfUVA9nAFB5ZNMmfJQJVKACAPd/Z2KYMppthw==", "cpu": [ - "x64" + "arm" ], "dev": true, + "license": "MIT", "optional": true, "os": [ - "darwin" + "android" ], "engines": { - "node": ">=18" + "node": ">= 10" } }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.4.tgz", - "integrity": "sha512-yYq+39NlTRzU2XmoPW4l5Ifpl9fqSk0nAJYM/V/WUGPEFfek1epLHJIkTQM6bBs1swApjO5nWgvr843g6TjxuQ==", + "node_modules/@napi-rs/nice-android-arm64": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-android-arm64/-/nice-android-arm64-1.1.1.tgz", + "integrity": "sha512-blG0i7dXgbInN5urONoUCNf+DUEAavRffrO7fZSeoRMJc5qD+BJeNcpr54msPF6qfDD6kzs9AQJogZvT2KD5nw==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ - "freebsd" + "android" ], "engines": { - "node": ">=18" + "node": ">= 10" } }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.4.tgz", - "integrity": "sha512-0FgvOJ6UUMflsHSPLzdfDnnBBVoCDtBTVyn/MrWloUNvq/5SFmh13l3dvgRPkDihRxb77Y17MbqbCAa2strMQQ==", + "node_modules/@napi-rs/nice-darwin-arm64": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-darwin-arm64/-/nice-darwin-arm64-1.1.1.tgz", + "integrity": "sha512-s/E7w45NaLqTGuOjC2p96pct4jRfo61xb9bU1unM/MJ/RFkKlJyJDx7OJI/O0ll/hrfpqKopuAFDV8yo0hfT7A==", "cpu": [ - "x64" + "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ - "freebsd" + "darwin" ], "engines": { - "node": ">=18" + "node": ">= 10" } }, - "node_modules/@esbuild/linux-arm": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.4.tgz", - "integrity": "sha512-kro4c0P85GMfFYqW4TWOpvmF8rFShbWGnrLqlzp4X1TNWjRY3JMYUfDCtOxPKOIY8B0WC8HN51hGP4I4hz4AaQ==", + "node_modules/@napi-rs/nice-darwin-x64": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-darwin-x64/-/nice-darwin-x64-1.1.1.tgz", + "integrity": "sha512-dGoEBnVpsdcC+oHHmW1LRK5eiyzLwdgNQq3BmZIav+9/5WTZwBYX7r5ZkQC07Nxd3KHOCkgbHSh4wPkH1N1LiQ==", "cpu": [ - "arm" + "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ - "linux" + "darwin" ], "engines": { - "node": ">=18" + "node": ">= 10" } }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.4.tgz", - "integrity": "sha512-+89UsQTfXdmjIvZS6nUnOOLoXnkUTB9hR5QAeLrQdzOSWZvNSAXAtcRDHWtqAUtAmv7ZM1WPOOeSxDzzzMogiQ==", + "node_modules/@napi-rs/nice-freebsd-x64": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-freebsd-x64/-/nice-freebsd-x64-1.1.1.tgz", + "integrity": "sha512-kHv4kEHAylMYmlNwcQcDtXjklYp4FCf0b05E+0h6nDHsZ+F0bDe04U/tXNOqrx5CmIAth4vwfkjjUmp4c4JktQ==", "cpu": [ - "arm64" + "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ - "linux" + "freebsd" ], "engines": { - "node": ">=18" + "node": ">= 10" } }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.4.tgz", - "integrity": "sha512-yTEjoapy8UP3rv8dB0ip3AfMpRbyhSN3+hY8mo/i4QXFeDxmiYbEKp3ZRjBKcOP862Ua4b1PDfwlvbuwY7hIGQ==", + "node_modules/@napi-rs/nice-linux-arm-gnueabihf": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-arm-gnueabihf/-/nice-linux-arm-gnueabihf-1.1.1.tgz", + "integrity": "sha512-E1t7K0efyKXZDoZg1LzCOLxgolxV58HCkaEkEvIYQx12ht2pa8hoBo+4OB3qh7e+QiBlp1SRf+voWUZFxyhyqg==", "cpu": [ - "ia32" + "arm" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=18" + "node": ">= 10" } }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.4.tgz", - "integrity": "sha512-NeqqYkrcGzFwi6CGRGNMOjWGGSYOpqwCjS9fvaUlX5s3zwOtn1qwg1s2iE2svBe4Q/YOG1q6875lcAoQK/F4VA==", + "node_modules/@napi-rs/nice-linux-arm64-gnu": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-arm64-gnu/-/nice-linux-arm64-gnu-1.1.1.tgz", + "integrity": "sha512-CIKLA12DTIZlmTaaKhQP88R3Xao+gyJxNWEn04wZwC2wmRapNnxCUZkVwggInMJvtVElA+D4ZzOU5sX4jV+SmQ==", "cpu": [ - "loong64" + "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=18" + "node": ">= 10" } }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.4.tgz", - "integrity": "sha512-IcvTlF9dtLrfL/M8WgNI/qJYBENP3ekgsHbYUIzEzq5XJzzVEV/fXY9WFPfEEXmu3ck2qJP8LG/p3Q8f7Zc2Xg==", + "node_modules/@napi-rs/nice-linux-arm64-musl": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-arm64-musl/-/nice-linux-arm64-musl-1.1.1.tgz", + "integrity": "sha512-+2Rzdb3nTIYZ0YJF43qf2twhqOCkiSrHx2Pg6DJaCPYhhaxbLcdlV8hCRMHghQ+EtZQWGNcS2xF4KxBhSGeutg==", "cpu": [ - "mips64el" + "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=18" + "node": ">= 10" } }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.4.tgz", - "integrity": "sha512-HOy0aLTJTVtoTeGZh4HSXaO6M95qu4k5lJcH4gxv56iaycfz1S8GO/5Jh6X4Y1YiI0h7cRyLi+HixMR+88swag==", + "node_modules/@napi-rs/nice-linux-ppc64-gnu": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-ppc64-gnu/-/nice-linux-ppc64-gnu-1.1.1.tgz", + "integrity": "sha512-4FS8oc0GeHpwvv4tKciKkw3Y4jKsL7FRhaOeiPei0X9T4Jd619wHNe4xCLmN2EMgZoeGg+Q7GY7BsvwKpL22Tg==", "cpu": [ "ppc64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=18" + "node": ">= 10" } }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.4.tgz", - "integrity": "sha512-i8JUDAufpz9jOzo4yIShCTcXzS07vEgWzyX3NH2G7LEFVgrLEhjwL3ajFE4fZI3I4ZgiM7JH3GQ7ReObROvSUA==", + "node_modules/@napi-rs/nice-linux-riscv64-gnu": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-riscv64-gnu/-/nice-linux-riscv64-gnu-1.1.1.tgz", + "integrity": "sha512-HU0nw9uD4FO/oGCCk409tCi5IzIZpH2agE6nN4fqpwVlCn5BOq0MS1dXGjXaG17JaAvrlpV5ZeyZwSon10XOXw==", "cpu": [ "riscv64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=18" + "node": ">= 10" } }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.4.tgz", - "integrity": "sha512-jFnu+6UbLlzIjPQpWCNh5QtrcNfMLjgIavnwPQAfoGx4q17ocOU9MsQ2QVvFxwQoWpZT8DvTLooTvmOQXkO51g==", + "node_modules/@napi-rs/nice-linux-s390x-gnu": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-s390x-gnu/-/nice-linux-s390x-gnu-1.1.1.tgz", + "integrity": "sha512-2YqKJWWl24EwrX0DzCQgPLKQBxYDdBxOHot1KWEq7aY2uYeX+Uvtv4I8xFVVygJDgf6/92h9N3Y43WPx8+PAgQ==", "cpu": [ "s390x" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=18" + "node": ">= 10" } }, - "node_modules/@esbuild/linux-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.4.tgz", - "integrity": "sha512-6e0cvXwzOnVWJHq+mskP8DNSrKBr1bULBvnFLpc1KY+d+irZSgZ02TGse5FsafKS5jg2e4pbvK6TPXaF/A6+CA==", + "node_modules/@napi-rs/nice-linux-x64-gnu": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-x64-gnu/-/nice-linux-x64-gnu-1.1.1.tgz", + "integrity": "sha512-/gaNz3R92t+dcrfCw/96pDopcmec7oCcAQ3l/M+Zxr82KT4DljD37CpgrnXV+pJC263JkW572pdbP3hP+KjcIg==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.4.tgz", - "integrity": "sha512-vUnkBYxZW4hL/ie91hSqaSNjulOnYXE1VSLusnvHg2u3jewJBz3YzB9+oCw8DABeVqZGg94t9tyZFoHma8gWZQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" + "node": ">= 10" } }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.4.tgz", - "integrity": "sha512-XAg8pIQn5CzhOB8odIcAm42QsOfa98SBeKUdo4xa8OvX8LbMZqEtgeWE9P/Wxt7MlG2QqvjGths+nq48TrUiKw==", + "node_modules/@napi-rs/nice-linux-x64-musl": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-x64-musl/-/nice-linux-x64-musl-1.1.1.tgz", + "integrity": "sha512-xScCGnyj/oppsNPMnevsBe3pvNaoK7FGvMjT35riz9YdhB2WtTG47ZlbxtOLpjeO9SqqQ2J2igCmz6IJOD5JYw==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ - "netbsd" + "linux" ], "engines": { - "node": ">=18" + "node": ">= 10" } }, - "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.4.tgz", - "integrity": "sha512-Ct2WcFEANlFDtp1nVAXSNBPDxyU+j7+tId//iHXU2f/lN5AmO4zLyhDcpR5Cz1r08mVxzt3Jpyt4PmXQ1O6+7A==", + "node_modules/@napi-rs/nice-openharmony-arm64": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-openharmony-arm64/-/nice-openharmony-arm64-1.1.1.tgz", + "integrity": "sha512-6uJPRVwVCLDeoOaNyeiW0gp2kFIM4r7PL2MczdZQHkFi9gVlgm+Vn+V6nTWRcu856mJ2WjYJiumEajfSm7arPQ==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.4.tgz", - "integrity": "sha512-xAGGhyOQ9Otm1Xu8NT1ifGLnA6M3sJxZ6ixylb+vIUVzvvd6GOALpwQrYrtlPouMqd/vSbgehz6HaVk4+7Afhw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.4.tgz", - "integrity": "sha512-Mw+tzy4pp6wZEK0+Lwr76pWLjrtjmJyUB23tHKqEDP74R3q95luY/bXqXZeYl4NYlvwOqoRKlInQialgCKy67Q==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "sunos" + "openharmony" ], "engines": { - "node": ">=18" + "node": ">= 10" } }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.4.tgz", - "integrity": "sha512-AVUP428VQTSddguz9dO9ngb+E5aScyg7nOeJDrF1HPYu555gmza3bDGMPhmVXL8svDSoqPCsCPjb265yG/kLKQ==", + "node_modules/@napi-rs/nice-win32-arm64-msvc": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-win32-arm64-msvc/-/nice-win32-arm64-msvc-1.1.1.tgz", + "integrity": "sha512-uoTb4eAvM5B2aj/z8j+Nv8OttPf2m+HVx3UjA5jcFxASvNhQriyCQF1OB1lHL43ZhW+VwZlgvjmP5qF3+59atA==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" ], "engines": { - "node": ">=18" + "node": ">= 10" } }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.4.tgz", - "integrity": "sha512-i1sW+1i+oWvQzSgfRcxxG2k4I9n3O9NRqy8U+uugaT2Dy7kLO9Y7wI72haOahxceMX8hZAzgGou1FhndRldxRg==", + "node_modules/@napi-rs/nice-win32-ia32-msvc": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-win32-ia32-msvc/-/nice-win32-ia32-msvc-1.1.1.tgz", + "integrity": "sha512-CNQqlQT9MwuCsg1Vd/oKXiuH+TcsSPJmlAFc5frFyX/KkOh0UpBLEj7aoY656d5UKZQMQFP7vJNa1DNUNORvug==", "cpu": [ "ia32" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" ], "engines": { - "node": ">=18" + "node": ">= 10" } }, - "node_modules/@esbuild/win32-x64": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.4.tgz", - "integrity": "sha512-nOT2vZNw6hJ+z43oP1SPea/G/6AbN6X+bGNhNuq8NtRHy4wsMhw765IKLNmnjek7GvjWBYQ8Q5VBoYTFg9y1UQ==", + "node_modules/@napi-rs/nice-win32-x64-msvc": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-win32-x64-msvc/-/nice-win32-x64-msvc-1.1.1.tgz", + "integrity": "sha512-vB+4G/jBQCAh0jelMTY3+kgFy00Hlx2f2/1zjMoH821IbplbWZOkLiTYXQkygNTzQJTq5cvwBDgn2ppHD+bglQ==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" ], "engines": { - "node": ">=18" + "node": ">= 10" } }, - "node_modules/@inquirer/checkbox": { - "version": "4.1.9", - "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-4.1.9.tgz", - "integrity": "sha512-DBJBkzI5Wx4jFaYm221LHvAhpKYkhVS0k9plqHwaHhofGNxvYB7J3Bz8w+bFJ05zaMb0sZNHo4KdmENQFlNTuQ==", + "node_modules/@napi-rs/wasm-runtime": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.1.tgz", + "integrity": "sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A==", "dev": true, + "license": "MIT", + "optional": true, "dependencies": { - "@inquirer/core": "^10.1.14", - "@inquirer/figures": "^1.0.12", - "@inquirer/type": "^3.0.7", - "ansi-escapes": "^4.3.2", - "yoctocolors-cjs": "^2.1.2" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@types/node": ">=18" + "@emnapi/core": "^1.7.1", + "@emnapi/runtime": "^1.7.1", + "@tybys/wasm-util": "^0.10.1" }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" } }, - "node_modules/@inquirer/confirm": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-5.1.6.tgz", - "integrity": "sha512-6ZXYK3M1XmaVBZX6FCfChgtponnL0R6I7k8Nu+kaoNkT828FVZTcca1MqmWQipaW2oNREQl5AaPCUOOCVNdRMw==", + "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, "dependencies": { - "@inquirer/core": "^10.1.7", - "@inquirer/type": "^3.0.4" + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" }, "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } + "node": ">= 8" } }, - "node_modules/@inquirer/core": { - "version": "10.1.14", - "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.1.14.tgz", - "integrity": "sha512-Ma+ZpOJPewtIYl6HZHZckeX1STvDnHTCB2GVINNUlSEn2Am6LddWwfPkIGY0IUFVjUUrr/93XlBwTK6mfLjf0A==", + "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, - "dependencies": { - "@inquirer/figures": "^1.0.12", - "@inquirer/type": "^3.0.7", - "ansi-escapes": "^4.3.2", - "cli-width": "^4.1.0", - "mute-stream": "^2.0.0", - "signal-exit": "^4.1.0", - "wrap-ansi": "^6.2.0", - "yoctocolors-cjs": "^2.1.2" - }, "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } + "node": ">= 8" } }, - "node_modules/@inquirer/editor": { - "version": "4.2.14", - "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-4.2.14.tgz", - "integrity": "sha512-yd2qtLl4QIIax9DTMZ1ZN2pFrrj+yL3kgIWxm34SS6uwCr0sIhsNyudUjAo5q3TqI03xx4SEBkUJqZuAInp9uA==", + "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, "dependencies": { - "@inquirer/core": "^10.1.14", - "@inquirer/type": "^3.0.7", - "external-editor": "^3.1.0" + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" }, "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } + "node": ">= 8" } }, - "node_modules/@inquirer/expand": { - "version": "4.0.16", - "resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-4.0.16.tgz", - "integrity": "sha512-oiDqafWzMtofeJyyGkb1CTPaxUkjIcSxePHHQCfif8t3HV9pHcw1Kgdw3/uGpDvaFfeTluwQtWiqzPVjAqS3zA==", + "node_modules/@npmcli/agent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/agent/-/agent-4.0.0.tgz", + "integrity": "sha512-kAQTcEN9E8ERLVg5AsGwLNoFb+oEG6engbqAU2P43gD4JEIkNGMHdVQ096FsOAAYpZPB0RSt0zgInKIAS1l5QA==", "dev": true, + "license": "ISC", "dependencies": { - "@inquirer/core": "^10.1.14", - "@inquirer/type": "^3.0.7", - "yoctocolors-cjs": "^2.1.2" + "agent-base": "^7.1.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.1", + "lru-cache": "^11.2.1", + "socks-proxy-agent": "^8.0.3" }, "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/@inquirer/figures": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.12.tgz", - "integrity": "sha512-MJttijd8rMFcKJC8NYmprWr6hD3r9Gd9qUC0XwPNwoEPWSMVJwA2MlXxF+nhZZNMY+HXsWa+o7KY2emWYIn0jQ==", + "node_modules/@npmcli/agent/node_modules/lru-cache": { + "version": "11.2.6", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.6.tgz", + "integrity": "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==", "dev": true, + "license": "BlueOak-1.0.0", "engines": { - "node": ">=18" + "node": "20 || >=22" } }, - "node_modules/@inquirer/input": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@inquirer/input/-/input-4.2.0.tgz", - "integrity": "sha512-opqpHPB1NjAmDISi3uvZOTrjEEU5CWVu/HBkDby8t93+6UxYX0Z7Ps0Ltjm5sZiEbWenjubwUkivAEYQmy9xHw==", + "node_modules/@npmcli/fs": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-5.0.0.tgz", + "integrity": "sha512-7OsC1gNORBEawOa5+j2pXN9vsicaIOH5cPXxoR6fJOmH6/EXpJB2CajXOu1fPRFun2m1lktEFX11+P89hqO/og==", "dev": true, + "license": "ISC", "dependencies": { - "@inquirer/core": "^10.1.14", - "@inquirer/type": "^3.0.7" + "semver": "^7.3.5" }, "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/@inquirer/number": { - "version": "3.0.16", - "resolved": "https://registry.npmjs.org/@inquirer/number/-/number-3.0.16.tgz", - "integrity": "sha512-kMrXAaKGavBEoBYUCgualbwA9jWUx2TjMA46ek+pEKy38+LFpL9QHlTd8PO2kWPUgI/KB+qi02o4y2rwXbzr3Q==", + "node_modules/@npmcli/git": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-7.0.1.tgz", + "integrity": "sha512-+XTFxK2jJF/EJJ5SoAzXk3qwIDfvFc5/g+bD274LZ7uY7LE8sTfG6Z8rOanPl2ZEvZWqNvmEdtXC25cE54VcoA==", "dev": true, + "license": "ISC", "dependencies": { - "@inquirer/core": "^10.1.14", - "@inquirer/type": "^3.0.7" + "@npmcli/promise-spawn": "^9.0.0", + "ini": "^6.0.0", + "lru-cache": "^11.2.1", + "npm-pick-manifest": "^11.0.1", + "proc-log": "^6.0.0", + "promise-retry": "^2.0.1", + "semver": "^7.3.5", + "which": "^6.0.0" }, "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/@inquirer/password": { - "version": "4.0.16", - "resolved": "https://registry.npmjs.org/@inquirer/password/-/password-4.0.16.tgz", - "integrity": "sha512-g8BVNBj5Zeb5/Y3cSN+hDUL7CsIFDIuVxb9EPty3lkxBaYpjL5BNRKSYOF9yOLe+JOcKFd+TSVeADQ4iSY7rbg==", + "node_modules/@npmcli/git/node_modules/isexe": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-4.0.0.tgz", + "integrity": "sha512-FFUtZMpoZ8RqHS3XeXEmHWLA4thH+ZxCv2lOiPIn1Xc7CxrqhWzNSDzD+/chS/zbYezmiwWLdQC09JdQKmthOw==", "dev": true, - "dependencies": { - "@inquirer/core": "^10.1.14", - "@inquirer/type": "^3.0.7", - "ansi-escapes": "^4.3.2" - }, + "license": "BlueOak-1.0.0", "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } + "node": ">=20" } }, - "node_modules/@inquirer/prompts": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-7.3.2.tgz", - "integrity": "sha512-G1ytyOoHh5BphmEBxSwALin3n1KGNYB6yImbICcRQdzXfOGbuJ9Jske/Of5Sebk339NSGGNfUshnzK8YWkTPsQ==", + "node_modules/@npmcli/git/node_modules/lru-cache": { + "version": "11.2.6", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.6.tgz", + "integrity": "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==", "dev": true, - "dependencies": { - "@inquirer/checkbox": "^4.1.2", - "@inquirer/confirm": "^5.1.6", - "@inquirer/editor": "^4.2.7", - "@inquirer/expand": "^4.0.9", - "@inquirer/input": "^4.1.6", - "@inquirer/number": "^3.0.9", - "@inquirer/password": "^4.0.9", - "@inquirer/rawlist": "^4.0.9", - "@inquirer/search": "^3.0.9", - "@inquirer/select": "^4.0.9" - }, + "license": "BlueOak-1.0.0", "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } + "node": "20 || >=22" } }, - "node_modules/@inquirer/rawlist": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-4.1.4.tgz", - "integrity": "sha512-5GGvxVpXXMmfZNtvWw4IsHpR7RzqAR624xtkPd1NxxlV5M+pShMqzL4oRddRkg8rVEOK9fKdJp1jjVML2Lr7TQ==", + "node_modules/@npmcli/git/node_modules/which": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/which/-/which-6.0.1.tgz", + "integrity": "sha512-oGLe46MIrCRqX7ytPUf66EAYvdeMIZYn3WaocqqKZAxrBpkqHfL/qvTyJ/bTk5+AqHCjXmrv3CEWgy368zhRUg==", "dev": true, + "license": "ISC", "dependencies": { - "@inquirer/core": "^10.1.14", - "@inquirer/type": "^3.0.7", - "yoctocolors-cjs": "^2.1.2" - }, - "engines": { - "node": ">=18" + "isexe": "^4.0.0" }, - "peerDependencies": { - "@types/node": ">=18" + "bin": { + "node-which": "bin/which.js" }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/@inquirer/search": { - "version": "3.0.16", - "resolved": "https://registry.npmjs.org/@inquirer/search/-/search-3.0.16.tgz", - "integrity": "sha512-POCmXo+j97kTGU6aeRjsPyuCpQQfKcMXdeTMw708ZMtWrj5aykZvlUxH4Qgz3+Y1L/cAVZsSpA+UgZCu2GMOMg==", + "node_modules/@npmcli/installed-package-contents": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/installed-package-contents/-/installed-package-contents-4.0.0.tgz", + "integrity": "sha512-yNyAdkBxB72gtZ4GrwXCM0ZUedo9nIbOMKfGjt6Cu6DXf0p8y1PViZAKDC8q8kv/fufx0WTjRBdSlyrvnP7hmA==", "dev": true, + "license": "ISC", "dependencies": { - "@inquirer/core": "^10.1.14", - "@inquirer/figures": "^1.0.12", - "@inquirer/type": "^3.0.7", - "yoctocolors-cjs": "^2.1.2" - }, - "engines": { - "node": ">=18" + "npm-bundled": "^5.0.0", + "npm-normalize-package-bin": "^5.0.0" }, - "peerDependencies": { - "@types/node": ">=18" + "bin": { + "installed-package-contents": "bin/index.js" }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/@inquirer/select": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-4.2.4.tgz", - "integrity": "sha512-unTppUcTjmnbl/q+h8XeQDhAqIOmwWYWNyiiP2e3orXrg6tOaa5DHXja9PChCSbChOsktyKgOieRZFnajzxoBg==", + "node_modules/@npmcli/node-gyp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/node-gyp/-/node-gyp-5.0.0.tgz", + "integrity": "sha512-uuG5HZFXLfyFKqg8QypsmgLQW7smiRjVc45bqD/ofZZcR/uxEjgQU8qDPv0s9TEeMUiAAU/GC5bR6++UdTirIQ==", "dev": true, - "dependencies": { - "@inquirer/core": "^10.1.14", - "@inquirer/figures": "^1.0.12", - "@inquirer/type": "^3.0.7", - "ansi-escapes": "^4.3.2", - "yoctocolors-cjs": "^2.1.2" - }, + "license": "ISC", "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/@inquirer/type": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.7.tgz", - "integrity": "sha512-PfunHQcjwnju84L+ycmcMKB/pTPIngjUJvfnRhKY6FKPuYXlM4aQCb/nIdTFR6BEhMjFvngzvng/vBAJMZpLSA==", + "node_modules/@npmcli/package-json": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/@npmcli/package-json/-/package-json-7.0.4.tgz", + "integrity": "sha512-0wInJG3j/K40OJt/33ax47WfWMzZTm6OQxB9cDhTt5huCP2a9g2GnlsxmfN+PulItNPIpPrZ+kfwwUil7eHcZQ==", "dev": true, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@types/node": ">=18" + "license": "ISC", + "dependencies": { + "@npmcli/git": "^7.0.0", + "glob": "^13.0.0", + "hosted-git-info": "^9.0.0", + "json-parse-even-better-errors": "^5.0.0", + "proc-log": "^6.0.0", + "semver": "^7.5.3", + "validate-npm-package-license": "^3.0.4" }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "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==", + "node_modules/@npmcli/package-json/node_modules/balanced-match": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.2.tgz", + "integrity": "sha512-x0K50QvKQ97fdEz2kPehIerj+YTeptKF9hyYkKf6egnwmMWAkADiO0QCzSp0R5xN8FTZgYaBfSaue46Ej62nMg==", "dev": true, + "license": "MIT", "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" + "jackspeak": "^4.2.3" }, "engines": { - "node": ">=12" + "node": "20 || >=22" } }, - "node_modules/@isaacs/cliui/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "node_modules/@npmcli/package-json/node_modules/brace-expansion": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.2.tgz", + "integrity": "sha512-Pdk8c9poy+YhOgVWw1JNN22/HcivgKWwpxKq04M/jTmHyCZn12WPJebZxdjSa5TmBqISrUSgNYU3eRORljfCCw==", "dev": true, - "engines": { - "node": ">=12" + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "engines": { + "node": "20 || >=22" } }, - "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 - }, - "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==", + "node_modules/@npmcli/package-json/node_modules/glob": { + "version": "13.0.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.3.tgz", + "integrity": "sha512-/g3B0mC+4x724v1TgtBlBtt2hPi/EWptsIAmXUx9Z2rvBYleQcsrmaOzd5LyL50jf/Soi83ZDJmw2+XqvH/EeA==", "dev": true, + "license": "BlueOak-1.0.0", "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" + "minimatch": "^10.2.0", + "minipass": "^7.1.2", + "path-scurry": "^2.0.0" }, "engines": { - "node": ">=12" + "node": "20 || >=22" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/isaacs" } }, - "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==", + "node_modules/@npmcli/package-json/node_modules/minimatch": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.0.tgz", + "integrity": "sha512-ugkC31VaVg9cF0DFVoADH12k6061zNZkZON+aX8AWsR9GhPcErkcMBceb6znR8wLERM2AkkOxy2nWRLpT9Jq5w==", "dev": true, + "license": "BlueOak-1.0.0", "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" + "brace-expansion": "^5.0.2" }, "engines": { - "node": ">=12" + "node": "20 || >=22" }, "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@isaacs/fs-minipass": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", - "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", + "node_modules/@npmcli/promise-spawn": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-9.0.1.tgz", + "integrity": "sha512-OLUaoqBuyxeTqUvjA3FZFiXUfYC1alp3Sa99gW3EUDz3tZ3CbXDdcZ7qWKBzicrJleIgucoWamWH1saAmH/l2Q==", "dev": true, + "license": "ISC", "dependencies": { - "minipass": "^7.0.4" + "which": "^6.0.0" }, "engines": { - "node": ">=18.0.0" + "node": "^20.17.0 || >=22.9.0" } }, - "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==", + "node_modules/@npmcli/promise-spawn/node_modules/isexe": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-4.0.0.tgz", + "integrity": "sha512-FFUtZMpoZ8RqHS3XeXEmHWLA4thH+ZxCv2lOiPIn1Xc7CxrqhWzNSDzD+/chS/zbYezmiwWLdQC09JdQKmthOw==", "dev": true, + "license": "BlueOak-1.0.0", "engines": { - "node": ">=8" + "node": ">=20" } }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.12", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.12.tgz", - "integrity": "sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==", + "node_modules/@npmcli/promise-spawn/node_modules/which": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/which/-/which-6.0.1.tgz", + "integrity": "sha512-oGLe46MIrCRqX7ytPUf66EAYvdeMIZYn3WaocqqKZAxrBpkqHfL/qvTyJ/bTk5+AqHCjXmrv3CEWgy368zhRUg==", "dev": true, + "license": "ISC", "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0", - "@jridgewell/trace-mapping": "^0.3.24" + "isexe": "^4.0.0" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "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==", + "node_modules/@npmcli/redact": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/redact/-/redact-4.0.0.tgz", + "integrity": "sha512-gOBg5YHMfZy+TfHArfVogwgfBeQnKbbGo3pSUyK/gSI0AVu+pEiDVcKlQb0D8Mg1LNRZILZ6XG8I5dJ4KuAd9Q==", "dev": true, + "license": "ISC", "engines": { - "node": ">=6.0.0" + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/@jridgewell/source-map": { - "version": "0.3.10", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.10.tgz", - "integrity": "sha512-0pPkgz9dY+bijgistcTTJ5mR+ocqRXLuhXHYdzoMmmoJ2C9S46RCm2GMUbatPEUK9Yjy26IrAy8D/M00lLkv+Q==", + "node_modules/@npmcli/run-script": { + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-10.0.3.tgz", + "integrity": "sha512-ER2N6itRkzWbbtVmZ9WKaWxVlKlOeBFF1/7xx+KA5J1xKa4JjUwBdb6tDpk0v1qA+d+VDwHI9qmLcXSWcmi+Rw==", "dev": true, + "license": "ISC", "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25" + "@npmcli/node-gyp": "^5.0.0", + "@npmcli/package-json": "^7.0.0", + "@npmcli/promise-spawn": "^9.0.0", + "node-gyp": "^12.1.0", + "proc-log": "^6.0.0", + "which": "^6.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.4.tgz", - "integrity": "sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==", - "dev": true - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.29", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.29.tgz", - "integrity": "sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==", + "node_modules/@npmcli/run-script/node_modules/isexe": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-4.0.0.tgz", + "integrity": "sha512-FFUtZMpoZ8RqHS3XeXEmHWLA4thH+ZxCv2lOiPIn1Xc7CxrqhWzNSDzD+/chS/zbYezmiwWLdQC09JdQKmthOw==", "dev": true, - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=20" } }, - "node_modules/@jsonjoy.com/base64": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-q6XAnWQDIMA3+FTiOYajoYqySkO+JSat0ytXGSuRdq9uXE7o92gzuQwQM14xaCRlBLGq3v5miDGC4vkVTn54xA==", - "dev": true, - "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" - } - }, - "node_modules/@jsonjoy.com/json-pack": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-1.2.0.tgz", - "integrity": "sha512-io1zEbbYcElht3tdlqEOFxZ0dMTYrHz9iMf0gqn1pPjZFTCgM5R4R5IMA20Chb2UPYYsxjzs8CgZ7Nb5n2K2rA==", + "node_modules/@npmcli/run-script/node_modules/which": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/which/-/which-6.0.1.tgz", + "integrity": "sha512-oGLe46MIrCRqX7ytPUf66EAYvdeMIZYn3WaocqqKZAxrBpkqHfL/qvTyJ/bTk5+AqHCjXmrv3CEWgy368zhRUg==", "dev": true, + "license": "ISC", "dependencies": { - "@jsonjoy.com/base64": "^1.1.1", - "@jsonjoy.com/util": "^1.1.2", - "hyperdyperid": "^1.2.0", - "thingies": "^1.20.0" - }, - "engines": { - "node": ">=10.0" + "isexe": "^4.0.0" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" + "bin": { + "node-which": "bin/which.js" }, - "peerDependencies": { - "tslib": "2" + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/@jsonjoy.com/util": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-1.6.0.tgz", - "integrity": "sha512-sw/RMbehRhN68WRtcKCpQOPfnH6lLP4GJfqzi3iYej8tnzpZUDr6UkZYJjcjjC0FWEJOJbyM3PTIwxucUmDG2A==", + "node_modules/@oxc-project/types": { + "version": "0.106.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.106.0.tgz", + "integrity": "sha512-QdsH3rZq480VnOHSHgPYOhjL8O8LBdcnSjM408BpPCCUc0JYYZPG9Gafl9i3OcGk/7137o+gweb4cCv3WAUykg==", "dev": true, - "engines": { - "node": ">=10.0" - }, + "license": "MIT", "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" + "url": "https://github.com/sponsors/Boshen" } }, - "node_modules/@leichtgewicht/ip-codec": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz", - "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==", - "dev": true - }, - "node_modules/@listr2/prompt-adapter-inquirer": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/@listr2/prompt-adapter-inquirer/-/prompt-adapter-inquirer-2.0.18.tgz", - "integrity": "sha512-0hz44rAcrphyXcA8IS7EJ2SCoaBZD2u5goE8S/e+q/DL+dOGpqpcLidVOFeLG3VgML62SXmfRLAhWt0zL1oW4Q==", + "node_modules/@parcel/watcher": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.1.tgz", + "integrity": "sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==", "dev": true, + "hasInstallScript": true, + "optional": true, "dependencies": { - "@inquirer/type": "^1.5.5" + "detect-libc": "^1.0.3", + "is-glob": "^4.0.3", + "micromatch": "^4.0.5", + "node-addon-api": "^7.0.0" }, "engines": { - "node": ">=18.0.0" + "node": ">= 10.0.0" }, - "peerDependencies": { - "@inquirer/prompts": ">= 3 < 8" - } - }, - "node_modules/@listr2/prompt-adapter-inquirer/node_modules/@inquirer/type": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-1.5.5.tgz", - "integrity": "sha512-MzICLu4yS7V8AA61sANROZ9vT1H3ooca5dSmI1FjZkzq7o/koMsRfQSzRtFo+F3Ao4Sf1C0bpLKejpKB/+j6MA==", - "dev": true, - "dependencies": { - "mute-stream": "^1.0.0" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" }, - "engines": { - "node": ">=18" + "optionalDependencies": { + "@parcel/watcher-android-arm64": "2.5.1", + "@parcel/watcher-darwin-arm64": "2.5.1", + "@parcel/watcher-darwin-x64": "2.5.1", + "@parcel/watcher-freebsd-x64": "2.5.1", + "@parcel/watcher-linux-arm-glibc": "2.5.1", + "@parcel/watcher-linux-arm-musl": "2.5.1", + "@parcel/watcher-linux-arm64-glibc": "2.5.1", + "@parcel/watcher-linux-arm64-musl": "2.5.1", + "@parcel/watcher-linux-x64-glibc": "2.5.1", + "@parcel/watcher-linux-x64-musl": "2.5.1", + "@parcel/watcher-win32-arm64": "2.5.1", + "@parcel/watcher-win32-ia32": "2.5.1", + "@parcel/watcher-win32-x64": "2.5.1" } }, - "node_modules/@listr2/prompt-adapter-inquirer/node_modules/mute-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-1.0.0.tgz", - "integrity": "sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==", + "node_modules/@parcel/watcher-android-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.1.tgz", + "integrity": "sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==", + "cpu": [ + "arm64" + ], "dev": true, + "optional": true, + "os": [ + "android" + ], "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/@lmdb/lmdb-darwin-arm64": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-arm64/-/lmdb-darwin-arm64-3.2.6.tgz", - "integrity": "sha512-yF/ih9EJJZc72psFQbwnn8mExIWfTnzWJg+N02hnpXtDPETYLmQswIMBn7+V88lfCaFrMozJsUvcEQIkEPU0Gg==", + "node_modules/@parcel/watcher-darwin-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.1.tgz", + "integrity": "sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==", "cpu": [ "arm64" ], @@ -3192,12 +3499,19 @@ "optional": true, "os": [ "darwin" - ] + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } }, - "node_modules/@lmdb/lmdb-darwin-x64": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-x64/-/lmdb-darwin-x64-3.2.6.tgz", - "integrity": "sha512-5BbCumsFLbCi586Bb1lTWQFkekdQUw8/t8cy++Uq251cl3hbDIGEwD9HAwh8H6IS2F6QA9KdKmO136LmipRNkg==", + "node_modules/@parcel/watcher-darwin-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.1.tgz", + "integrity": "sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==", "cpu": [ "x64" ], @@ -3205,6151 +3519,4415 @@ "optional": true, "os": [ "darwin" - ] + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } }, - "node_modules/@lmdb/lmdb-linux-arm": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm/-/lmdb-linux-arm-3.2.6.tgz", - "integrity": "sha512-+6XgLpMb7HBoWxXj+bLbiiB4s0mRRcDPElnRS3LpWRzdYSe+gFk5MT/4RrVNqd2MESUDmb53NUXw1+BP69bjiQ==", + "node_modules/@parcel/watcher-freebsd-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.1.tgz", + "integrity": "sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==", "cpu": [ - "arm" + "x64" ], "dev": true, "optional": true, "os": [ - "linux" - ] + "freebsd" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } }, - "node_modules/@lmdb/lmdb-linux-arm64": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm64/-/lmdb-linux-arm64-3.2.6.tgz", - "integrity": "sha512-l5VmJamJ3nyMmeD1ANBQCQqy7do1ESaJQfKPSm2IG9/ADZryptTyCj8N6QaYgIWewqNUrcbdMkJajRQAt5Qjfg==", + "node_modules/@parcel/watcher-linux-arm-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.1.tgz", + "integrity": "sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==", "cpu": [ - "arm64" + "arm" ], "dev": true, "optional": true, "os": [ "linux" - ] + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } }, - "node_modules/@lmdb/lmdb-linux-x64": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-x64/-/lmdb-linux-x64-3.2.6.tgz", - "integrity": "sha512-nDYT8qN9si5+onHYYaI4DiauDMx24OAiuZAUsEqrDy+ja/3EbpXPX/VAkMV8AEaQhy3xc4dRC+KcYIvOFefJ4Q==", + "node_modules/@parcel/watcher-linux-arm-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.1.tgz", + "integrity": "sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==", "cpu": [ - "x64" + "arm" ], "dev": true, "optional": true, "os": [ "linux" - ] + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } }, - "node_modules/@lmdb/lmdb-win32-x64": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-win32-x64/-/lmdb-win32-x64-3.2.6.tgz", - "integrity": "sha512-XlqVtILonQnG+9fH2N3Aytria7P/1fwDgDhl29rde96uH2sLB8CHORIf2PfuLVzFQJ7Uqp8py9AYwr3ZUCFfWg==", + "node_modules/@parcel/watcher-linux-arm64-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.1.tgz", + "integrity": "sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==", "cpu": [ - "x64" + "arm64" ], "dev": true, "optional": true, "os": [ - "win32" - ] + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } }, - "node_modules/@msgpackr-extract/msgpackr-extract-darwin-arm64": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-3.0.3.tgz", - "integrity": "sha512-QZHtlVgbAdy2zAqNA9Gu1UpIuI8Xvsd1v8ic6B2pZmeFnFcMWiPLfWXh7TVw4eGEZ/C9TH281KwhVoeQUKbyjw==", + "node_modules/@parcel/watcher-linux-arm64-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.1.tgz", + "integrity": "sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==", "cpu": [ "arm64" ], "dev": true, "optional": true, "os": [ - "darwin" - ] + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } }, - "node_modules/@msgpackr-extract/msgpackr-extract-darwin-x64": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-x64/-/msgpackr-extract-darwin-x64-3.0.3.tgz", - "integrity": "sha512-mdzd3AVzYKuUmiWOQ8GNhl64/IoFGol569zNRdkLReh6LRLHOXxU4U8eq0JwaD8iFHdVGqSy4IjFL4reoWCDFw==", + "node_modules/@parcel/watcher-linux-x64-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.1.tgz", + "integrity": "sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==", "cpu": [ "x64" ], "dev": true, "optional": true, "os": [ - "darwin" - ] + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } }, - "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm/-/msgpackr-extract-linux-arm-3.0.3.tgz", - "integrity": "sha512-fg0uy/dG/nZEXfYilKoRe7yALaNmHoYeIoJuJ7KJ+YyU2bvY8vPv27f7UKhGRpY6euFYqEVhxCFZgAUNQBM3nw==", + "node_modules/@parcel/watcher-linux-x64-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.1.tgz", + "integrity": "sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==", "cpu": [ - "arm" + "x64" ], "dev": true, "optional": true, "os": [ "linux" - ] + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } }, - "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm64": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm64/-/msgpackr-extract-linux-arm64-3.0.3.tgz", - "integrity": "sha512-YxQL+ax0XqBJDZiKimS2XQaf+2wDGVa1enVRGzEvLLVFeqa5kx2bWbtcSXgsxjQB7nRqqIGFIcLteF/sHeVtQg==", + "node_modules/@parcel/watcher-win32-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.1.tgz", + "integrity": "sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==", "cpu": [ "arm64" ], "dev": true, "optional": true, "os": [ - "linux" - ] - }, - "node_modules/@msgpackr-extract/msgpackr-extract-linux-x64": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-x64/-/msgpackr-extract-linux-x64-3.0.3.tgz", - "integrity": "sha512-cvwNfbP07pKUfq1uH+S6KJ7dT9K8WOE4ZiAcsrSes+UY55E/0jLYc+vq+DO7jlmqRb5zAggExKm0H7O/CBaesg==", - "cpu": [ - "x64" + "win32" ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } }, - "node_modules/@msgpackr-extract/msgpackr-extract-win32-x64": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-3.0.3.tgz", - "integrity": "sha512-x0fWaQtYp4E6sktbsdAqnehxDgEc/VwM7uLsRCYWaiGu0ykYdZPiS8zCWdnjHwyiumousxfBm4SO31eXqwEZhQ==", + "node_modules/@parcel/watcher-win32-ia32": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.1.tgz", + "integrity": "sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ==", "cpu": [ - "x64" + "ia32" ], "dev": true, "optional": true, "os": [ "win32" - ] - }, - "node_modules/@napi-rs/nice": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@napi-rs/nice/-/nice-1.0.4.tgz", - "integrity": "sha512-Sqih1YARrmMoHlXGgI9JrrgkzxcaaEso0AH+Y7j8NHonUs+xe4iDsgC3IBIDNdzEewbNpccNN6hip+b5vmyRLw==", - "dev": true, - "optional": true, + ], "engines": { - "node": ">= 10" + "node": ">= 10.0.0" }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/Brooooooklyn" - }, - "optionalDependencies": { - "@napi-rs/nice-android-arm-eabi": "1.0.4", - "@napi-rs/nice-android-arm64": "1.0.4", - "@napi-rs/nice-darwin-arm64": "1.0.4", - "@napi-rs/nice-darwin-x64": "1.0.4", - "@napi-rs/nice-freebsd-x64": "1.0.4", - "@napi-rs/nice-linux-arm-gnueabihf": "1.0.4", - "@napi-rs/nice-linux-arm64-gnu": "1.0.4", - "@napi-rs/nice-linux-arm64-musl": "1.0.4", - "@napi-rs/nice-linux-ppc64-gnu": "1.0.4", - "@napi-rs/nice-linux-riscv64-gnu": "1.0.4", - "@napi-rs/nice-linux-s390x-gnu": "1.0.4", - "@napi-rs/nice-linux-x64-gnu": "1.0.4", - "@napi-rs/nice-linux-x64-musl": "1.0.4", - "@napi-rs/nice-win32-arm64-msvc": "1.0.4", - "@napi-rs/nice-win32-ia32-msvc": "1.0.4", - "@napi-rs/nice-win32-x64-msvc": "1.0.4" + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/@napi-rs/nice-android-arm-eabi": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-android-arm-eabi/-/nice-android-arm-eabi-1.0.4.tgz", - "integrity": "sha512-OZFMYUkih4g6HCKTjqJHhMUlgvPiDuSLZPbPBWHLjKmFTv74COzRlq/gwHtmEVaR39mJQ6ZyttDl2HNMUbLVoA==", + "node_modules/@parcel/watcher-win32-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.1.tgz", + "integrity": "sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==", "cpu": [ - "arm" + "x64" ], "dev": true, "optional": true, "os": [ - "android" + "win32" ], "engines": { - "node": ">= 10" + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/@napi-rs/nice-android-arm64": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-android-arm64/-/nice-android-arm64-1.0.4.tgz", - "integrity": "sha512-k8u7cjeA64vQWXZcRrPbmwjH8K09CBnNaPnI9L1D5N6iMPL3XYQzLcN6WwQonfcqCDv5OCY3IqX89goPTV4KMw==", + "node_modules/@parcel/watcher/node_modules/detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", + "dev": true, + "optional": true, + "bin": { + "detect-libc": "bin/detect-libc.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/@parcel/watcher/node_modules/node-addon-api": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", + "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", + "dev": true, + "optional": true + }, + "node_modules/@rolldown/binding-android-arm64": { + "version": "1.0.0-beta.58", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-beta.58.tgz", + "integrity": "sha512-mWj5eE4Qc8TbPdGGaaLvBb9XfDPvE1EmZkJQgiGKwchkWH4oAJcRAKMTw7ZHnb1L+t7Ah41sBkAecaIsuUgsug==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "android" ], "engines": { - "node": ">= 10" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@napi-rs/nice-darwin-arm64": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-darwin-arm64/-/nice-darwin-arm64-1.0.4.tgz", - "integrity": "sha512-GsLdQvUcuVzoyzmtjsThnpaVEizAqH5yPHgnsBmq3JdVoVZHELFo7PuJEdfOH1DOHi2mPwB9sCJEstAYf3XCJA==", + "node_modules/@rolldown/binding-darwin-arm64": { + "version": "1.0.0-beta.58", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-beta.58.tgz", + "integrity": "sha512-wFxUymI/5R8bH8qZFYDfAxAN9CyISEIYke+95oZPiv6EWo88aa5rskjVcCpKA532R+klFmdqjbbaD56GNmTF4Q==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" ], "engines": { - "node": ">= 10" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@napi-rs/nice-darwin-x64": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-darwin-x64/-/nice-darwin-x64-1.0.4.tgz", - "integrity": "sha512-1y3gyT3e5zUY5SxRl3QDtJiWVsbkmhtUHIYwdWWIQ3Ia+byd/IHIEpqAxOGW1nhhnIKfTCuxBadHQb+yZASVoA==", + "node_modules/@rolldown/binding-darwin-x64": { + "version": "1.0.0-beta.58", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-beta.58.tgz", + "integrity": "sha512-ybp3MkPj23VDV9PhtRwdU5qrGhlViWRV5BjKwO6epaSlUD5lW0WyY+roN3ZAzbma/9RrMTgZ/a/gtQq8YXOcqw==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" ], "engines": { - "node": ">= 10" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@napi-rs/nice-freebsd-x64": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-freebsd-x64/-/nice-freebsd-x64-1.0.4.tgz", - "integrity": "sha512-06oXzESPRdXUuzS8n2hGwhM2HACnDfl3bfUaSqLGImM8TA33pzDXgGL0e3If8CcFWT98aHows5Lk7xnqYNGFeA==", + "node_modules/@rolldown/binding-freebsd-x64": { + "version": "1.0.0-beta.58", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-beta.58.tgz", + "integrity": "sha512-Evxj3yh7FWvyklUYZa0qTVT9N2zX9TPDqGF056hl8hlCZ9/ndQ2xMv6uw9PD1VlLpukbsqL+/C6M0qwipL0QMg==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "freebsd" ], "engines": { - "node": ">= 10" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@napi-rs/nice-linux-arm-gnueabihf": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-arm-gnueabihf/-/nice-linux-arm-gnueabihf-1.0.4.tgz", - "integrity": "sha512-CgklZ6g8WL4+EgVVkxkEvvsi2DSLf9QIloxWO0fvQyQBp6VguUSX3eHLeRpqwW8cRm2Hv/Q1+PduNk7VK37VZw==", + "node_modules/@rolldown/binding-linux-arm-gnueabihf": { + "version": "1.0.0-beta.58", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-beta.58.tgz", + "integrity": "sha512-tYeXprDOrEgVHUbPXH6MPso4cM/c6RTkmJNICMQlYdki4hGMh92aj3yU6CKs+4X5gfG0yj5kVUw/L4M685SYag==", "cpu": [ "arm" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">= 10" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@napi-rs/nice-linux-arm64-gnu": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-arm64-gnu/-/nice-linux-arm64-gnu-1.0.4.tgz", - "integrity": "sha512-wdAJ7lgjhAlsANUCv0zi6msRwq+D4KDgU+GCCHssSxWmAERZa2KZXO0H2xdmoJ/0i03i6YfK/sWaZgUAyuW2oQ==", + "node_modules/@rolldown/binding-linux-arm64-gnu": { + "version": "1.0.0-beta.58", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-beta.58.tgz", + "integrity": "sha512-N78vmZzP6zG967Ohr+MasCjmKtis0geZ1SOVmxrA0/bklTQSzH5kHEjW5Qn+i1taFno6GEre1E40v0wuWsNOQw==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">= 10" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@napi-rs/nice-linux-arm64-musl": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-arm64-musl/-/nice-linux-arm64-musl-1.0.4.tgz", - "integrity": "sha512-4b1KYG+sriufhFrpUS9uNOEYYJqSfcbnwGx6uGX7JjrH8tELG90cOpCawz5THNIwlS3DhLgnCOcn0+4p6z26QA==", + "node_modules/@rolldown/binding-linux-arm64-musl": { + "version": "1.0.0-beta.58", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-beta.58.tgz", + "integrity": "sha512-l+p4QVtG72C7wI2SIkNQw/KQtSjuYwS3rV6AKcWrRBF62ClsFUcif5vLaZIEbPrCXu5OFRXigXFJnxYsVVZqdQ==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">= 10" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@napi-rs/nice-linux-ppc64-gnu": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-ppc64-gnu/-/nice-linux-ppc64-gnu-1.0.4.tgz", - "integrity": "sha512-iaf3vMRgr23oe1PUaKpxaH3DS0IMN0+N9iEiWVwYPm/U15vZFYdqVegGfN2PzrZLUl5lc8ZxbmEKDfuqslhAMA==", + "node_modules/@rolldown/binding-linux-x64-gnu": { + "version": "1.0.0-beta.58", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-beta.58.tgz", + "integrity": "sha512-urzJX0HrXxIh0FfxwWRjfPCMeInU9qsImLQxHBgLp5ivji1EEUnOfux8KxPPnRQthJyneBrN2LeqUix9DYrNaQ==", "cpu": [ - "ppc64" + "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">= 10" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@napi-rs/nice-linux-riscv64-gnu": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-riscv64-gnu/-/nice-linux-riscv64-gnu-1.0.4.tgz", - "integrity": "sha512-UXoREY6Yw6rHrGuTwQgBxpfjK34t6mTjibE9/cXbefL9AuUCJ9gEgwNKZiONuR5QGswChqo9cnthjdKkYyAdDg==", + "node_modules/@rolldown/binding-linux-x64-musl": { + "version": "1.0.0-beta.58", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-beta.58.tgz", + "integrity": "sha512-7ijfVK3GISnXIwq/1FZo+KyAUJjL3kWPJ7rViAL6MWeEBhEgRzJ0yEd9I8N9aut8Y8ab+EKFJyRNMWZuUBwQ0A==", "cpu": [ - "riscv64" + "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ], "engines": { - "node": ">= 10" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@napi-rs/nice-linux-s390x-gnu": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-s390x-gnu/-/nice-linux-s390x-gnu-1.0.4.tgz", - "integrity": "sha512-eFbgYCRPmsqbYPAlLYU5hYTNbogmIDUvknilehHsFhCH1+0/kN87lP+XaLT0Yeq4V/rpwChSd9vlz4muzFArtw==", + "node_modules/@rolldown/binding-openharmony-arm64": { + "version": "1.0.0-beta.58", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-beta.58.tgz", + "integrity": "sha512-/m7sKZCS+cUULbzyJTIlv8JbjNohxbpAOA6cM+lgWgqVzPee3U6jpwydrib328JFN/gF9A99IZEnuGYqEDJdww==", "cpu": [ - "s390x" + "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ - "linux" + "openharmony" ], "engines": { - "node": ">= 10" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@napi-rs/nice-linux-x64-gnu": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-x64-gnu/-/nice-linux-x64-gnu-1.0.4.tgz", - "integrity": "sha512-4T3E6uTCwWT6IPnwuPcWVz3oHxvEp/qbrCxZhsgzwTUBEwu78EGNXGdHfKJQt3soth89MLqZJw+Zzvnhrsg1mQ==", + "node_modules/@rolldown/binding-wasm32-wasi": { + "version": "1.0.0-beta.58", + "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-beta.58.tgz", + "integrity": "sha512-6SZk7zMgv+y3wFFQ9qE5P9NnRHcRsptL1ypmudD26PDY+PvFCvfHRkJNfclWnvacVGxjowr7JOL3a9fd1wWhUw==", "cpu": [ - "x64" + "wasm32" ], "dev": true, + "license": "MIT", "optional": true, - "os": [ - "linux" - ], + "dependencies": { + "@napi-rs/wasm-runtime": "^1.1.1" + }, "engines": { - "node": ">= 10" + "node": ">=14.0.0" } }, - "node_modules/@napi-rs/nice-linux-x64-musl": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-x64-musl/-/nice-linux-x64-musl-1.0.4.tgz", - "integrity": "sha512-NtbBkAeyBPLvCBkWtwkKXkNSn677eaT0cX3tygq+2qVv71TmHgX4gkX6o9BXjlPzdgPGwrUudavCYPT9tzkEqQ==", + "node_modules/@rolldown/binding-win32-arm64-msvc": { + "version": "1.0.0-beta.58", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-beta.58.tgz", + "integrity": "sha512-sFqfYPnBZ6xBhMkadB7UD0yjEDRvs7ipR3nCggblN+N4ODCXY6qhg/bKL39+W+dgQybL7ErD4EGERVbW9DAWvg==", "cpu": [ - "x64" + "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ - "linux" + "win32" ], "engines": { - "node": ">= 10" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@napi-rs/nice-win32-arm64-msvc": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-win32-arm64-msvc/-/nice-win32-arm64-msvc-1.0.4.tgz", - "integrity": "sha512-vubOe3i+YtSJGEk/++73y+TIxbuVHi+W8ZzrRm2eETCjCRwNlgbfToQZ85dSA+4iBB/NJRGNp+O4hfdbbttZWA==", + "node_modules/@rolldown/binding-win32-x64-msvc": { + "version": "1.0.0-beta.58", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-beta.58.tgz", + "integrity": "sha512-AnFWJdAqB8+IDPcGrATYs67Kik/6tnndNJV2jGRmwlbeNiQQ8GhRJU8ETRlINfII0pqi9k4WWLnb00p1QCxw/Q==", "cpu": [ - "arm64" + "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" ], "engines": { - "node": ">= 10" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@napi-rs/nice-win32-ia32-msvc": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-win32-ia32-msvc/-/nice-win32-ia32-msvc-1.0.4.tgz", - "integrity": "sha512-BMOVrUDZeg1RNRKVlh4eyLv5djAAVLiSddfpuuQ47EFjBcklg0NUeKMFKNrKQR4UnSn4HAiACLD7YK7koskwmg==", + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-beta.58", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.58.tgz", + "integrity": "sha512-qWhDs6yFGR5xDfdrwiSa3CWGIHxD597uGE/A9xGqytBjANvh4rLCTTkq7szhMV4+Ygh+PMS90KVJ8xWG/TkX4w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.52.3.tgz", + "integrity": "sha512-h6cqHGZ6VdnwliFG1NXvMPTy/9PS3h8oLh7ImwR+kl+oYnQizgjxsONmmPSb2C66RksfkfIxEVtDSEcJiO0tqw==", "cpu": [ - "ia32" + "arm" ], "dev": true, + "license": "MIT", "optional": true, "os": [ - "win32" + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.52.3.tgz", + "integrity": "sha512-wd+u7SLT/u6knklV/ifG7gr5Qy4GUbH2hMWcDauPFJzmCZUAJ8L2bTkVXC2niOIxp8lk3iH/QX8kSrUxVZrOVw==", + "cpu": [ + "arm64" ], - "engines": { - "node": ">= 10" - } + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] }, - "node_modules/@napi-rs/nice-win32-x64-msvc": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-win32-x64-msvc/-/nice-win32-x64-msvc-1.0.4.tgz", - "integrity": "sha512-kCNk6HcRZquhw/whwh4rHsdPyOSCQCgnVDVik+Y9cuSVTDy3frpiCJTScJqPPS872h4JgZKkr/+CwcwttNEo9Q==", + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.52.3.tgz", + "integrity": "sha512-lj9ViATR1SsqycwFkJCtYfQTheBdvlWJqzqxwc9f2qrcVrQaF/gCuBRTiTolkRWS6KvNxSk4KHZWG7tDktLgjg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.52.3.tgz", + "integrity": "sha512-+Dyo7O1KUmIsbzx1l+4V4tvEVnVQqMOIYtrxK7ncLSknl1xnMHLgn7gddJVrYPNZfEB8CIi3hK8gq8bDhb3h5A==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ - "win32" + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.52.3.tgz", + "integrity": "sha512-u9Xg2FavYbD30g3DSfNhxgNrxhi6xVG4Y6i9Ur1C7xUuGDW3banRbXj+qgnIrwRN4KeJ396jchwy9bCIzbyBEQ==", + "cpu": [ + "arm64" ], - "engines": { - "node": ">= 10" - } + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] }, - "node_modules/@ngtools/webpack": { - "version": "19.2.15", - "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-19.2.15.tgz", - "integrity": "sha512-H37nop/wWMkSgoU2VvrMzanHePdLRRrX52nC5tT2ZhH3qP25+PrnMyw11PoLDLv3iWXC68uB1AiKNIT+jiQbuQ==", + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.52.3.tgz", + "integrity": "sha512-5M8kyi/OX96wtD5qJR89a/3x5x8x5inXBZO04JWhkQb2JWavOWfjgkdvUqibGJeNNaz1/Z1PPza5/tAPXICI6A==", + "cpu": [ + "x64" + ], "dev": true, - "engines": { - "node": "^18.19.1 || ^20.11.1 || >=22.0.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - }, - "peerDependencies": { - "@angular/compiler-cli": "^19.0.0 || ^19.2.0-next.0", - "typescript": ">=5.5 <5.9", - "webpack": "^5.54.0" - } + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] }, - "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==", + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.52.3.tgz", + "integrity": "sha512-IoerZJ4l1wRMopEHRKOO16e04iXRDyZFZnNZKrWeNquh5d6bucjezgd+OxG03mOMTnS1x7hilzb3uURPkJ0OfA==", + "cpu": [ + "arm" + ], "dev": true, - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "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==", + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.52.3.tgz", + "integrity": "sha512-ZYdtqgHTDfvrJHSh3W22TvjWxwOgc3ThK/XjgcNGP2DIwFIPeAPNsQxrJO5XqleSlgDux2VAoWQ5iJrtaC1TbA==", + "cpu": [ + "arm" + ], "dev": true, - "engines": { - "node": ">= 8" - } + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "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==", + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.52.3.tgz", + "integrity": "sha512-NcViG7A0YtuFDA6xWSgmFb6iPFzHlf5vcqb2p0lGEbT+gjrEEz8nC/EeDHvx6mnGXnGCC1SeVV+8u+smj0CeGQ==", + "cpu": [ + "arm64" + ], "dev": true, - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@npmcli/agent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@npmcli/agent/-/agent-3.0.0.tgz", - "integrity": "sha512-S79NdEgDQd/NGCay6TCoVzXSj74skRZIKJcpJjC5lOq34SZzyI6MqtiiWoiVWoVrTcGjNeC4ipbh1VIHlpfF5Q==", + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.52.3.tgz", + "integrity": "sha512-d3pY7LWno6SYNXRm6Ebsq0DJGoiLXTb83AIPCXl9fmtIQs/rXoS8SJxxUNtFbJ5MiOvs+7y34np77+9l4nfFMw==", + "cpu": [ + "arm64" + ], "dev": true, - "dependencies": { - "agent-base": "^7.1.0", - "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.1", - "lru-cache": "^10.0.1", - "socks-proxy-agent": "^8.0.3" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@npmcli/agent/node_modules/lru-cache": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "dev": true + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.52.3.tgz", + "integrity": "sha512-3y5GA0JkBuirLqmjwAKwB0keDlI6JfGYduMlJD/Rl7fvb4Ni8iKdQs1eiunMZJhwDWdCvrcqXRY++VEBbvk6Eg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@npmcli/fs": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-4.0.0.tgz", - "integrity": "sha512-/xGlezI6xfGO9NwuJlnwz/K14qD1kCSAGtacBHnGzeAIuJGazcp45KP5NuyARXoKb7cwulAGWVsbeSxdG/cb0Q==", + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.52.3.tgz", + "integrity": "sha512-AUUH65a0p3Q0Yfm5oD2KVgzTKgwPyp9DSXc3UA7DtxhEb/WSPfbG4wqXeSN62OG5gSo18em4xv6dbfcUGXcagw==", + "cpu": [ + "ppc64" + ], "dev": true, - "dependencies": { - "semver": "^7.3.5" - }, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.52.3.tgz", + "integrity": "sha512-1makPhFFVBqZE+XFg3Dkq+IkQ7JvmUrwwqaYBL2CE+ZpxPaqkGaiWFEWVGyvTwZace6WLJHwjVh/+CXbKDGPmg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.52.3.tgz", + "integrity": "sha512-OOFJa28dxfl8kLOPMUOQBCO6z3X2SAfzIE276fwT52uXDWUS178KWq0pL7d6p1kz7pkzA0yQwtqL0dEPoVcRWg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.52.3.tgz", + "integrity": "sha512-jMdsML2VI5l+V7cKfZx3ak+SLlJ8fKvLJ0Eoa4b9/vCUrzXKgoKxvHqvJ/mkWhFiyp88nCkM5S2v6nIwRtPcgg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.52.3.tgz", + "integrity": "sha512-tPgGd6bY2M2LJTA1uGq8fkSPK8ZLYjDjY+ZLK9WHncCnfIz29LIXIqUgzCR0hIefzy6Hpbe8Th5WOSwTM8E7LA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.52.3.tgz", + "integrity": "sha512-BCFkJjgk+WFzP+tcSMXq77ymAPIxsX9lFJWs+2JzuZTLtksJ2o5hvgTdIcZ5+oKzUDMwI0PfWzRBYAydAHF2Mw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.52.3.tgz", + "integrity": "sha512-KTD/EqjZF3yvRaWUJdD1cW+IQBk4fbQaHYJUmP8N4XoKFZilVL8cobFSTDnjTtxWJQ3JYaMgF4nObY/+nYkumA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.52.3.tgz", + "integrity": "sha512-+zteHZdoUYLkyYKObGHieibUFLbttX2r+58l27XZauq0tcWYYuKUwY2wjeCN9oK1Um2YgH2ibd6cnX/wFD7DuA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.52.3.tgz", + "integrity": "sha512-of1iHkTQSo3kr6dTIRX6t81uj/c/b15HXVsPcEElN5sS859qHrOepM5p9G41Hah+CTqSh2r8Bm56dL2z9UQQ7g==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.52.3.tgz", + "integrity": "sha512-s0hybmlHb56mWVZQj8ra9048/WZTPLILKxcvcq+8awSZmyiSUZjjem1AhU3Tf4ZKpYhK4mg36HtHDOe8QJS5PQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.52.3.tgz", + "integrity": "sha512-zGIbEVVXVtauFgl3MRwGWEN36P5ZGenHRMgNw88X5wEhEBpq0XrMEZwOn07+ICrwM17XO5xfMZqh0OldCH5VTA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@saehrimnir/druidjs": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/@saehrimnir/druidjs/-/druidjs-0.7.3.tgz", + "integrity": "sha512-ROrGB3VqU2ombyJz9XlvDvMCHstuJ25+lPzV1HXYaP0Pp4uOkcaHZUMJlA0YNB/SM0s/Toc9n4gJFCs7LPclDQ==", + "license": "BSD-3-Clause", "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": ">=14" } }, - "node_modules/@npmcli/git": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-6.0.3.tgz", - "integrity": "sha512-GUYESQlxZRAdhs3UhbB6pVRNUELQOHXwK9ruDkwmCv2aZ5y0SApQzUJCg02p3A7Ue2J5hxvlk1YI53c00NmRyQ==", + "node_modules/@schematics/angular": { + "version": "21.1.4", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-21.1.4.tgz", + "integrity": "sha512-I1zdSNzdbrVCWpeE2NsZQmIoa9m0nlw4INgdGIkqUH6FgwvoGKC0RoOxKAmm6HHVJ48FE/sPI13dwAeK89ow5A==", "dev": true, + "license": "MIT", "dependencies": { - "@npmcli/promise-spawn": "^8.0.0", - "ini": "^5.0.0", - "lru-cache": "^10.0.1", - "npm-pick-manifest": "^10.0.0", - "proc-log": "^5.0.0", - "promise-retry": "^2.0.1", - "semver": "^7.3.5", - "which": "^5.0.0" + "@angular-devkit/core": "21.1.4", + "@angular-devkit/schematics": "21.1.4", + "jsonc-parser": "3.3.1" }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^20.19.0 || ^22.12.0 || >=24.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" } }, - "node_modules/@npmcli/git/node_modules/isexe": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", - "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "node_modules/@schematics/angular/node_modules/@angular-devkit/core": { + "version": "21.1.4", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-21.1.4.tgz", + "integrity": "sha512-ObPTI5gYCB1jGxTRhcqZ6oQVUBFVJ8GH4LksVuAiz0nFX7xxpzARWvlhq943EtnlovVlUd9I8fM3RQqjfGVVAQ==", "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "8.17.1", + "ajv-formats": "3.0.1", + "jsonc-parser": "3.3.1", + "picomatch": "4.0.3", + "rxjs": "7.8.2", + "source-map": "0.7.6" + }, "engines": { - "node": ">=16" + "node": "^20.19.0 || ^22.12.0 || >=24.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "chokidar": "^5.0.0" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } } }, - "node_modules/@npmcli/git/node_modules/lru-cache": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "dev": true - }, - "node_modules/@npmcli/git/node_modules/which": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz", - "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==", + "node_modules/@sigstore/bundle": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@sigstore/bundle/-/bundle-4.0.0.tgz", + "integrity": "sha512-NwCl5Y0V6Di0NexvkTqdoVfmjTaQwoLM236r89KEojGmq/jMls8S+zb7yOwAPdXvbwfKDlP+lmXgAL4vKSQT+A==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "isexe": "^3.1.1" - }, - "bin": { - "node-which": "bin/which.js" + "@sigstore/protobuf-specs": "^0.5.0" }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/@npmcli/installed-package-contents": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@npmcli/installed-package-contents/-/installed-package-contents-3.0.0.tgz", - "integrity": "sha512-fkxoPuFGvxyrH+OQzyTkX2LUEamrF4jZSmxjAtPPHHGO0dqsQ8tTKjnIS8SAnPHdk2I03BDtSMR5K/4loKg79Q==", + "node_modules/@sigstore/core": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@sigstore/core/-/core-3.1.0.tgz", + "integrity": "sha512-o5cw1QYhNQ9IroioJxpzexmPjfCe7gzafd2RY3qnMpxr4ZEja+Jad/U8sgFpaue6bOaF+z7RVkyKVV44FN+N8A==", "dev": true, - "dependencies": { - "npm-bundled": "^4.0.0", - "npm-normalize-package-bin": "^4.0.0" - }, - "bin": { - "installed-package-contents": "bin/index.js" - }, + "license": "Apache-2.0", "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/@npmcli/node-gyp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@npmcli/node-gyp/-/node-gyp-4.0.0.tgz", - "integrity": "sha512-+t5DZ6mO/QFh78PByMq1fGSAub/agLJZDRfJRMeOSNCt8s9YVlTjmGpIPwPhvXTGUIJk+WszlT0rQa1W33yzNA==", + "node_modules/@sigstore/protobuf-specs": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@sigstore/protobuf-specs/-/protobuf-specs-0.5.0.tgz", + "integrity": "sha512-MM8XIwUjN2bwvCg1QvrMtbBmpcSHrkhFSCu1D11NyPvDQ25HEc4oG5/OcQfd/Tlf/OxmKWERDj0zGE23jQaMwA==", "dev": true, + "license": "Apache-2.0", "engines": { "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/@npmcli/package-json": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/@npmcli/package-json/-/package-json-6.2.0.tgz", - "integrity": "sha512-rCNLSB/JzNvot0SEyXqWZ7tX2B5dD2a1br2Dp0vSYVo5jh8Z0EZ7lS9TsZ1UtziddB1UfNUaMCc538/HztnJGA==", + "node_modules/@sigstore/sign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@sigstore/sign/-/sign-4.1.0.tgz", + "integrity": "sha512-Vx1RmLxLGnSUqx/o5/VsCjkuN5L7y+vxEEwawvc7u+6WtX2W4GNa7b9HEjmcRWohw/d6BpATXmvOwc78m+Swdg==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@npmcli/git": "^6.0.0", - "glob": "^10.2.2", - "hosted-git-info": "^8.0.0", - "json-parse-even-better-errors": "^4.0.0", - "proc-log": "^5.0.0", - "semver": "^7.5.3", - "validate-npm-package-license": "^3.0.4" + "@sigstore/bundle": "^4.0.0", + "@sigstore/core": "^3.1.0", + "@sigstore/protobuf-specs": "^0.5.0", + "make-fetch-happen": "^15.0.3", + "proc-log": "^6.1.0", + "promise-retry": "^2.0.1" }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/@npmcli/package-json/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==", + "node_modules/@sigstore/tuf": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@sigstore/tuf/-/tuf-4.0.1.tgz", + "integrity": "sha512-OPZBg8y5Vc9yZjmWCHrlWPMBqW5yd8+wFNl+thMdtcWz3vjVSoJQutF8YkrzI0SLGnkuFof4HSsWUhXrf219Lw==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "balanced-match": "^1.0.0" + "@sigstore/protobuf-specs": "^0.5.0", + "tuf-js": "^4.1.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/@npmcli/package-json/node_modules/glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "node_modules/@sigstore/verify": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@sigstore/verify/-/verify-3.1.0.tgz", + "integrity": "sha512-mNe0Iigql08YupSOGv197YdHpPPr+EzDZmfCgMc7RPNaZTw5aLN01nBl6CHJOh3BGtnMIj83EeN4butBchc8Ag==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" + "@sigstore/bundle": "^4.0.0", + "@sigstore/core": "^3.1.0", + "@sigstore/protobuf-specs": "^0.5.0" }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/@npmcli/package-json/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "node_modules/@socket.io/component-emitter": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz", + "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==", + "dev": true + }, + "node_modules/@standard-schema/spec": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", + "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", + "license": "MIT" + }, + "node_modules/@tufjs/canonical-json": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tufjs/canonical-json/-/canonical-json-2.0.0.tgz", + "integrity": "sha512-yVtV8zsdo8qFHe+/3kw81dSLyF7D576A5cCFCi4X7B39tWT7SekaEFUnvnWJHz+9qO7qJTah1JbrDjWKqFtdWA==", "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, + "license": "MIT", "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/@npmcli/promise-spawn": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-8.0.2.tgz", - "integrity": "sha512-/bNJhjc+o6qL+Dwz/bqfTQClkEO5nTQ1ZEcdCkAQjhkZMHIh22LPG7fNh1enJP1NKWDqYiiABnjFCY7E0zHYtQ==", + "node_modules/@tufjs/models": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@tufjs/models/-/models-4.1.0.tgz", + "integrity": "sha512-Y8cK9aggNRsqJVaKUlEYs4s7CvQ1b1ta2DVPyAimb0I2qhzjNk+A+mxvll/klL0RlfuIUei8BF7YWiua4kQqww==", "dev": true, + "license": "MIT", "dependencies": { - "which": "^5.0.0" + "@tufjs/canonical-json": "2.0.0", + "minimatch": "^10.1.1" }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/@npmcli/promise-spawn/node_modules/isexe": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", - "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "node_modules/@tufjs/models/node_modules/balanced-match": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.2.tgz", + "integrity": "sha512-x0K50QvKQ97fdEz2kPehIerj+YTeptKF9hyYkKf6egnwmMWAkADiO0QCzSp0R5xN8FTZgYaBfSaue46Ej62nMg==", "dev": true, + "license": "MIT", + "dependencies": { + "jackspeak": "^4.2.3" + }, "engines": { - "node": ">=16" + "node": "20 || >=22" } }, - "node_modules/@npmcli/promise-spawn/node_modules/which": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz", - "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==", + "node_modules/@tufjs/models/node_modules/brace-expansion": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.2.tgz", + "integrity": "sha512-Pdk8c9poy+YhOgVWw1JNN22/HcivgKWwpxKq04M/jTmHyCZn12WPJebZxdjSa5TmBqISrUSgNYU3eRORljfCCw==", "dev": true, + "license": "MIT", "dependencies": { - "isexe": "^3.1.1" - }, - "bin": { - "node-which": "bin/which.js" + "balanced-match": "^4.0.2" }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "20 || >=22" } }, - "node_modules/@npmcli/redact": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/@npmcli/redact/-/redact-3.2.2.tgz", - "integrity": "sha512-7VmYAmk4csGv08QzrDKScdzn11jHPFGyqJW39FyPgPuAp3zIaUmuCo1yxw9aGs+NEJuTGQ9Gwqpt93vtJubucg==", - "dev": true, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/@npmcli/run-script": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-9.1.0.tgz", - "integrity": "sha512-aoNSbxtkePXUlbZB+anS1LqsJdctG5n3UVhfU47+CDdwMi6uNTBMF9gPcQRnqghQd2FGzcwwIFBruFMxjhBewg==", - "dev": true, - "dependencies": { - "@npmcli/node-gyp": "^4.0.0", - "@npmcli/package-json": "^6.0.0", - "@npmcli/promise-spawn": "^8.0.0", - "node-gyp": "^11.0.0", - "proc-log": "^5.0.0", - "which": "^5.0.0" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/@npmcli/run-script/node_modules/isexe": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", - "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", - "dev": true, - "engines": { - "node": ">=16" - } - }, - "node_modules/@npmcli/run-script/node_modules/which": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz", - "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==", - "dev": true, - "dependencies": { - "isexe": "^3.1.1" - }, - "bin": { - "node-which": "bin/which.js" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/@parcel/watcher": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.1.tgz", - "integrity": "sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "dependencies": { - "detect-libc": "^1.0.3", - "is-glob": "^4.0.3", - "micromatch": "^4.0.5", - "node-addon-api": "^7.0.0" - }, - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - }, - "optionalDependencies": { - "@parcel/watcher-android-arm64": "2.5.1", - "@parcel/watcher-darwin-arm64": "2.5.1", - "@parcel/watcher-darwin-x64": "2.5.1", - "@parcel/watcher-freebsd-x64": "2.5.1", - "@parcel/watcher-linux-arm-glibc": "2.5.1", - "@parcel/watcher-linux-arm-musl": "2.5.1", - "@parcel/watcher-linux-arm64-glibc": "2.5.1", - "@parcel/watcher-linux-arm64-musl": "2.5.1", - "@parcel/watcher-linux-x64-glibc": "2.5.1", - "@parcel/watcher-linux-x64-musl": "2.5.1", - "@parcel/watcher-win32-arm64": "2.5.1", - "@parcel/watcher-win32-ia32": "2.5.1", - "@parcel/watcher-win32-x64": "2.5.1" - } - }, - "node_modules/@parcel/watcher-android-arm64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.1.tgz", - "integrity": "sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-darwin-arm64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.1.tgz", - "integrity": "sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-darwin-x64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.1.tgz", - "integrity": "sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-freebsd-x64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.1.tgz", - "integrity": "sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-arm-glibc": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.1.tgz", - "integrity": "sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-arm-musl": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.1.tgz", - "integrity": "sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-arm64-glibc": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.1.tgz", - "integrity": "sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-arm64-musl": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.1.tgz", - "integrity": "sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-x64-glibc": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.1.tgz", - "integrity": "sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-x64-musl": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.1.tgz", - "integrity": "sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-win32-arm64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.1.tgz", - "integrity": "sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-win32-ia32": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.1.tgz", - "integrity": "sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-win32-x64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.1.tgz", - "integrity": "sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher/node_modules/detect-libc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", - "dev": true, - "optional": true, - "bin": { - "detect-libc": "bin/detect-libc.js" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/@parcel/watcher/node_modules/node-addon-api": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", - "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", - "dev": true, - "optional": true - }, - "node_modules/@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "dev": true, - "optional": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.34.8.tgz", - "integrity": "sha512-q217OSE8DTp8AFHuNHXo0Y86e1wtlfVrXiAlwkIvGRQv9zbc6mE3sjIVfwI8sYUyNxwOg0j/Vm1RKM04JcWLJw==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.34.8.tgz", - "integrity": "sha512-Gigjz7mNWaOL9wCggvoK3jEIUUbGul656opstjaUSGC3eT0BM7PofdAJaBfPFWWkXNVAXbaQtC99OCg4sJv70Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.34.8.tgz", - "integrity": "sha512-02rVdZ5tgdUNRxIUrFdcMBZQoaPMrxtwSb+/hOfBdqkatYHR3lZ2A2EGyHq2sGOd0Owk80oV3snlDASC24He3Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.34.8.tgz", - "integrity": "sha512-qIP/elwR/tq/dYRx3lgwK31jkZvMiD6qUtOycLhTzCvrjbZ3LjQnEM9rNhSGpbLXVJYQ3rq39A6Re0h9tU2ynw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.34.8.tgz", - "integrity": "sha512-IQNVXL9iY6NniYbTaOKdrlVP3XIqazBgJOVkddzJlqnCpRi/yAeSOa8PLcECFSQochzqApIOE1GHNu3pCz+BDA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.34.8.tgz", - "integrity": "sha512-TYXcHghgnCqYFiE3FT5QwXtOZqDj5GmaFNTNt3jNC+vh22dc/ukG2cG+pi75QO4kACohZzidsq7yKTKwq/Jq7Q==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.34.8.tgz", - "integrity": "sha512-A4iphFGNkWRd+5m3VIGuqHnG3MVnqKe7Al57u9mwgbyZ2/xF9Jio72MaY7xxh+Y87VAHmGQr73qoKL9HPbXj1g==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.34.8.tgz", - "integrity": "sha512-S0lqKLfTm5u+QTxlFiAnb2J/2dgQqRy/XvziPtDd1rKZFXHTyYLoVL58M/XFwDI01AQCDIevGLbQrMAtdyanpA==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.34.8.tgz", - "integrity": "sha512-jpz9YOuPiSkL4G4pqKrus0pn9aYwpImGkosRKwNi+sJSkz+WU3anZe6hi73StLOQdfXYXC7hUfsQlTnjMd3s1A==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.34.8.tgz", - "integrity": "sha512-KdSfaROOUJXgTVxJNAZ3KwkRc5nggDk+06P6lgi1HLv1hskgvxHUKZ4xtwHkVYJ1Rep4GNo+uEfycCRRxht7+Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-loongarch64-gnu": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.34.8.tgz", - "integrity": "sha512-NyF4gcxwkMFRjgXBM6g2lkT58OWztZvw5KkV2K0qqSnUEqCVcqdh2jN4gQrTn/YUpAcNKyFHfoOZEer9nwo6uQ==", - "cpu": [ - "loong64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.34.8.tgz", - "integrity": "sha512-LMJc999GkhGvktHU85zNTDImZVUCJ1z/MbAJTnviiWmmjyckP5aQsHtcujMjpNdMZPT2rQEDBlJfubhs3jsMfw==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.34.8.tgz", - "integrity": "sha512-xAQCAHPj8nJq1PI3z8CIZzXuXCstquz7cIOL73HHdXiRcKk8Ywwqtx2wrIy23EcTn4aZ2fLJNBB8d0tQENPCmw==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.34.8.tgz", - "integrity": "sha512-DdePVk1NDEuc3fOe3dPPTb+rjMtuFw89gw6gVWxQFAuEqqSdDKnrwzZHrUYdac7A7dXl9Q2Vflxpme15gUWQFA==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.34.8.tgz", - "integrity": "sha512-8y7ED8gjxITUltTUEJLQdgpbPh1sUQ0kMTmufRF/Ns5tI9TNMNlhWtmPKKHCU0SilX+3MJkZ0zERYYGIVBYHIA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.34.8.tgz", - "integrity": "sha512-SCXcP0ZpGFIe7Ge+McxY5zKxiEI5ra+GT3QRxL0pMMtxPfpyLAKleZODi1zdRHkz5/BhueUrYtYVgubqe9JBNQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.34.8.tgz", - "integrity": "sha512-YHYsgzZgFJzTRbth4h7Or0m5O74Yda+hLin0irAIobkLQFRQd1qWmnoVfwmKm9TXIZVAD0nZ+GEb2ICicLyCnQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.34.8.tgz", - "integrity": "sha512-r3NRQrXkHr4uWy5TOjTpTYojR9XmF0j/RYgKCef+Ag46FWUTltm5ziticv8LdNsDMehjJ543x/+TJAek/xBA2w==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.34.8.tgz", - "integrity": "sha512-U0FaE5O1BCpZSeE6gBl3c5ObhePQSfk9vDRToMmTkbhCOgW4jqvtS5LGyQ76L1fH8sM0keRp4uDTsbjiUyjk0g==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@saehrimnir/druidjs": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/@saehrimnir/druidjs/-/druidjs-0.7.3.tgz", - "integrity": "sha512-ROrGB3VqU2ombyJz9XlvDvMCHstuJ25+lPzV1HXYaP0Pp4uOkcaHZUMJlA0YNB/SM0s/Toc9n4gJFCs7LPclDQ==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=14" - } - }, - "node_modules/@schematics/angular": { - "version": "19.2.15", - "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-19.2.15.tgz", - "integrity": "sha512-dz/eoFQKG09POSygpEDdlCehFIMo35HUM2rVV8lx9PfQEibpbGwl1NNQYEbqwVjTyCyD/ILyIXCWPE+EfTnG4g==", - "dev": true, - "dependencies": { - "@angular-devkit/core": "19.2.15", - "@angular-devkit/schematics": "19.2.15", - "jsonc-parser": "3.3.1" - }, - "engines": { - "node": "^18.19.1 || ^20.11.1 || >=22.0.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - } - }, - "node_modules/@sigstore/bundle": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@sigstore/bundle/-/bundle-3.1.0.tgz", - "integrity": "sha512-Mm1E3/CmDDCz3nDhFKTuYdB47EdRFRQMOE/EAbiG1MJW77/w1b3P7Qx7JSrVJs8PfwOLOVcKQCHErIwCTyPbag==", - "dev": true, - "dependencies": { - "@sigstore/protobuf-specs": "^0.4.0" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/@sigstore/core": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sigstore/core/-/core-2.0.0.tgz", - "integrity": "sha512-nYxaSb/MtlSI+JWcwTHQxyNmWeWrUXJJ/G4liLrGG7+tS4vAz6LF3xRXqLH6wPIVUoZQel2Fs4ddLx4NCpiIYg==", - "dev": true, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/@sigstore/protobuf-specs": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@sigstore/protobuf-specs/-/protobuf-specs-0.4.3.tgz", - "integrity": "sha512-fk2zjD9117RL9BjqEwF7fwv7Q/P9yGsMV4MUJZ/DocaQJ6+3pKr+syBq1owU5Q5qGw5CUbXzm+4yJ2JVRDQeSA==", - "dev": true, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/@sigstore/sign": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@sigstore/sign/-/sign-3.1.0.tgz", - "integrity": "sha512-knzjmaOHOov1Ur7N/z4B1oPqZ0QX5geUfhrVaqVlu+hl0EAoL4o+l0MSULINcD5GCWe3Z0+YJO8ues6vFlW0Yw==", - "dev": true, - "dependencies": { - "@sigstore/bundle": "^3.1.0", - "@sigstore/core": "^2.0.0", - "@sigstore/protobuf-specs": "^0.4.0", - "make-fetch-happen": "^14.0.2", - "proc-log": "^5.0.0", - "promise-retry": "^2.0.1" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/@sigstore/tuf": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@sigstore/tuf/-/tuf-3.1.1.tgz", - "integrity": "sha512-eFFvlcBIoGwVkkwmTi/vEQFSva3xs5Ot3WmBcjgjVdiaoelBLQaQ/ZBfhlG0MnG0cmTYScPpk7eDdGDWUcFUmg==", - "dev": true, - "dependencies": { - "@sigstore/protobuf-specs": "^0.4.1", - "tuf-js": "^3.0.1" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/@sigstore/verify": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@sigstore/verify/-/verify-2.1.1.tgz", - "integrity": "sha512-hVJD77oT67aowHxwT4+M6PGOp+E2LtLdTK3+FC0lBO9T7sYwItDMXZ7Z07IDCvR1M717a4axbIWckrW67KMP/w==", - "dev": true, - "dependencies": { - "@sigstore/bundle": "^3.1.0", - "@sigstore/core": "^2.0.0", - "@sigstore/protobuf-specs": "^0.4.1" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/@sindresorhus/merge-streams": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz", - "integrity": "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==", - "dev": true, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@socket.io/component-emitter": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz", - "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==", - "dev": true - }, - "node_modules/@tufjs/canonical-json": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@tufjs/canonical-json/-/canonical-json-2.0.0.tgz", - "integrity": "sha512-yVtV8zsdo8qFHe+/3kw81dSLyF7D576A5cCFCi4X7B39tWT7SekaEFUnvnWJHz+9qO7qJTah1JbrDjWKqFtdWA==", - "dev": true, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/@tufjs/models": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@tufjs/models/-/models-3.0.1.tgz", - "integrity": "sha512-UUYHISyhCU3ZgN8yaear3cGATHb3SMuKHsQ/nVbHXcmnBf+LzQ/cQfhNG+rfaSHgqGKNEm2cOCLVLELStUQ1JA==", - "dev": true, - "dependencies": { - "@tufjs/canonical-json": "2.0.0", - "minimatch": "^9.0.5" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/@tufjs/models/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, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@tufjs/models/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, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "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 - }, - "node_modules/@types/body-parser": { - "version": "1.19.6", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz", - "integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==", - "dev": true, - "dependencies": { - "@types/connect": "*", - "@types/node": "*" - } - }, - "node_modules/@types/bonjour": { - "version": "3.5.13", - "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", - "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/connect": { - "version": "3.4.38", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", - "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/connect-history-api-fallback": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz", - "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==", - "dev": true, - "dependencies": { - "@types/express-serve-static-core": "*", - "@types/node": "*" - } - }, - "node_modules/@types/cors": { - "version": "2.8.19", - "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.19.tgz", - "integrity": "sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/d3": { - "version": "7.4.3", - "resolved": "https://registry.npmjs.org/@types/d3/-/d3-7.4.3.tgz", - "integrity": "sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww==", - "dev": true, - "dependencies": { - "@types/d3-array": "*", - "@types/d3-axis": "*", - "@types/d3-brush": "*", - "@types/d3-chord": "*", - "@types/d3-color": "*", - "@types/d3-contour": "*", - "@types/d3-delaunay": "*", - "@types/d3-dispatch": "*", - "@types/d3-drag": "*", - "@types/d3-dsv": "*", - "@types/d3-ease": "*", - "@types/d3-fetch": "*", - "@types/d3-force": "*", - "@types/d3-format": "*", - "@types/d3-geo": "*", - "@types/d3-hierarchy": "*", - "@types/d3-interpolate": "*", - "@types/d3-path": "*", - "@types/d3-polygon": "*", - "@types/d3-quadtree": "*", - "@types/d3-random": "*", - "@types/d3-scale": "*", - "@types/d3-scale-chromatic": "*", - "@types/d3-selection": "*", - "@types/d3-shape": "*", - "@types/d3-time": "*", - "@types/d3-time-format": "*", - "@types/d3-timer": "*", - "@types/d3-transition": "*", - "@types/d3-zoom": "*" - } - }, - "node_modules/@types/d3-array": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.1.tgz", - "integrity": "sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==", - "dev": true - }, - "node_modules/@types/d3-axis": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@types/d3-axis/-/d3-axis-3.0.6.tgz", - "integrity": "sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw==", - "dev": true, - "dependencies": { - "@types/d3-selection": "*" - } - }, - "node_modules/@types/d3-brush": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@types/d3-brush/-/d3-brush-3.0.6.tgz", - "integrity": "sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A==", - "dev": true, - "dependencies": { - "@types/d3-selection": "*" - } - }, - "node_modules/@types/d3-chord": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@types/d3-chord/-/d3-chord-3.0.6.tgz", - "integrity": "sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg==", - "dev": true - }, - "node_modules/@types/d3-color": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz", - "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==", - "dev": true - }, - "node_modules/@types/d3-contour": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@types/d3-contour/-/d3-contour-3.0.6.tgz", - "integrity": "sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg==", - "dev": true, - "dependencies": { - "@types/d3-array": "*", - "@types/geojson": "*" - } - }, - "node_modules/@types/d3-delaunay": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/@types/d3-delaunay/-/d3-delaunay-6.0.4.tgz", - "integrity": "sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw==", - "dev": true - }, - "node_modules/@types/d3-dispatch": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@types/d3-dispatch/-/d3-dispatch-3.0.6.tgz", - "integrity": "sha512-4fvZhzMeeuBJYZXRXrRIQnvUYfyXwYmLsdiN7XXmVNQKKw1cM8a5WdID0g1hVFZDqT9ZqZEY5pD44p24VS7iZQ==", - "dev": true - }, - "node_modules/@types/d3-drag": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@types/d3-drag/-/d3-drag-3.0.7.tgz", - "integrity": "sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==", - "dev": true, - "dependencies": { - "@types/d3-selection": "*" - } - }, - "node_modules/@types/d3-dsv": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@types/d3-dsv/-/d3-dsv-3.0.7.tgz", - "integrity": "sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g==", - "dev": true - }, - "node_modules/@types/d3-ease": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz", - "integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==", - "dev": true - }, - "node_modules/@types/d3-fetch": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@types/d3-fetch/-/d3-fetch-3.0.7.tgz", - "integrity": "sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA==", - "dev": true, - "dependencies": { - "@types/d3-dsv": "*" - } - }, - "node_modules/@types/d3-force": { - "version": "3.0.10", - "resolved": "https://registry.npmjs.org/@types/d3-force/-/d3-force-3.0.10.tgz", - "integrity": "sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw==", - "dev": true - }, - "node_modules/@types/d3-format": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/d3-format/-/d3-format-3.0.4.tgz", - "integrity": "sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g==", - "dev": true - }, - "node_modules/@types/d3-geo": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@types/d3-geo/-/d3-geo-3.1.0.tgz", - "integrity": "sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ==", - "dev": true, - "dependencies": { - "@types/geojson": "*" - } - }, - "node_modules/@types/d3-hierarchy": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/@types/d3-hierarchy/-/d3-hierarchy-3.1.7.tgz", - "integrity": "sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg==", - "dev": true - }, - "node_modules/@types/d3-interpolate": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz", - "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==", - "dev": true, - "dependencies": { - "@types/d3-color": "*" - } - }, - "node_modules/@types/d3-path": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.1.tgz", - "integrity": "sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==", - "dev": true - }, - "node_modules/@types/d3-polygon": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/d3-polygon/-/d3-polygon-3.0.2.tgz", - "integrity": "sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA==", - "dev": true - }, - "node_modules/@types/d3-quadtree": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@types/d3-quadtree/-/d3-quadtree-3.0.6.tgz", - "integrity": "sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg==", - "dev": true - }, - "node_modules/@types/d3-random": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/d3-random/-/d3-random-3.0.3.tgz", - "integrity": "sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ==", - "dev": true - }, - "node_modules/@types/d3-scale": { - "version": "4.0.9", - "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.9.tgz", - "integrity": "sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==", - "dev": true, - "dependencies": { - "@types/d3-time": "*" - } - }, - "node_modules/@types/d3-scale-chromatic": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz", - "integrity": "sha512-iWMJgwkK7yTRmWqRB5plb1kadXyQ5Sj8V/zYlFGMUBbIPKQScw+Dku9cAAMgJG+z5GYDoMjWGLVOvjghDEFnKQ==", - "dev": true - }, - "node_modules/@types/d3-selection": { - "version": "3.0.11", - "resolved": "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.11.tgz", - "integrity": "sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w==", - "dev": true - }, - "node_modules/@types/d3-shape": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.7.tgz", - "integrity": "sha512-VLvUQ33C+3J+8p+Daf+nYSOsjB4GXp19/S/aGo60m9h1v6XaxjiT82lKVWJCfzhtuZ3yD7i/TPeC/fuKLLOSmg==", - "dev": true, - "dependencies": { - "@types/d3-path": "*" - } - }, - "node_modules/@types/d3-time": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.4.tgz", - "integrity": "sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==", - "dev": true - }, - "node_modules/@types/d3-time-format": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-4.0.3.tgz", - "integrity": "sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg==", - "dev": true - }, - "node_modules/@types/d3-timer": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz", - "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==", - "dev": true - }, - "node_modules/@types/d3-transition": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-3.0.9.tgz", - "integrity": "sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg==", - "dev": true, - "dependencies": { - "@types/d3-selection": "*" - } - }, - "node_modules/@types/d3-zoom": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-3.0.8.tgz", - "integrity": "sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==", - "dev": true, - "dependencies": { - "@types/d3-interpolate": "*", - "@types/d3-selection": "*" - } - }, - "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, - "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, - "dependencies": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, - "node_modules/@types/estree": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", - "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", - "dev": true - }, - "node_modules/@types/express": { - "version": "4.17.23", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.23.tgz", - "integrity": "sha512-Crp6WY9aTYP3qPi2wGDo9iUe/rceX01UMhnF1jmwDcKCFM6cx7YhGP/Mpr3y9AASpfHixIG0E6azCcL5OcDHsQ==", - "dev": true, - "dependencies": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.33", - "@types/qs": "*", - "@types/serve-static": "*" - } - }, - "node_modules/@types/express-serve-static-core": { - "version": "4.19.6", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz", - "integrity": "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==", - "dev": true, - "dependencies": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*", - "@types/send": "*" - } - }, - "node_modules/@types/geojson": { - "version": "7946.0.16", - "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.16.tgz", - "integrity": "sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==", - "dev": true - }, - "node_modules/@types/http-errors": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.5.tgz", - "integrity": "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==", - "dev": true - }, - "node_modules/@types/http-proxy": { - "version": "1.17.16", - "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.16.tgz", - "integrity": "sha512-sdWoUajOB1cd0A8cRRQ1cfyWNbmFKLAqBB89Y8x5iYyG/mkJHc0YUH8pdWBy2omi9qtCpiIgGjuwO0dQST2l5w==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/jasmine": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-5.1.8.tgz", - "integrity": "sha512-u7/CnvRdh6AaaIzYjCgUuVbREFgulhX05Qtf6ZtW+aOcjCKKVvKgpkPYJBFTZSHtFBYimzU4zP0V2vrEsq9Wcg==", - "dev": true - }, - "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 - }, - "node_modules/@types/mime": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", - "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", - "dev": true - }, - "node_modules/@types/node": { - "version": "18.19.116", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.116.tgz", - "integrity": "sha512-1SHF5oSE6UfsnhB1QtPTB8bhKI/ZL57kIesbl0+/Nj8jW1C4Pjc+E+7sMq0Np6lu1zhjOKmoqPsK+RUsmok7nQ==", - "dev": true, - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/@types/node-forge": { - "version": "1.3.12", - "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.12.tgz", - "integrity": "sha512-a0ToKlRVnUw3aXKQq2F+krxZKq7B8LEQijzPn5RdFAMatARD2JX9o8FBpMXOOrjob0uc13aN+V/AXniOXW4d9A==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/qs": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.14.0.tgz", - "integrity": "sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==", - "dev": true - }, - "node_modules/@types/range-parser": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", - "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", - "dev": true - }, - "node_modules/@types/retry": { - "version": "0.12.2", - "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.2.tgz", - "integrity": "sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==", - "dev": true - }, - "node_modules/@types/send": { - "version": "0.17.5", - "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.5.tgz", - "integrity": "sha512-z6F2D3cOStZvuk2SaP6YrwkNO65iTZcwA2ZkSABegdkAh/lf+Aa/YQndZVfmEXT5vgAp6zv06VQ3ejSVjAny4w==", - "dev": true, - "dependencies": { - "@types/mime": "^1", - "@types/node": "*" - } - }, - "node_modules/@types/serve-index": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", - "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", - "dev": true, - "dependencies": { - "@types/express": "*" - } - }, - "node_modules/@types/serve-static": { - "version": "1.15.8", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.8.tgz", - "integrity": "sha512-roei0UY3LhpOJvjbIP6ZZFngyLKl5dskOtDhxY5THRSpO+ZI+nzJ+m5yUMzGrp89YRa7lvknKkMYjqQFGwA7Sg==", - "dev": true, - "dependencies": { - "@types/http-errors": "*", - "@types/node": "*", - "@types/send": "*" - } - }, - "node_modules/@types/sockjs": { - "version": "0.3.36", - "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", - "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "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 - }, - "node_modules/@types/three": { - "version": "0.176.0", - "resolved": "https://registry.npmjs.org/@types/three/-/three-0.176.0.tgz", - "integrity": "sha512-FwfPXxCqOtP7EdYMagCFePNKoG1AGBDUEVKtluv2BTVRpSt7b+X27xNsirPCTCqY1pGYsPUzaM3jgWP7dXSxlw==", - "dev": true, - "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/uuid": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-10.0.0.tgz", - "integrity": "sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==", - "dev": true - }, - "node_modules/@types/webxr": { - "version": "0.5.22", - "resolved": "https://registry.npmjs.org/@types/webxr/-/webxr-0.5.22.tgz", - "integrity": "sha512-Vr6Stjv5jPRqH690f5I5GLjVk8GSsoQSYJ2FVd/3jJF7KaqfwPi3ehfBS96mlQ2kPCwZaX6U0rG2+NGHBKkA/A==", - "dev": true - }, - "node_modules/@types/ws": { - "version": "8.18.1", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz", - "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@vitejs/plugin-basic-ssl": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-basic-ssl/-/plugin-basic-ssl-1.2.0.tgz", - "integrity": "sha512-mkQnxTkcldAzIsomk1UuLfAu9n+kpQ3JbHcpCp7d2Oo6ITtji8pHS3QToOWjhPFvNQSnhlkAjmGbhv2QvwO/7Q==", - "dev": true, - "engines": { - "node": ">=14.21.3" - }, - "peerDependencies": { - "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0" - } - }, - "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, - "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 - }, - "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 - }, - "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 - }, - "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, - "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 - }, - "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, - "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, - "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, - "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 - }, - "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, - "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, - "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, - "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, - "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, - "dependencies": { - "@webassemblyjs/ast": "1.14.1", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webgpu/types": { - "version": "0.1.64", - "resolved": "https://registry.npmjs.org/@webgpu/types/-/types-0.1.64.tgz", - "integrity": "sha512-84kRIAGV46LJTlJZWxShiOrNL30A+9KokD7RB3dRCIqODFjodS5tCD5yyiZ8kIReGVZSDfA3XkkwyyOIF6K62A==", - "dev": 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 - }, - "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 - }, - "node_modules/@yarnpkg/lockfile": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", - "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==", - "dev": true - }, - "node_modules/abbrev": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-3.0.1.tgz", - "integrity": "sha512-AO2ac6pjRB3SJmGJo+v5/aK6Omggp6fsLrs6wN9bd35ulu4cCwaAU9+7ZhXjeqHVkaHThLuzH0nZr0YpCDhygg==", - "dev": true, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - }, - "engines": { - "node": ">= 0.6" - } - }, - "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, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/adjust-sourcemap-loader": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-4.0.0.tgz", - "integrity": "sha512-OXwN5b9pCUXNQHJpwwD2qP40byEmSgzj8B4ydSN0uMNYWiFmJ6x6KwUllMmfk8Rwu/HJDFR7U8ubsWBoN0Xp0A==", - "dev": true, - "dependencies": { - "loader-utils": "^2.0.0", - "regex-parser": "^2.2.11" - }, - "engines": { - "node": ">=8.9" - } - }, - "node_modules/adjust-sourcemap-loader/node_modules/loader-utils": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", - "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", - "dev": true, - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - }, - "engines": { - "node": ">=8.9.0" - } - }, - "node_modules/agent-base": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", - "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", - "dev": true, - "engines": { - "node": ">= 14" - } - }, - "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, - "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": "3.0.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", - "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", - "dev": true, - "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, - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, - "node_modules/ansi-colors": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", - "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "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, - "dependencies": { - "type-fest": "^0.21.3" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-html-community": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", - "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", - "dev": true, - "engines": [ - "node >= 0.8.0" - ], - "bin": { - "ansi-html": "bin/ansi-html" - } - }, - "node_modules/ansi-regex": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", - "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "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, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "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, - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/anymatch/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "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 - }, - "node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" - }, - "node_modules/autoprefixer": { - "version": "10.4.20", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.20.tgz", - "integrity": "sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/autoprefixer" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "browserslist": "^4.23.3", - "caniuse-lite": "^1.0.30001646", - "fraction.js": "^4.3.7", - "normalize-range": "^0.1.2", - "picocolors": "^1.0.1", - "postcss-value-parser": "^4.2.0" - }, - "bin": { - "autoprefixer": "bin/autoprefixer" - }, - "engines": { - "node": "^10 || ^12 || >=14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/babel-loader": { - "version": "9.2.1", - "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.2.1.tgz", - "integrity": "sha512-fqe8naHt46e0yIdkjUZYqddSXfej3AHajX+CSO5X7oy0EmPc6o5Xh+RClNoHjnieWz9AW4kZxW9yyFMhVB1QLA==", - "dev": true, - "dependencies": { - "find-cache-dir": "^4.0.0", - "schema-utils": "^4.0.0" - }, - "engines": { - "node": ">= 14.15.0" - }, - "peerDependencies": { - "@babel/core": "^7.12.0", - "webpack": ">=5" - } - }, - "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, - "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-corejs2/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, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.11.1.tgz", - "integrity": "sha512-yGCqvBT4rwMczo28xkH/noxJ6MZ4nJfkVYdoDaC/utLtWrXxv27HVrzAeSbqR8SxDsp46n0YF47EbHoixy6rXQ==", - "dev": true, - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.3", - "core-js-compat": "^3.40.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, - "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.5" - }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.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 - }, - "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" - } - ] - }, - "node_modules/base64id": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", - "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==", - "dev": true, - "engines": { - "node": "^4.5.0 || >= 5.9" - } - }, - "node_modules/batch": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", - "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", - "dev": true - }, - "node_modules/beasties": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/beasties/-/beasties-0.3.2.tgz", - "integrity": "sha512-p4AF8uYzm9Fwu8m/hSVTCPXrRBPmB34hQpHsec2KOaR9CZmgoU8IOv4Cvwq4hgz2p4hLMNbsdNl5XeA6XbAQwA==", - "dev": true, - "dependencies": { - "css-select": "^5.1.0", - "css-what": "^6.1.0", - "dom-serializer": "^2.0.0", - "domhandler": "^5.0.3", - "htmlparser2": "^10.0.0", - "picocolors": "^1.1.1", - "postcss": "^8.4.49", - "postcss-media-query-parser": "^0.2.3" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/binary-extensions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", - "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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, - "dependencies": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "node_modules/body-parser": { - "version": "1.20.3", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", - "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.5", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.13.0", - "raw-body": "2.5.2", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/body-parser/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/body-parser/node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/body-parser/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/bonjour-service": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.3.0.tgz", - "integrity": "sha512-3YuAUiSkWykd+2Azjgyxei8OWf8thdn8AITIog2M4UICzoqfjlqr64WIjEXZllf/W6vK1goqleSR6brGomxQqA==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.3", - "multicast-dns": "^7.2.5" - } - }, - "node_modules/boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", - "dev": true - }, - "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, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "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, - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/browserslist": { - "version": "4.25.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.1.tgz", - "integrity": "sha512-KGj0KoOMXLpSNkkEI6Z6mShmQy0bc1I+T7K9N81k4WWMrfz+6fQ6es80B/YLAeRoKvjYE1YSHHOW1qe9xIVzHw==", - "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" - } - ], - "dependencies": { - "caniuse-lite": "^1.0.30001726", - "electron-to-chromium": "^1.5.173", - "node-releases": "^2.0.19", - "update-browserslist-db": "^1.1.3" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "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" - } - ], - "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 - }, - "node_modules/bundle-name": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", - "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", - "dev": true, - "dependencies": { - "run-applescript": "^7.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/cacache": { - "version": "19.0.1", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-19.0.1.tgz", - "integrity": "sha512-hdsUxulXCi5STId78vRVYEtDAjq99ICAUktLTeTYsLoTE6Z8dS0c8pWNCxwdrk9YfJeobDZc2Y186hD/5ZQgFQ==", + "node_modules/@tufjs/models/node_modules/minimatch": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.0.tgz", + "integrity": "sha512-ugkC31VaVg9cF0DFVoADH12k6061zNZkZON+aX8AWsR9GhPcErkcMBceb6znR8wLERM2AkkOxy2nWRLpT9Jq5w==", "dev": true, + "license": "BlueOak-1.0.0", "dependencies": { - "@npmcli/fs": "^4.0.0", - "fs-minipass": "^3.0.0", - "glob": "^10.2.2", - "lru-cache": "^10.0.1", - "minipass": "^7.0.3", - "minipass-collect": "^2.0.1", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "p-map": "^7.0.2", - "ssri": "^12.0.0", - "tar": "^7.4.3", - "unique-filename": "^4.0.0" + "brace-expansion": "^5.0.2" }, "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/cacache/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, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/cacache/node_modules/chownr": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", - "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", - "dev": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/cacache/node_modules/glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", - "dev": true, - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" + "node": "20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/cacache/node_modules/lru-cache": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "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 }, - "node_modules/cacache/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, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/cacache/node_modules/mkdirp": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", - "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", - "dev": true, - "bin": { - "mkdirp": "dist/cjs/src/bin.js" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/cacache/node_modules/tar": { - "version": "7.4.3", - "resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz", - "integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==", - "dev": true, - "dependencies": { - "@isaacs/fs-minipass": "^4.0.0", - "chownr": "^3.0.0", - "minipass": "^7.1.2", - "minizlib": "^3.0.1", - "mkdirp": "^3.0.1", - "yallist": "^5.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/cacache/node_modules/yallist": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", - "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", + "node_modules/@tybys/wasm-util": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz", + "integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==", "dev": true, - "engines": { - "node": ">=18" - } - }, - "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==", - "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==", + "license": "MIT", + "optional": true, "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, - "engines": { - "node": ">=6" + "tslib": "^2.4.0" } }, - "node_modules/caniuse-lite": { - "version": "1.0.30001727", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001727.tgz", - "integrity": "sha512-pB68nIHmbN6L/4C6MH1DokyR3bYqFwjaSs/sWDHGj4CTcFtQUQMuJftVwWkXq7mNWOybD3KhUv3oWHoGxgP14Q==", - "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" - } - ] - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/@types/cors": { + "version": "2.8.19", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.19.tgz", + "integrity": "sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg==", "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "@types/node": "*" } }, - "node_modules/chardet": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", - "dev": true - }, - "node_modules/chokidar": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", - "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "node_modules/@types/d3": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/@types/d3/-/d3-7.4.3.tgz", + "integrity": "sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww==", "dev": true, "dependencies": { - "readdirp": "^4.0.1" - }, - "engines": { - "node": ">= 14.16.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "dev": true, - "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, - "engines": { - "node": ">=6.0" + "@types/d3-array": "*", + "@types/d3-axis": "*", + "@types/d3-brush": "*", + "@types/d3-chord": "*", + "@types/d3-color": "*", + "@types/d3-contour": "*", + "@types/d3-delaunay": "*", + "@types/d3-dispatch": "*", + "@types/d3-drag": "*", + "@types/d3-dsv": "*", + "@types/d3-ease": "*", + "@types/d3-fetch": "*", + "@types/d3-force": "*", + "@types/d3-format": "*", + "@types/d3-geo": "*", + "@types/d3-hierarchy": "*", + "@types/d3-interpolate": "*", + "@types/d3-path": "*", + "@types/d3-polygon": "*", + "@types/d3-quadtree": "*", + "@types/d3-random": "*", + "@types/d3-scale": "*", + "@types/d3-scale-chromatic": "*", + "@types/d3-selection": "*", + "@types/d3-shape": "*", + "@types/d3-time": "*", + "@types/d3-time-format": "*", + "@types/d3-timer": "*", + "@types/d3-transition": "*", + "@types/d3-zoom": "*" } }, - "node_modules/cli-cursor": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", - "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", - "dev": true, - "dependencies": { - "restore-cursor": "^5.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } + "node_modules/@types/d3-array": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.1.tgz", + "integrity": "sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==", + "dev": true }, - "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==", + "node_modules/@types/d3-axis": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-axis/-/d3-axis-3.0.6.tgz", + "integrity": "sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw==", "dev": true, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "dependencies": { + "@types/d3-selection": "*" } }, - "node_modules/cli-truncate": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-4.0.0.tgz", - "integrity": "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==", + "node_modules/@types/d3-brush": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-brush/-/d3-brush-3.0.6.tgz", + "integrity": "sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A==", "dev": true, "dependencies": { - "slice-ansi": "^5.0.0", - "string-width": "^7.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "@types/d3-selection": "*" } }, - "node_modules/cli-width": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", - "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", - "dev": true, - "engines": { - "node": ">= 12" - } + "node_modules/@types/d3-chord": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-chord/-/d3-chord-3.0.6.tgz", + "integrity": "sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg==", + "dev": true }, - "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, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - } + "node_modules/@types/d3-color": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz", + "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==", + "dev": true }, - "node_modules/cliui/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==", + "node_modules/@types/d3-contour": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-contour/-/d3-contour-3.0.6.tgz", + "integrity": "sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg==", "dev": true, - "engines": { - "node": ">=8" + "dependencies": { + "@types/d3-array": "*", + "@types/geojson": "*" } }, - "node_modules/cliui/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==", + "node_modules/@types/d3-delaunay": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-delaunay/-/d3-delaunay-6.0.4.tgz", + "integrity": "sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw==", "dev": true }, - "node_modules/cliui/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, - "engines": { - "node": ">=8" - } + "node_modules/@types/d3-dispatch": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-dispatch/-/d3-dispatch-3.0.6.tgz", + "integrity": "sha512-4fvZhzMeeuBJYZXRXrRIQnvUYfyXwYmLsdiN7XXmVNQKKw1cM8a5WdID0g1hVFZDqT9ZqZEY5pD44p24VS7iZQ==", + "dev": true }, - "node_modules/cliui/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==", + "node_modules/@types/d3-drag": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@types/d3-drag/-/d3-drag-3.0.7.tgz", + "integrity": "sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==", "dev": true, "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" + "@types/d3-selection": "*" } }, - "node_modules/cliui/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==", + "node_modules/@types/d3-dsv": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@types/d3-dsv/-/d3-dsv-3.0.7.tgz", + "integrity": "sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g==", + "dev": true + }, + "node_modules/@types/d3-ease": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz", + "integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==", + "dev": true + }, + "node_modules/@types/d3-fetch": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@types/d3-fetch/-/d3-fetch-3.0.7.tgz", + "integrity": "sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA==", "dev": true, "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" + "@types/d3-dsv": "*" } }, - "node_modules/cliui/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==", + "node_modules/@types/d3-force": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@types/d3-force/-/d3-force-3.0.10.tgz", + "integrity": "sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw==", + "dev": true + }, + "node_modules/@types/d3-format": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-format/-/d3-format-3.0.4.tgz", + "integrity": "sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g==", + "dev": true + }, + "node_modules/@types/d3-geo": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/d3-geo/-/d3-geo-3.1.0.tgz", + "integrity": "sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ==", "dev": true, "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" + "@types/geojson": "*" } }, - "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, - "engines": { - "node": ">=0.8" - } + "node_modules/@types/d3-hierarchy": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/@types/d3-hierarchy/-/d3-hierarchy-3.1.7.tgz", + "integrity": "sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg==", + "dev": true }, - "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==", + "node_modules/@types/d3-interpolate": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz", + "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==", "dev": true, "dependencies": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" - }, - "engines": { - "node": ">=6" + "@types/d3-color": "*" } }, - "node_modules/clone-deep/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==", + "node_modules/@types/d3-path": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.1.tgz", + "integrity": "sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==", + "dev": true + }, + "node_modules/@types/d3-polygon": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-polygon/-/d3-polygon-3.0.2.tgz", + "integrity": "sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA==", + "dev": true + }, + "node_modules/@types/d3-quadtree": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-quadtree/-/d3-quadtree-3.0.6.tgz", + "integrity": "sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg==", + "dev": true + }, + "node_modules/@types/d3-random": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-random/-/d3-random-3.0.3.tgz", + "integrity": "sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ==", + "dev": true + }, + "node_modules/@types/d3-scale": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.9.tgz", + "integrity": "sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==", "dev": true, "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" + "@types/d3-time": "*" } }, - "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==", + "node_modules/@types/d3-scale-chromatic": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz", + "integrity": "sha512-iWMJgwkK7yTRmWqRB5plb1kadXyQ5Sj8V/zYlFGMUBbIPKQScw+Dku9cAAMgJG+z5GYDoMjWGLVOvjghDEFnKQ==", + "dev": true + }, + "node_modules/@types/d3-selection": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.11.tgz", + "integrity": "sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w==", + "dev": true + }, + "node_modules/@types/d3-shape": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.7.tgz", + "integrity": "sha512-VLvUQ33C+3J+8p+Daf+nYSOsjB4GXp19/S/aGo60m9h1v6XaxjiT82lKVWJCfzhtuZ3yD7i/TPeC/fuKLLOSmg==", "dev": true, "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" + "@types/d3-path": "*" } }, - "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==", + "node_modules/@types/d3-time": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.4.tgz", + "integrity": "sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==", "dev": true }, - "node_modules/colorette": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "node_modules/@types/d3-time-format": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-4.0.3.tgz", + "integrity": "sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg==", "dev": true }, - "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==", - "engines": { - "node": ">= 10" - } - }, - "node_modules/common-path-prefix": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", - "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==", + "node_modules/@types/d3-timer": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz", + "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==", "dev": true }, - "node_modules/compressible": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", - "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "node_modules/@types/d3-transition": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-3.0.9.tgz", + "integrity": "sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg==", "dev": true, "dependencies": { - "mime-db": ">= 1.43.0 < 2" - }, - "engines": { - "node": ">= 0.6" + "@types/d3-selection": "*" } }, - "node_modules/compression": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.8.0.tgz", - "integrity": "sha512-k6WLKfunuqCYD3t6AsuPGvQWaKwuLLh2/xHNcX4qE+vIfDNXpSqnrhwA7O53R7WVQUnt8dVAIW+YHr7xTgOgGA==", + "node_modules/@types/d3-zoom": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-3.0.8.tgz", + "integrity": "sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==", "dev": true, "dependencies": { - "bytes": "3.1.2", - "compressible": "~2.0.18", - "debug": "2.6.9", - "negotiator": "~0.6.4", - "on-headers": "~1.0.2", - "safe-buffer": "5.2.1", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.8.0" + "@types/d3-interpolate": "*", + "@types/d3-selection": "*" } }, - "node_modules/compression/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "node_modules/@types/esrecurse": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@types/esrecurse/-/esrecurse-4.3.1.tgz", + "integrity": "sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==", "dev": true, - "dependencies": { - "ms": "2.0.0" - } + "license": "MIT" }, - "node_modules/compression/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "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/geojson": { + "version": "7946.0.16", + "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.16.tgz", + "integrity": "sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==", "dev": true }, - "node_modules/compression/node_modules/negotiator": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", - "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==", - "dev": true, - "engines": { - "node": ">= 0.6" - } + "node_modules/@types/jasmine": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-5.1.8.tgz", + "integrity": "sha512-u7/CnvRdh6AaaIzYjCgUuVbREFgulhX05Qtf6ZtW+aOcjCKKVvKgpkPYJBFTZSHtFBYimzU4zP0V2vrEsq9Wcg==", + "dev": true }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "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 }, - "node_modules/connect": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", - "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==", + "node_modules/@types/node": { + "version": "18.19.116", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.116.tgz", + "integrity": "sha512-1SHF5oSE6UfsnhB1QtPTB8bhKI/ZL57kIesbl0+/Nj8jW1C4Pjc+E+7sMq0Np6lu1zhjOKmoqPsK+RUsmok7nQ==", "dev": true, "dependencies": { - "debug": "2.6.9", - "finalhandler": "1.1.2", - "parseurl": "~1.3.3", - "utils-merge": "1.0.1" - }, - "engines": { - "node": ">= 0.10.0" + "undici-types": "~5.26.4" } }, - "node_modules/connect-history-api-fallback": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", - "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==", - "dev": true, - "engines": { - "node": ">=0.8" - } + "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 }, - "node_modules/connect/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "node_modules/@types/three": { + "version": "0.176.0", + "resolved": "https://registry.npmjs.org/@types/three/-/three-0.176.0.tgz", + "integrity": "sha512-FwfPXxCqOtP7EdYMagCFePNKoG1AGBDUEVKtluv2BTVRpSt7b+X27xNsirPCTCqY1pGYsPUzaM3jgWP7dXSxlw==", "dev": true, "dependencies": { - "ms": "2.0.0" + "@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/connect/node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", - "dev": true, - "engines": { - "node": ">= 0.8" - } + "node_modules/@types/webxr": { + "version": "0.5.22", + "resolved": "https://registry.npmjs.org/@types/webxr/-/webxr-0.5.22.tgz", + "integrity": "sha512-Vr6Stjv5jPRqH690f5I5GLjVk8GSsoQSYJ2FVd/3jJF7KaqfwPi3ehfBS96mlQ2kPCwZaX6U0rG2+NGHBKkA/A==", + "dev": true }, - "node_modules/connect/node_modules/finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.46.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.46.4.tgz", + "integrity": "sha512-R48VhmTJqplNyDxCyqqVkFSZIx1qX6PzwqgcXn1olLrzxcSBDlOsbtcnQuQhNtnNiJ4Xe5gREI1foajYaYU2Vg==", "dev": true, + "license": "MIT", "dependencies": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "unpipe": "~1.0.0" + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "8.46.4", + "@typescript-eslint/type-utils": "8.46.4", + "@typescript-eslint/utils": "8.46.4", + "@typescript-eslint/visitor-keys": "8.46.4", + "graphemer": "^1.4.0", + "ignore": "^7.0.0", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.1.0" }, "engines": { - "node": ">= 0.8" + "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.4", + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" } }, - "node_modules/connect/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/connect/node_modules/on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/project-service": { + "version": "8.46.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.46.4.tgz", + "integrity": "sha512-nPiRSKuvtTN+no/2N1kt2tUh/HoFzeEgOm9fQ6XQk4/ApGqjx0zFIIaLJ6wooR1HIoozvj2j6vTi/1fgAz7UYQ==", "dev": true, + "license": "MIT", "dependencies": { - "ee-first": "1.1.1" + "@typescript-eslint/tsconfig-utils": "^8.46.4", + "@typescript-eslint/types": "^8.46.4", + "debug": "^4.3.4" }, "engines": { - "node": ">= 0.8" + "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/connect/node_modules/statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { + "version": "8.46.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.46.4.tgz", + "integrity": "sha512-tMDbLGXb1wC+McN1M6QeDx7P7c0UWO5z9CXqp7J8E+xGcJuUuevWKxuG8j41FoweS3+L41SkyKKkia16jpX7CA==", "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "license": "MIT", "dependencies": { - "safe-buffer": "5.2.1" + "@typescript-eslint/types": "8.46.4", + "@typescript-eslint/visitor-keys": "8.46.4" }, "engines": { - "node": ">= 0.6" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.46.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.46.4.tgz", + "integrity": "sha512-+/XqaZPIAk6Cjg7NWgSGe27X4zMGqrFqZ8atJsX3CWxH/jACqWnrWI68h7nHQld0y+k9eTTjb9r+KU4twLoo9A==", + "dev": true, + "license": "MIT", "engines": { - "node": ">= 0.6" + "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/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", - "dev": true - }, - "node_modules/cookie": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", - "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { + "version": "8.46.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.46.4.tgz", + "integrity": "sha512-USjyxm3gQEePdUwJBFjjGNG18xY9A2grDVGuk7/9AkjIF1L+ZrVnwR5VAU5JXtUnBL/Nwt3H31KlRDaksnM7/w==", + "dev": true, + "license": "MIT", "engines": { - "node": ">= 0.6" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" - }, - "node_modules/copy-anything": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-2.0.6.tgz", - "integrity": "sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==", + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/typescript-estree": { + "version": "8.46.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.46.4.tgz", + "integrity": "sha512-7oV2qEOr1d4NWNmpXLR35LvCfOkTNymY9oyW+lUHkmCno7aOmIf/hMaydnJBUTBMRCOGZh8YjkFOc8dadEoNGA==", "dev": true, + "license": "MIT", "dependencies": { - "is-what": "^3.14.1" + "@typescript-eslint/project-service": "8.46.4", + "@typescript-eslint/tsconfig-utils": "8.46.4", + "@typescript-eslint/types": "8.46.4", + "@typescript-eslint/visitor-keys": "8.46.4", + "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": { - "url": "https://github.com/sponsors/mesqueeb" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" } }, - "node_modules/copy-webpack-plugin": { - "version": "12.0.2", - "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-12.0.2.tgz", - "integrity": "sha512-SNwdBeHyII+rWvee/bTnAYyO8vfVdcSTud4EIb6jcZ8inLeWucJE0DnxXQBjlQ5zlteuuvooGQy3LIyGxhvlOA==", + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/utils": { + "version": "8.46.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.46.4.tgz", + "integrity": "sha512-AbSv11fklGXV6T28dp2Me04Uw90R2iJ30g2bgLz529Koehrmkbs1r7paFqr1vPCZi7hHwYxYtxfyQMRC8QaVSg==", "dev": true, + "license": "MIT", "dependencies": { - "fast-glob": "^3.3.2", - "glob-parent": "^6.0.1", - "globby": "^14.0.0", - "normalize-path": "^3.0.0", - "schema-utils": "^4.2.0", - "serialize-javascript": "^6.0.2" + "@eslint-community/eslint-utils": "^4.7.0", + "@typescript-eslint/scope-manager": "8.46.4", + "@typescript-eslint/types": "8.46.4", + "@typescript-eslint/typescript-estree": "8.46.4" }, "engines": { - "node": ">= 18.12.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/webpack" + "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "webpack": "^5.1.0" + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" } }, - "node_modules/core-js-compat": { - "version": "3.44.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.44.0.tgz", - "integrity": "sha512-JepmAj2zfl6ogy34qfWtcE7nHKAJnKsQFRn++scjVS2bZFllwptzw61BZcZFYBPpUznLfAvh0LGhxKppk04ClA==", + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { + "version": "8.46.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.46.4.tgz", + "integrity": "sha512-/++5CYLQqsO9HFGLI7APrxBJYo+5OCMpViuhV8q5/Qa3o5mMrF//eQHks+PXcsAVaLdn817fMuS7zqoXNNZGaw==", "dev": true, + "license": "MIT", "dependencies": { - "browserslist": "^4.25.1" + "@typescript-eslint/types": "8.46.4", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/core-js" + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true + "node_modules/@typescript-eslint/eslint-plugin/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/cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "node_modules/@typescript-eslint/eslint-plugin/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/@typescript-eslint/eslint-plugin/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": { - "object-assign": "^4", - "vary": "^1" + "brace-expansion": "^2.0.1" }, "engines": { - "node": ">= 0.10" + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.46.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.46.4.tgz", + "integrity": "sha512-tK3GPFWbirvNgsNKto+UmB/cRtn6TZfyw0D6IKrW55n6Vbs7KJoZtI//kpTKzE/DUmmnAFD8/Ca46s7Obs92/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/scope-manager": "8.46.4", + "@typescript-eslint/types": "8.46.4", + "@typescript-eslint/typescript-estree": "8.46.4", + "@typescript-eslint/visitor-keys": "8.46.4", + "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/cosmiconfig": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", - "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/project-service": { + "version": "8.46.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.46.4.tgz", + "integrity": "sha512-nPiRSKuvtTN+no/2N1kt2tUh/HoFzeEgOm9fQ6XQk4/ApGqjx0zFIIaLJ6wooR1HIoozvj2j6vTi/1fgAz7UYQ==", "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" + "@typescript-eslint/tsconfig-utils": "^8.46.4", + "@typescript-eslint/types": "^8.46.4", + "debug": "^4.3.4" }, "engines": { - "node": ">=14" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://github.com/sponsors/d-fischer" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "typescript": ">=4.9.5" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "typescript": ">=4.8.4 <6.0.0" } }, - "node_modules/cross-spawn": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { + "version": "8.46.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.46.4.tgz", + "integrity": "sha512-tMDbLGXb1wC+McN1M6QeDx7P7c0UWO5z9CXqp7J8E+xGcJuUuevWKxuG8j41FoweS3+L41SkyKKkia16jpX7CA==", "dev": true, + "license": "MIT", "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" + "@typescript-eslint/types": "8.46.4", + "@typescript-eslint/visitor-keys": "8.46.4" }, "engines": { - "node": ">= 8" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/cross-spawn/node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.46.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.46.4.tgz", + "integrity": "sha512-+/XqaZPIAk6Cjg7NWgSGe27X4zMGqrFqZ8atJsX3CWxH/jACqWnrWI68h7nHQld0y+k9eTTjb9r+KU4twLoo9A==", "dev": true, - "dependencies": { - "isexe": "^2.0.0" + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, - "bin": { - "node-which": "bin/node-which" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { + "version": "8.46.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.46.4.tgz", + "integrity": "sha512-USjyxm3gQEePdUwJBFjjGNG18xY9A2grDVGuk7/9AkjIF1L+ZrVnwR5VAU5JXtUnBL/Nwt3H31KlRDaksnM7/w==", + "dev": true, + "license": "MIT", "engines": { - "node": ">= 8" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/css-loader": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-7.1.2.tgz", - "integrity": "sha512-6WvYYn7l/XEGN8Xu2vWFt9nVzrCn39vKyTEFf/ExEyoksJjjSZV/0/35XPlMbpnr6VGhZIUg5yJrL8tGfes/FA==", + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { + "version": "8.46.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.46.4.tgz", + "integrity": "sha512-7oV2qEOr1d4NWNmpXLR35LvCfOkTNymY9oyW+lUHkmCno7aOmIf/hMaydnJBUTBMRCOGZh8YjkFOc8dadEoNGA==", "dev": true, + "license": "MIT", "dependencies": { - "icss-utils": "^5.1.0", - "postcss": "^8.4.33", - "postcss-modules-extract-imports": "^3.1.0", - "postcss-modules-local-by-default": "^4.0.5", - "postcss-modules-scope": "^3.2.0", - "postcss-modules-values": "^4.0.0", - "postcss-value-parser": "^4.2.0", - "semver": "^7.5.4" + "@typescript-eslint/project-service": "8.46.4", + "@typescript-eslint/tsconfig-utils": "8.46.4", + "@typescript-eslint/types": "8.46.4", + "@typescript-eslint/visitor-keys": "8.46.4", + "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.12.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/webpack" + "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@rspack/core": "0.x || 1.x", - "webpack": "^5.27.0" - }, - "peerDependenciesMeta": { - "@rspack/core": { - "optional": true - }, - "webpack": { - "optional": true - } + "typescript": ">=4.8.4 <6.0.0" } }, - "node_modules/css-select": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz", - "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==", + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { + "version": "8.46.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.46.4.tgz", + "integrity": "sha512-/++5CYLQqsO9HFGLI7APrxBJYo+5OCMpViuhV8q5/Qa3o5mMrF//eQHks+PXcsAVaLdn817fMuS7zqoXNNZGaw==", "dev": true, + "license": "MIT", "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^6.1.0", - "domhandler": "^5.0.2", - "domutils": "^3.0.1", - "nth-check": "^2.0.1" + "@typescript-eslint/types": "8.46.4", + "eslint-visitor-keys": "^4.2.1" }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/css-what": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz", - "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==", - "dev": true, "engines": { - "node": ">= 6" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://github.com/sponsors/fb55" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/cssesc": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "node_modules/@typescript-eslint/parser/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, - "bin": { - "cssesc": "bin/cssesc" - }, - "engines": { - "node": ">=4" + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" } }, - "node_modules/custom-event": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz", - "integrity": "sha512-GAj5FOq0Hd+RsCGVJxZuKaIDXDf3h6GQoNEjFgbLLI/trgtavwUbSnZ5pVfg27DVCaWjIohryS0JFwIJyT2cMg==", - "dev": true - }, - "node_modules/d3": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/d3/-/d3-7.9.0.tgz", - "integrity": "sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==", - "dependencies": { - "d3-array": "3", - "d3-axis": "3", - "d3-brush": "3", - "d3-chord": "3", - "d3-color": "3", - "d3-contour": "4", - "d3-delaunay": "6", - "d3-dispatch": "3", - "d3-drag": "3", - "d3-dsv": "3", - "d3-ease": "3", - "d3-fetch": "3", - "d3-force": "3", - "d3-format": "3", - "d3-geo": "3", - "d3-hierarchy": "3", - "d3-interpolate": "3", - "d3-path": "3", - "d3-polygon": "3", - "d3-quadtree": "3", - "d3-random": "3", - "d3-scale": "4", - "d3-scale-chromatic": "3", - "d3-selection": "3", - "d3-shape": "3", - "d3-time": "3", - "d3-time-format": "4", - "d3-timer": "3", - "d3-transition": "3", - "d3-zoom": "3" - }, + "node_modules/@typescript-eslint/parser/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": ">=12" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/d3-array": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", - "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", + "node_modules/@typescript-eslint/parser/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": { - "internmap": "1 - 2" + "brace-expansion": "^2.0.1" }, "engines": { - "node": ">=12" - } - }, - "node_modules/d3-axis": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-3.0.0.tgz", - "integrity": "sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==", - "engines": { - "node": ">=12" + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/d3-brush": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-3.0.0.tgz", - "integrity": "sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==", + "node_modules/@typescript-eslint/project-service": { + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.56.0.tgz", + "integrity": "sha512-M3rnyL1vIQOMeWxTWIW096/TtVP+8W3p/XnaFflhmcFp+U4zlxUxWj4XwNs6HbDeTtN4yun0GNTTDBw/SvufKg==", + "dev": true, + "license": "MIT", "dependencies": { - "d3-dispatch": "1 - 3", - "d3-drag": "2 - 3", - "d3-interpolate": "1 - 3", - "d3-selection": "3", - "d3-transition": "3" + "@typescript-eslint/tsconfig-utils": "^8.56.0", + "@typescript-eslint/types": "^8.56.0", + "debug": "^4.4.3" }, "engines": { - "node": ">=12" + "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/d3-chord": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-3.0.1.tgz", - "integrity": "sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==", + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.56.0.tgz", + "integrity": "sha512-7UiO/XwMHquH+ZzfVCfUNkIXlp/yQjjnlYUyYz7pfvlK3/EyyN6BK+emDmGNyQLBtLGaYrTAI6KOw8tFucWL2w==", + "dev": true, + "license": "MIT", "dependencies": { - "d3-path": "1 - 3" + "@typescript-eslint/types": "8.56.0", + "@typescript-eslint/visitor-keys": "8.56.0" }, "engines": { - "node": ">=12" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/d3-color": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", - "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.56.0.tgz", + "integrity": "sha512-bSJoIIt4o3lKXD3xmDh9chZcjCz5Lk8xS7Rxn+6l5/pKrDpkCwtQNQQwZ2qRPk7TkUYhrq3WPIHXOXlbXP0itg==", + "dev": true, + "license": "MIT", "engines": { - "node": ">=12" + "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/d3-contour": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-4.0.2.tgz", - "integrity": "sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==", + "node_modules/@typescript-eslint/type-utils": { + "version": "8.46.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.46.4.tgz", + "integrity": "sha512-V4QC8h3fdT5Wro6vANk6eojqfbv5bpwHuMsBcJUJkqs2z5XnYhJzyz9Y02eUmF9u3PgXEUiOt4w4KHR3P+z0PQ==", + "dev": true, + "license": "MIT", "dependencies": { - "d3-array": "^3.2.0" + "@typescript-eslint/types": "8.46.4", + "@typescript-eslint/typescript-estree": "8.46.4", + "@typescript-eslint/utils": "8.46.4", + "debug": "^4.3.4", + "ts-api-utils": "^2.1.0" }, "engines": { - "node": ">=12" + "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/d3-delaunay": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.4.tgz", - "integrity": "sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==", + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/project-service": { + "version": "8.46.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.46.4.tgz", + "integrity": "sha512-nPiRSKuvtTN+no/2N1kt2tUh/HoFzeEgOm9fQ6XQk4/ApGqjx0zFIIaLJ6wooR1HIoozvj2j6vTi/1fgAz7UYQ==", + "dev": true, + "license": "MIT", "dependencies": { - "delaunator": "5" + "@typescript-eslint/tsconfig-utils": "^8.46.4", + "@typescript-eslint/types": "^8.46.4", + "debug": "^4.3.4" }, "engines": { - "node": ">=12" - } - }, - "node_modules/d3-dispatch": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz", - "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==", - "engines": { - "node": ">=12" + "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/d3-drag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz", - "integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==", + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/scope-manager": { + "version": "8.46.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.46.4.tgz", + "integrity": "sha512-tMDbLGXb1wC+McN1M6QeDx7P7c0UWO5z9CXqp7J8E+xGcJuUuevWKxuG8j41FoweS3+L41SkyKKkia16jpX7CA==", + "dev": true, + "license": "MIT", "dependencies": { - "d3-dispatch": "1 - 3", - "d3-selection": "3" + "@typescript-eslint/types": "8.46.4", + "@typescript-eslint/visitor-keys": "8.46.4" }, "engines": { - "node": ">=12" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/d3-dsv": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-3.0.1.tgz", - "integrity": "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==", - "dependencies": { - "commander": "7", - "iconv-lite": "0.6", - "rw": "1" + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.46.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.46.4.tgz", + "integrity": "sha512-+/XqaZPIAk6Cjg7NWgSGe27X4zMGqrFqZ8atJsX3CWxH/jACqWnrWI68h7nHQld0y+k9eTTjb9r+KU4twLoo9A==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, - "bin": { - "csv2json": "bin/dsv2json.js", - "csv2tsv": "bin/dsv2dsv.js", - "dsv2dsv": "bin/dsv2dsv.js", - "dsv2json": "bin/dsv2json.js", - "json2csv": "bin/json2dsv.js", - "json2dsv": "bin/json2dsv.js", - "json2tsv": "bin/json2dsv.js", - "tsv2csv": "bin/dsv2dsv.js", - "tsv2json": "bin/dsv2json.js" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" }, - "engines": { - "node": ">=12" + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" } - }, - "node_modules/d3-ease": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", - "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { + "version": "8.46.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.46.4.tgz", + "integrity": "sha512-USjyxm3gQEePdUwJBFjjGNG18xY9A2grDVGuk7/9AkjIF1L+ZrVnwR5VAU5JXtUnBL/Nwt3H31KlRDaksnM7/w==", + "dev": true, + "license": "MIT", "engines": { - "node": ">=12" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/d3-fetch": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-3.0.1.tgz", - "integrity": "sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==", + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { + "version": "8.46.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.46.4.tgz", + "integrity": "sha512-7oV2qEOr1d4NWNmpXLR35LvCfOkTNymY9oyW+lUHkmCno7aOmIf/hMaydnJBUTBMRCOGZh8YjkFOc8dadEoNGA==", + "dev": true, + "license": "MIT", "dependencies": { - "d3-dsv": "1 - 3" + "@typescript-eslint/project-service": "8.46.4", + "@typescript-eslint/tsconfig-utils": "8.46.4", + "@typescript-eslint/types": "8.46.4", + "@typescript-eslint/visitor-keys": "8.46.4", + "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": ">=12" + "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/d3-force": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz", - "integrity": "sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==", + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/utils": { + "version": "8.46.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.46.4.tgz", + "integrity": "sha512-AbSv11fklGXV6T28dp2Me04Uw90R2iJ30g2bgLz529Koehrmkbs1r7paFqr1vPCZi7hHwYxYtxfyQMRC8QaVSg==", + "dev": true, + "license": "MIT", "dependencies": { - "d3-dispatch": "1 - 3", - "d3-quadtree": "1 - 3", - "d3-timer": "1 - 3" + "@eslint-community/eslint-utils": "^4.7.0", + "@typescript-eslint/scope-manager": "8.46.4", + "@typescript-eslint/types": "8.46.4", + "@typescript-eslint/typescript-estree": "8.46.4" }, "engines": { - "node": ">=12" + "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/d3-format": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", - "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==", + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { + "version": "8.46.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.46.4.tgz", + "integrity": "sha512-/++5CYLQqsO9HFGLI7APrxBJYo+5OCMpViuhV8q5/Qa3o5mMrF//eQHks+PXcsAVaLdn817fMuS7zqoXNNZGaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.46.4", + "eslint-visitor-keys": "^4.2.1" + }, "engines": { - "node": ">=12" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/d3-geo": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.1.tgz", - "integrity": "sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==", + "node_modules/@typescript-eslint/type-utils/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": { - "d3-array": "2.5.0 - 3" - }, - "engines": { - "node": ">=12" + "balanced-match": "^1.0.0" } }, - "node_modules/d3-hierarchy": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz", - "integrity": "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==", + "node_modules/@typescript-eslint/type-utils/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": ">=12" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/d3-interpolate": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", - "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "node_modules/@typescript-eslint/type-utils/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": { - "d3-color": "1 - 3" + "brace-expansion": "^2.0.1" }, "engines": { - "node": ">=12" + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/d3-path": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", - "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", + "node_modules/@typescript-eslint/types": { + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.56.0.tgz", + "integrity": "sha512-DBsLPs3GsWhX5HylbP9HNG15U0bnwut55Lx12bHB9MpXxQ+R5GC8MwQe+N1UFXxAeQDvEsEDY6ZYwX03K7Z6HQ==", + "dev": true, + "license": "MIT", "engines": { - "node": ">=12" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/d3-polygon": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-3.0.1.tgz", - "integrity": "sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==", + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.56.0.tgz", + "integrity": "sha512-ex1nTUMWrseMltXUHmR2GAQ4d+WjkZCT4f+4bVsps8QEdh0vlBsaCokKTPlnqBFqqGaxilDNJG7b8dolW2m43Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.56.0", + "@typescript-eslint/tsconfig-utils": "8.56.0", + "@typescript-eslint/types": "8.56.0", + "@typescript-eslint/visitor-keys": "8.56.0", + "debug": "^4.4.3", + "minimatch": "^9.0.5", + "semver": "^7.7.3", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.4.0" + }, "engines": { - "node": ">=12" + "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/d3-quadtree": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.1.tgz", - "integrity": "sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==", + "node_modules/@typescript-eslint/typescript-estree/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/@typescript-eslint/typescript-estree/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": ">=12" + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/d3-random": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-3.0.1.tgz", - "integrity": "sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==", + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, "engines": { - "node": ">=12" + "node": ">=10" } }, - "node_modules/d3-scale": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", - "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", + "node_modules/@typescript-eslint/utils": { + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.56.0.tgz", + "integrity": "sha512-RZ3Qsmi2nFGsS+n+kjLAYDPVlrzf7UhTffrDIKr+h2yzAlYP/y5ZulU0yeDEPItos2Ph46JAL5P/On3pe7kDIQ==", + "dev": true, + "license": "MIT", "dependencies": { - "d3-array": "2.10.0 - 3", - "d3-format": "1 - 3", - "d3-interpolate": "1.2.0 - 3", - "d3-time": "2.1.1 - 3", - "d3-time-format": "2 - 4" + "@eslint-community/eslint-utils": "^4.9.1", + "@typescript-eslint/scope-manager": "8.56.0", + "@typescript-eslint/types": "8.56.0", + "@typescript-eslint/typescript-estree": "8.56.0" }, "engines": { - "node": ">=12" + "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 || ^10.0.0", + "typescript": ">=4.8.4 <6.0.0" } }, - "node_modules/d3-scale-chromatic": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz", - "integrity": "sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==", + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.56.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.56.0.tgz", + "integrity": "sha512-q+SL+b+05Ud6LbEE35qe4A99P+htKTKVbyiNEe45eCbJFyh/HVK9QXwlrbz+Q4L8SOW4roxSVwXYj4DMBT7Ieg==", + "dev": true, + "license": "MIT", "dependencies": { - "d3-color": "1 - 3", - "d3-interpolate": "1 - 3" + "@typescript-eslint/types": "8.56.0", + "eslint-visitor-keys": "^5.0.0" }, "engines": { - "node": ">=12" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/d3-selection": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", - "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.0.tgz", + "integrity": "sha512-A0XeIi7CXU7nPlfHS9loMYEKxUaONu/hTEzHTGba9Huu94Cq1hPivf+DE5erJozZOky0LfvXAyrV/tcswpLI0Q==", + "dev": true, + "license": "Apache-2.0", "engines": { - "node": ">=12" + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/d3-shape": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", - "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", - "dependencies": { - "d3-path": "^3.1.0" - }, + "node_modules/@webgpu/types": { + "version": "0.1.64", + "resolved": "https://registry.npmjs.org/@webgpu/types/-/types-0.1.64.tgz", + "integrity": "sha512-84kRIAGV46LJTlJZWxShiOrNL30A+9KokD7RB3dRCIqODFjodS5tCD5yyiZ8kIReGVZSDfA3XkkwyyOIF6K62A==", + "dev": true + }, + "node_modules/@yarnpkg/lockfile": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", + "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==", + "dev": true + }, + "node_modules/abbrev": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-4.0.0.tgz", + "integrity": "sha512-a1wflyaL0tHtJSmLSOVybYhy22vRih4eduhhrkcjgrWGnRfrZtovJ2FRjxuTtkkj47O/baf0R86QU5OuYpz8fA==", + "dev": true, + "license": "ISC", "engines": { - "node": ">=12" + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/d3-time": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", - "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dev": true, "dependencies": { - "d3-array": "2 - 3" + "mime-types": "~2.1.34", + "negotiator": "0.6.3" }, "engines": { - "node": ">=12" + "node": ">= 0.6" } }, - "node_modules/d3-time-format": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", - "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", - "dependencies": { - "d3-time": "1 - 3" + "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, + "bin": { + "acorn": "bin/acorn" }, "engines": { - "node": ">=12" + "node": ">=0.4.0" } }, - "node_modules/d3-timer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", - "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", + "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/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "dev": true, + "license": "MIT", "engines": { - "node": ">=12" + "node": ">= 14" + } + }, + "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, + "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/d3-transition": { + "node_modules/ajv-formats": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz", - "integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "dev": true, "dependencies": { - "d3-color": "1 - 3", - "d3-dispatch": "1 - 3", - "d3-ease": "1 - 3", - "d3-interpolate": "1 - 3", - "d3-timer": "1 - 3" - }, - "engines": { - "node": ">=12" + "ajv": "^8.0.0" }, "peerDependencies": { - "d3-selection": "2 - 3" + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } } }, - "node_modules/d3-zoom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz", - "integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==", + "node_modules/algoliasearch": { + "version": "5.46.2", + "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-5.46.2.tgz", + "integrity": "sha512-qqAXW9QvKf2tTyhpDA4qXv1IfBwD2eduSW6tUEBFIfCeE9gn9HQ9I5+MaKoenRuHrzk5sQoNh1/iof8mY7uD6Q==", + "dev": true, + "license": "MIT", "dependencies": { - "d3-dispatch": "1 - 3", - "d3-drag": "2 - 3", - "d3-interpolate": "1 - 3", - "d3-selection": "2 - 3", - "d3-transition": "2 - 3" + "@algolia/abtesting": "1.12.2", + "@algolia/client-abtesting": "5.46.2", + "@algolia/client-analytics": "5.46.2", + "@algolia/client-common": "5.46.2", + "@algolia/client-insights": "5.46.2", + "@algolia/client-personalization": "5.46.2", + "@algolia/client-query-suggestions": "5.46.2", + "@algolia/client-search": "5.46.2", + "@algolia/ingestion": "1.46.2", + "@algolia/monitoring": "1.46.2", + "@algolia/recommend": "5.46.2", + "@algolia/requester-browser-xhr": "5.46.2", + "@algolia/requester-fetch": "5.46.2", + "@algolia/requester-node-http": "5.46.2" }, "engines": { - "node": ">=12" + "node": ">= 14.0.0" } }, - "node_modules/date-format": { - "version": "4.0.14", - "resolved": "https://registry.npmjs.org/date-format/-/date-format-4.0.14.tgz", - "integrity": "sha512-39BOQLs9ZjKh0/patS9nrT8wc3ioX3/eA/zgbKNopnF2wCqJEoxywwwElATYvRsXdnOxA/OQeQoFZ3rFjVajhg==", + "node_modules/angular-eslint": { + "version": "21.0.1", + "resolved": "https://registry.npmjs.org/angular-eslint/-/angular-eslint-21.0.1.tgz", + "integrity": "sha512-YZT5SAYXv3zxTcCwjuAJb7D8tOnRyF+a7Hrn4niLAihH+DowBocOAvhWyjCDKEULNGDszcKZukaDMzp2S18I5A==", "dev": true, - "engines": { - "node": ">=4.0" + "license": "MIT", + "dependencies": { + "@angular-devkit/core": ">= 21.0.0 < 22.0.0", + "@angular-devkit/schematics": ">= 21.0.0 < 22.0.0", + "@angular-eslint/builder": "21.0.1", + "@angular-eslint/eslint-plugin": "21.0.1", + "@angular-eslint/eslint-plugin-template": "21.0.1", + "@angular-eslint/schematics": "21.0.1", + "@angular-eslint/template-parser": "21.0.1", + "@typescript-eslint/types": "^8.0.0", + "@typescript-eslint/utils": "^8.0.0" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": "*", + "typescript-eslint": "^8.0.0" } }, - "node_modules/debug": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", - "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "node_modules/angular-eslint/node_modules/@angular-devkit/core": { + "version": "21.1.4", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-21.1.4.tgz", + "integrity": "sha512-ObPTI5gYCB1jGxTRhcqZ6oQVUBFVJ8GH4LksVuAiz0nFX7xxpzARWvlhq943EtnlovVlUd9I8fM3RQqjfGVVAQ==", "dev": true, + "license": "MIT", "dependencies": { - "ms": "^2.1.3" + "ajv": "8.17.1", + "ajv-formats": "3.0.1", + "jsonc-parser": "3.3.1", + "picomatch": "4.0.3", + "rxjs": "7.8.2", + "source-map": "0.7.6" }, "engines": { - "node": ">=6.0" + "node": "^20.19.0 || ^22.12.0 || >=24.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "chokidar": "^5.0.0" }, "peerDependenciesMeta": { - "supports-color": { + "chokidar": { "optional": true } } }, - "node_modules/default-browser": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.2.1.tgz", - "integrity": "sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==", + "node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", "dev": true, - "dependencies": { - "bundle-name": "^4.1.0", - "default-browser-id": "^5.0.0" - }, "engines": { - "node": ">=18" + "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, - "node_modules/default-browser-id": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.0.tgz", - "integrity": "sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==", + "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, + "dependencies": { + "color-convert": "^2.0.1" + }, "engines": { - "node": ">=18" + "node": ">=8" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "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==", + "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, "dependencies": { - "clone": "^1.0.2" + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">= 8" } }, - "node_modules/define-lazy-prop": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", - "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", + "node_modules/anymatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, "engines": { - "node": ">=12" + "node": ">=8.6" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/delaunator": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.0.1.tgz", - "integrity": "sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==", - "dependencies": { - "robust-predicates": "^3.0.2" + "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 + }, + "node_modules/aria-query": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", + "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" } }, - "node_modules/depd": { + "node_modules/axobject-query": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", + "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "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 + }, + "node_modules/base64id": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", + "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==", + "dev": true, "engines": { - "node": ">= 0.8" + "node": "^4.5.0 || >= 5.9" } }, - "node_modules/destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "node_modules/baseline-browser-mapping": { + "version": "2.9.19", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.19.tgz", + "integrity": "sha512-ipDqC8FrAl/76p2SSWKSI+H9tFwm7vYqXQrItCuiVPt26Km0jS+NzSsBWAaBusvSbQcfJG+JitdMm+wZAgTYqg==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.js" + } + }, + "node_modules/beasties": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/beasties/-/beasties-0.3.5.tgz", + "integrity": "sha512-NaWu+f4YrJxEttJSm16AzMIFtVldCvaJ68b1L098KpqXmxt9xOLtKoLkKxb8ekhOrLqEJAbvT6n6SEvB/sac7A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "css-select": "^6.0.0", + "css-what": "^7.0.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "htmlparser2": "^10.0.0", + "picocolors": "^1.1.1", + "postcss": "^8.4.49", + "postcss-media-query-parser": "^0.2.3" + }, "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" + "node": ">=14.0.0" } }, - "node_modules/detect-libc": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", - "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==", + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", "dev": true, - "optional": true, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/detect-node": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", - "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", - "dev": true - }, - "node_modules/di": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz", - "integrity": "sha512-uJaamHkagcZtHPqCIHZxnFrXlunQXgBOsZSUOWwFw31QJCAbyTBoHMW75YOTur5ZNx8pIeAKgf6GWIgaqqiLhA==", - "dev": true - }, - "node_modules/dns-packet": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", - "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", + "node_modules/body-parser": { + "version": "1.20.4", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.4.tgz", + "integrity": "sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA==", "dev": true, + "license": "MIT", "dependencies": { - "@leichtgewicht/ip-codec": "^2.0.1" + "bytes": "~3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "~1.2.0", + "http-errors": "~2.0.1", + "iconv-lite": "~0.4.24", + "on-finished": "~2.4.1", + "qs": "~6.14.0", + "raw-body": "~2.5.3", + "type-is": "~1.6.18", + "unpipe": "~1.0.0" }, "engines": { - "node": ">=6" + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" } }, - "node_modules/dom-serialize": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz", - "integrity": "sha512-Yra4DbvoW7/Z6LBN560ZwXMjoNOSAN2wRsKFGc4iBeso+mpIA6qj1vfdf9HpMaKAqG6wXTy+1SYEzmNpKXOSsQ==", + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "dependencies": { - "custom-event": "~1.0.0", - "ent": "~2.2.0", - "extend": "^3.0.0", - "void-elements": "^2.0.0" + "ms": "2.0.0" } }, - "node_modules/dom-serializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", - "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "node_modules/body-parser/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "dev": true, "dependencies": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.2", - "entities": "^4.2.0" + "safer-buffer": ">= 2.1.2 < 3" }, - "funding": { - "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + "engines": { + "node": ">=0.10.0" } }, - "node_modules/domelementtype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", - "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ] + "license": "ISC" }, - "node_modules/domhandler": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", - "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "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, "dependencies": { - "domelementtype": "^2.3.0" - }, - "engines": { - "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "node_modules/domutils": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", - "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", + "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, "dependencies": { - "dom-serializer": "^2.0.0", - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3" + "fill-range": "^7.1.1" }, - "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" + "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==", + "node_modules/browserslist": { + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", + "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", + "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": { - "call-bind-apply-helpers": "^1.0.1", - "es-errors": "^1.3.0", - "gopd": "^1.2.0" + "baseline-browser-mapping": "^2.9.0", + "caniuse-lite": "^1.0.30001759", + "electron-to-chromium": "^1.5.263", + "node-releases": "^2.0.27", + "update-browserslist-db": "^1.2.0" + }, + "bin": { + "browserslist": "cli.js" }, "engines": { - "node": ">= 0.4" + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "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 - }, - "node_modules/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" - }, - "node_modules/electron-to-chromium": { - "version": "1.5.180", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.180.tgz", - "integrity": "sha512-ED+GEyEh3kYMwt2faNmgMB0b8O5qtATGgR4RmRsIp4T6p7B8vdMbIedYndnvZfsaXvSzegtpfqRMDNCjjiSduA==", - "dev": true - }, - "node_modules/emoji-regex": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz", - "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==", + "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 }, - "node_modules/emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/encodeurl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", - "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", "engines": { "node": ">= 0.8" } }, - "node_modules/encoding": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", - "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", - "dev": true, - "optional": true, - "dependencies": { - "iconv-lite": "^0.6.2" - } - }, - "node_modules/engine.io": { - "version": "6.6.4", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.6.4.tgz", - "integrity": "sha512-ZCkIjSYNDyGn0R6ewHDtXgns/Zre/NT6Agvq1/WobF7JXgFff4SeDroKiCO3fNJreU9YG429Sc81o4w5ok/W5g==", + "node_modules/cacache": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-20.0.3.tgz", + "integrity": "sha512-3pUp4e8hv07k1QlijZu6Kn7c9+ZpWWk4j3F8N3xPuCExULobqJydKYOTj1FTq58srkJsXvO7LbGAH4C0ZU3WGw==", "dev": true, + "license": "ISC", "dependencies": { - "@types/cors": "^2.8.12", - "@types/node": ">=10.0.0", - "accepts": "~1.3.4", - "base64id": "2.0.0", - "cookie": "~0.7.2", - "cors": "~2.8.5", - "debug": "~4.3.1", - "engine.io-parser": "~5.2.1", - "ws": "~8.17.1" + "@npmcli/fs": "^5.0.0", + "fs-minipass": "^3.0.0", + "glob": "^13.0.0", + "lru-cache": "^11.1.0", + "minipass": "^7.0.3", + "minipass-collect": "^2.0.1", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "p-map": "^7.0.2", + "ssri": "^13.0.0", + "unique-filename": "^5.0.0" }, "engines": { - "node": ">=10.2.0" + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/engine.io-parser": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz", - "integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==", + "node_modules/cacache/node_modules/balanced-match": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.2.tgz", + "integrity": "sha512-x0K50QvKQ97fdEz2kPehIerj+YTeptKF9hyYkKf6egnwmMWAkADiO0QCzSp0R5xN8FTZgYaBfSaue46Ej62nMg==", "dev": true, + "license": "MIT", + "dependencies": { + "jackspeak": "^4.2.3" + }, "engines": { - "node": ">=10.0.0" + "node": "20 || >=22" } }, - "node_modules/engine.io/node_modules/cookie": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", - "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "node_modules/cacache/node_modules/brace-expansion": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.2.tgz", + "integrity": "sha512-Pdk8c9poy+YhOgVWw1JNN22/HcivgKWwpxKq04M/jTmHyCZn12WPJebZxdjSa5TmBqISrUSgNYU3eRORljfCCw==", "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, "engines": { - "node": ">= 0.6" + "node": "20 || >=22" } }, - "node_modules/engine.io/node_modules/debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "node_modules/cacache/node_modules/glob": { + "version": "13.0.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.3.tgz", + "integrity": "sha512-/g3B0mC+4x724v1TgtBlBtt2hPi/EWptsIAmXUx9Z2rvBYleQcsrmaOzd5LyL50jf/Soi83ZDJmw2+XqvH/EeA==", "dev": true, + "license": "BlueOak-1.0.0", "dependencies": { - "ms": "^2.1.3" + "minimatch": "^10.2.0", + "minipass": "^7.1.2", + "path-scurry": "^2.0.0" }, "engines": { - "node": ">=6.0" + "node": "20 || >=22" }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/engine.io/node_modules/ws": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", - "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", + "node_modules/cacache/node_modules/lru-cache": { + "version": "11.2.6", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.6.tgz", + "integrity": "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==", "dev": true, + "license": "BlueOak-1.0.0", "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } + "node": "20 || >=22" } }, - "node_modules/enhanced-resolve": { - "version": "5.18.2", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.2.tgz", - "integrity": "sha512-6Jw4sE1maoRJo3q8MsSIn2onJFbLTOjY9hlx4DZXmOKvLRd1Ok2kXmAGXaafL2+ijsJZ1ClYbl/pmqr9+k4iUQ==", + "node_modules/cacache/node_modules/minimatch": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.0.tgz", + "integrity": "sha512-ugkC31VaVg9cF0DFVoADH12k6061zNZkZON+aX8AWsR9GhPcErkcMBceb6znR8wLERM2AkkOxy2nWRLpT9Jq5w==", "dev": true, + "license": "BlueOak-1.0.0", "dependencies": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" + "brace-expansion": "^5.0.2" }, "engines": { - "node": ">=10.13.0" + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/ent": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.2.tgz", - "integrity": "sha512-kKvD1tO6BM+oK9HzCPpUdRb4vKFQY/FPTFmurMvh6LlN68VMrdj77w8yp51/kDbpkFOS9J8w5W6zIzgM2H8/hw==", + "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, "dependencies": { - "call-bound": "^1.0.3", "es-errors": "^1.3.0", - "punycode": "^1.4.1", - "safe-regex-test": "^1.1.0" + "function-bind": "^1.1.2" }, "engines": { "node": ">= 0.4" } }, - "node_modules/entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "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, + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, "engines": { - "node": ">=0.12" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" + "url": "https://github.com/sponsors/ljharb" } }, - "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==", + "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, "engines": { "node": ">=6" } }, - "node_modules/environment": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", - "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==", + "node_modules/caniuse-lite": { + "version": "1.0.30001770", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001770.tgz", + "integrity": "sha512-x/2CLQ1jHENRbHg5PSId2sXq1CIO1CISvwWAj027ltMVG2UNgW+w9oH2+HzgEIRFembL8bUlXtfbBHR1fCg2xw==", "dev": true, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/err-code": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", - "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", - "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/errno": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", - "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", + "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, - "optional": true, "dependencies": { - "prr": "~1.0.1" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, - "bin": { - "errno": "cli.js" - } - }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "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==", - "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==", "engines": { - "node": ">= 0.4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "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 + "node_modules/chardet": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-2.1.1.tgz", + "integrity": "sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==", + "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==", + "node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, "dependencies": { - "es-errors": "^1.3.0" + "readdirp": "^4.0.1" }, "engines": { - "node": ">= 0.4" + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "node_modules/esbuild": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.4.tgz", - "integrity": "sha512-8pgjLUcUjcgDg+2Q4NYXnPbo/vncAY4UmyaCm0jZevERqCHZIaWwdJHkf8XQtu4AxSKCdvrUbT0XUr1IdZzI8Q==", + "node_modules/chownr": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", "dev": true, - "hasInstallScript": true, - "bin": { - "esbuild": "bin/esbuild" - }, + "license": "BlueOak-1.0.0", "engines": { "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.4", - "@esbuild/android-arm": "0.25.4", - "@esbuild/android-arm64": "0.25.4", - "@esbuild/android-x64": "0.25.4", - "@esbuild/darwin-arm64": "0.25.4", - "@esbuild/darwin-x64": "0.25.4", - "@esbuild/freebsd-arm64": "0.25.4", - "@esbuild/freebsd-x64": "0.25.4", - "@esbuild/linux-arm": "0.25.4", - "@esbuild/linux-arm64": "0.25.4", - "@esbuild/linux-ia32": "0.25.4", - "@esbuild/linux-loong64": "0.25.4", - "@esbuild/linux-mips64el": "0.25.4", - "@esbuild/linux-ppc64": "0.25.4", - "@esbuild/linux-riscv64": "0.25.4", - "@esbuild/linux-s390x": "0.25.4", - "@esbuild/linux-x64": "0.25.4", - "@esbuild/netbsd-arm64": "0.25.4", - "@esbuild/netbsd-x64": "0.25.4", - "@esbuild/openbsd-arm64": "0.25.4", - "@esbuild/openbsd-x64": "0.25.4", - "@esbuild/sunos-x64": "0.25.4", - "@esbuild/win32-arm64": "0.25.4", - "@esbuild/win32-ia32": "0.25.4", - "@esbuild/win32-x64": "0.25.4" - } - }, - "node_modules/esbuild-wasm": { - "version": "0.25.4", - "resolved": "https://registry.npmjs.org/esbuild-wasm/-/esbuild-wasm-0.25.4.tgz", - "integrity": "sha512-2HlCS6rNvKWaSKhWaG/YIyRsTsL3gUrMP2ToZMBIjw9LM7vVcIs+rz8kE2vExvTJgvM8OKPqNpcHawY/BQc/qQ==", + } + }, + "node_modules/cli-cursor": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", + "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", "dev": true, - "bin": { - "esbuild": "bin/esbuild" + "dependencies": { + "restore-cursor": "^5.0.0" }, "engines": { "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "node_modules/cli-spinners": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-3.4.0.tgz", + "integrity": "sha512-bXfOC4QcT1tKXGorxL3wbJm6XJPDqEnij2gQ2m7ESQuE+/z9YFIWnl/5RpTiKWbMq3EVKR4fRLJGn6DVfu0mpw==", "dev": true, + "license": "MIT", "engines": { - "node": ">=6" + "node": ">=18.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" - }, - "node_modules/eslint-scope": { + "node_modules/cli-truncate": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-5.1.1.tgz", + "integrity": "sha512-SroPvNHxUnk+vIW/dOSfNqdy1sPEFkrTk6TUtqLCnBlo3N7TNYYkzzN7uSD6+jVjrdO4+p8nH7JzH6cIvUem6A==", "dev": true, + "license": "MIT", "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" + "slice-ansi": "^7.1.0", + "string-width": "^8.0.0" }, "engines": { - "node": ">=8.0.0" + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "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==", + "node_modules/cli-truncate/node_modules/string-width": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.1.1.tgz", + "integrity": "sha512-KpqHIdDL9KwYk22wEOg/VIqYbrnLeSApsKT/bSj6Ez7pn3CftUiLAv2Lccpq1ALcpLV9UX1Ppn92npZWu2w/aw==", "dev": true, + "license": "MIT", "dependencies": { - "estraverse": "^5.2.0" + "get-east-asian-width": "^1.3.0", + "strip-ansi": "^7.1.0" }, "engines": { - "node": ">=4.0" + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/esrecurse/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "node_modules/cli-width": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", + "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", "dev": true, + "license": "ISC", "engines": { - "node": ">=4.0" + "node": ">= 12" } }, - "node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "node_modules/cliui": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-9.0.1.tgz", + "integrity": "sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==", "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^7.2.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" + }, "engines": { - "node": ">=4.0" + "node": ">=20" } }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "node_modules/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": ">=0.10.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, "engines": { - "node": ">= 0.6" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "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, + "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 }, - "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, + "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 + }, + "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==", "engines": { - "node": ">=0.8.x" + "node": ">= 10" } }, - "node_modules/exponential-backoff": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.2.tgz", - "integrity": "sha512-8QxYTVXUkuy7fIIoitQkPwGonB8F3Zj8eEO8Sqg9Zv/bkI7RJAzowee4gr81Hak/dUTpA2Z7VfQgoijjPNlUZA==", + "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 }, - "node_modules/express": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", - "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", - "dependencies": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.3", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.7.1", - "cookie-signature": "1.0.6", + "node_modules/connect": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", + "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==", + "dev": true, + "dependencies": { "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.3.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.3", - "methods": "~1.1.2", - "on-finished": "2.4.1", + "finalhandler": "1.1.2", "parseurl": "~1.3.3", - "path-to-regexp": "0.1.12", - "proxy-addr": "~2.0.7", - "qs": "6.13.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.19.0", - "serve-static": "1.16.2", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" + "utils-merge": "1.0.1" }, "engines": { "node": ">= 0.10.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" } }, - "node_modules/express/node_modules/debug": { + "node_modules/connect/node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, "dependencies": { "ms": "2.0.0" } }, - "node_modules/express/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, - "node_modules/external-editor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", - "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "node_modules/connect/node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", "dev": true, - "dependencies": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" - }, "engines": { - "node": ">=4" + "node": ">= 0.8" } }, - "node_modules/external-editor/node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "node_modules/connect/node_modules/finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", "dev": true, "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.8" } }, - "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==", + "node_modules/connect/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true }, - "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==", + "node_modules/connect/node_modules/on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", "dev": true, "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" + "ee-first": "1.1.1" }, "engines": { - "node": ">=8.6.0" + "node": ">= 0.8" } }, - "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==", + "node_modules/connect/node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-disposition": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.1.tgz", + "integrity": "sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, "engines": { - "node": ">= 6" + "node": ">= 0.6" } }, - "node_modules/fast-uri": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz", - "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==", + "node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fastify" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fastify" - } - ] + "license": "MIT" }, - "node_modules/fastq": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", - "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "node_modules/cookie": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", "dev": true, - "dependencies": { - "reusify": "^1.0.4" + "license": "MIT", + "engines": { + "node": ">= 0.6" } }, - "node_modules/faye-websocket": { - "version": "0.11.4", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", - "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "node_modules/cookie-signature": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", + "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", "dev": true, - "dependencies": { - "websocket-driver": ">=0.5.1" - }, + "license": "MIT", "engines": { - "node": ">=0.8.0" + "node": ">=6.6.0" } }, - "node_modules/fdir": { - "version": "6.4.6", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.6.tgz", - "integrity": "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==", + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", "dev": true, - "peerDependencies": { - "picomatch": "^3 || ^4" + "dependencies": { + "object-assign": "^4", + "vary": "^1" }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } + "engines": { + "node": ">= 0.10" } }, - "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 - }, - "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==", + "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, "dependencies": { - "to-regex-range": "^5.0.1" + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" }, "engines": { - "node": ">=8" + "node": ">= 8" } }, - "node_modules/finalhandler": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", - "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", + "node_modules/cross-spawn/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, "dependencies": { - "debug": "2.6.9", - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" }, "engines": { - "node": ">= 0.8" - } - }, - "node_modules/finalhandler/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" + "node": ">= 8" } }, - "node_modules/finalhandler/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/find-cache-dir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-4.0.0.tgz", - "integrity": "sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg==", + "node_modules/css-select": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-6.0.0.tgz", + "integrity": "sha512-rZZVSLle8v0+EY8QAkDWrKhpgt6SA5OtHsgBnsj6ZaLb5dmDVOWUDtQitd9ydxxvEjhewNudS6eTVU7uOyzvXw==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "common-path-prefix": "^3.0.0", - "pkg-dir": "^7.0.0" - }, - "engines": { - "node": ">=14.16" + "boolbase": "^1.0.0", + "css-what": "^7.0.0", + "domhandler": "^5.0.3", + "domutils": "^3.2.2", + "nth-check": "^2.1.1" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/fb55" } }, - "node_modules/find-up": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", - "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", + "node_modules/css-what": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-7.0.0.tgz", + "integrity": "sha512-wD5oz5xibMOPHzy13CyGmogB3phdvcDaB5t0W/Nr5Z2O/agcB8YwOz6e2Lsp10pNDzBoDO9nVa3RGs/2BttpHQ==", "dev": true, - "dependencies": { - "locate-path": "^7.1.0", - "path-exists": "^5.0.0" - }, + "license": "BSD-2-Clause", "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">= 6" }, "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, - "bin": { - "flat": "cli.js" + "url": "https://github.com/sponsors/fb55" } }, - "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==", + "node_modules/custom-event": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz", + "integrity": "sha512-GAj5FOq0Hd+RsCGVJxZuKaIDXDf3h6GQoNEjFgbLLI/trgtavwUbSnZ5pVfg27DVCaWjIohryS0JFwIJyT2cMg==", "dev": true }, - "node_modules/follow-redirects": { - "version": "1.15.9", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", - "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "engines": { - "node": ">=4.0" + "node_modules/d3": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/d3/-/d3-7.9.0.tgz", + "integrity": "sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==", + "dependencies": { + "d3-array": "3", + "d3-axis": "3", + "d3-brush": "3", + "d3-chord": "3", + "d3-color": "3", + "d3-contour": "4", + "d3-delaunay": "6", + "d3-dispatch": "3", + "d3-drag": "3", + "d3-dsv": "3", + "d3-ease": "3", + "d3-fetch": "3", + "d3-force": "3", + "d3-format": "3", + "d3-geo": "3", + "d3-hierarchy": "3", + "d3-interpolate": "3", + "d3-path": "3", + "d3-polygon": "3", + "d3-quadtree": "3", + "d3-random": "3", + "d3-scale": "4", + "d3-scale-chromatic": "3", + "d3-selection": "3", + "d3-shape": "3", + "d3-time": "3", + "d3-time-format": "4", + "d3-timer": "3", + "d3-transition": "3", + "d3-zoom": "3" }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } + "engines": { + "node": ">=12" } }, - "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, + "node_modules/d3-array": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", + "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", "dependencies": { - "cross-spawn": "^7.0.6", - "signal-exit": "^4.0.1" + "internmap": "1 - 2" }, "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": ">=12" } }, - "node_modules/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "node_modules/d3-axis": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-3.0.0.tgz", + "integrity": "sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==", "engines": { - "node": ">= 0.6" + "node": ">=12" } }, - "node_modules/fraction.js": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", - "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", - "dev": true, + "node_modules/d3-brush": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-3.0.0.tgz", + "integrity": "sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-drag": "2 - 3", + "d3-interpolate": "1 - 3", + "d3-selection": "3", + "d3-transition": "3" + }, "engines": { - "node": "*" + "node": ">=12" + } + }, + "node_modules/d3-chord": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-3.0.1.tgz", + "integrity": "sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==", + "dependencies": { + "d3-path": "1 - 3" }, - "funding": { - "type": "patreon", - "url": "https://github.com/sponsors/rawify" + "engines": { + "node": ">=12" } }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "node_modules/d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", "engines": { - "node": ">= 0.6" + "node": ">=12" } }, - "node_modules/fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" + "node_modules/d3-contour": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-4.0.2.tgz", + "integrity": "sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==", + "dependencies": { + "d3-array": "^3.2.0" }, "engines": { - "node": ">=6 <7 || >=8" + "node": ">=12" } }, - "node_modules/fs-minipass": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz", - "integrity": "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==", - "dev": true, + "node_modules/d3-delaunay": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.4.tgz", + "integrity": "sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==", "dependencies": { - "minipass": "^7.0.3" + "delaunator": "5" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": ">=12" } }, - "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 - }, - "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, - "optional": true, - "os": [ - "darwin" - ], + "node_modules/d3-dispatch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz", + "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==", "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==", - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=12" } }, - "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, + "node_modules/d3-drag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz", + "integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-selection": "3" + }, "engines": { - "node": ">=6.9.0" + "node": ">=12" } }, - "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, + "node_modules/d3-dsv": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-3.0.1.tgz", + "integrity": "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==", + "dependencies": { + "commander": "7", + "iconv-lite": "0.6", + "rw": "1" + }, + "bin": { + "csv2json": "bin/dsv2json.js", + "csv2tsv": "bin/dsv2dsv.js", + "dsv2dsv": "bin/dsv2dsv.js", + "dsv2json": "bin/dsv2json.js", + "json2csv": "bin/json2dsv.js", + "json2dsv": "bin/json2dsv.js", + "json2tsv": "bin/json2dsv.js", + "tsv2csv": "bin/dsv2dsv.js", + "tsv2json": "bin/dsv2json.js" + }, "engines": { - "node": "6.* || 8.* || >= 10.*" + "node": ">=12" } }, - "node_modules/get-east-asian-width": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.3.0.tgz", - "integrity": "sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ==", - "dev": true, + "node_modules/d3-ease": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", + "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=12" } }, - "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==", + "node_modules/d3-fetch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-3.0.1.tgz", + "integrity": "sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==", "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" + "d3-dsv": "1 - 3" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=12" } }, - "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==", + "node_modules/d3-force": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz", + "integrity": "sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==", "dependencies": { - "dunder-proto": "^1.0.1", - "es-object-atoms": "^1.0.0" + "d3-dispatch": "1 - 3", + "d3-quadtree": "1 - 3", + "d3-timer": "1 - 3" }, "engines": { - "node": ">= 0.4" + "node": ">=12" } }, - "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, - "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" - }, + "node_modules/d3-format": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", + "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==", "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": ">=12" } }, - "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, + "node_modules/d3-geo": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.1.tgz", + "integrity": "sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==", "dependencies": { - "is-glob": "^4.0.3" + "d3-array": "2.5.0 - 3" }, "engines": { - "node": ">=10.13.0" + "node": ">=12" } }, - "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 + "node_modules/d3-hierarchy": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz", + "integrity": "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==", + "engines": { + "node": ">=12" + } }, - "node_modules/globby": { - "version": "14.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-14.1.0.tgz", - "integrity": "sha512-0Ia46fDOaT7k4og1PDW4YbodWWr3scS2vAr2lTbsplOt2WkKp0vQbkI9wKis/T5LV/dqPjO3bpS/z6GTJB82LA==", - "dev": true, + "node_modules/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", "dependencies": { - "@sindresorhus/merge-streams": "^2.1.0", - "fast-glob": "^3.3.3", - "ignore": "^7.0.3", - "path-type": "^6.0.0", - "slash": "^5.1.0", - "unicorn-magic": "^0.3.0" + "d3-color": "1 - 3" }, "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=12" } }, - "node_modules/gopd": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", - "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "node_modules/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=12" } }, - "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 - }, - "node_modules/handle-thing": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", - "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", - "dev": true - }, - "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, + "node_modules/d3-polygon": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-3.0.1.tgz", + "integrity": "sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==", "engines": { - "node": ">=8" + "node": ">=12" } }, - "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==", + "node_modules/d3-quadtree": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.1.tgz", + "integrity": "sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==", "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=12" } }, - "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, - "dependencies": { - "has-symbols": "^1.0.3" - }, + "node_modules/d3-random": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-3.0.1.tgz", + "integrity": "sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==", "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=12" } }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "node_modules/d3-scale": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", + "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", "dependencies": { - "function-bind": "^1.1.2" + "d3-array": "2.10.0 - 3", + "d3-format": "1 - 3", + "d3-interpolate": "1.2.0 - 3", + "d3-time": "2.1.1 - 3", + "d3-time-format": "2 - 4" }, "engines": { - "node": ">= 0.4" + "node": ">=12" } }, - "node_modules/hosted-git-info": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-8.1.0.tgz", - "integrity": "sha512-Rw/B2DNQaPBICNXEm8balFz9a6WpZrkCGpcWFpy7nCj+NyhSdqXipmfvtmWt9xGfp0wZnBxB+iVpLmQMYt47Tw==", - "dev": true, + "node_modules/d3-scale-chromatic": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz", + "integrity": "sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==", "dependencies": { - "lru-cache": "^10.0.1" + "d3-color": "1 - 3", + "d3-interpolate": "1 - 3" }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": ">=12" } }, - "node_modules/hosted-git-info/node_modules/lru-cache": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "dev": true - }, - "node_modules/hpack.js": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", - "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", - "dev": true, - "dependencies": { - "inherits": "^2.0.1", - "obuf": "^1.0.0", - "readable-stream": "^2.0.1", - "wbuf": "^1.1.0" + "node_modules/d3-selection": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", + "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", + "engines": { + "node": ">=12" } }, - "node_modules/hpack.js/node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dev": true, + "node_modules/d3-shape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", + "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" + "d3-path": "^3.1.0" + }, + "engines": { + "node": ">=12" } }, - "node_modules/hpack.js/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "node_modules/hpack.js/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, + "node_modules/d3-time": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", + "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", "dependencies": { - "safe-buffer": "~5.1.0" + "d3-array": "2 - 3" + }, + "engines": { + "node": ">=12" } }, - "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 - }, - "node_modules/htmlparser2": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-10.0.0.tgz", - "integrity": "sha512-TwAZM+zE5Tq3lrEHvOlvwgj1XLWQCtaaibSN11Q+gGBAS7Y1uZSWwXXRe4iF6OXnaq1riyQAPFOBtYc77Mxq0g==", - "dev": true, - "funding": [ - "https://github.com/fb55/htmlparser2?sponsor=1", - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], + "node_modules/d3-time-format": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", + "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", "dependencies": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3", - "domutils": "^3.2.1", - "entities": "^6.0.0" + "d3-time": "1 - 3" + }, + "engines": { + "node": ">=12" } }, - "node_modules/htmlparser2/node_modules/entities": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", - "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", - "dev": true, + "node_modules/d3-timer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", + "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" + "node": ">=12" } }, - "node_modules/http-cache-semantics": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", - "integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==", - "dev": true - }, - "node_modules/http-deceiver": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", - "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==", - "dev": true - }, - "node_modules/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "node_modules/d3-transition": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz", + "integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==", "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" + "d3-color": "1 - 3", + "d3-dispatch": "1 - 3", + "d3-ease": "1 - 3", + "d3-interpolate": "1 - 3", + "d3-timer": "1 - 3" }, "engines": { - "node": ">= 0.8" + "node": ">=12" + }, + "peerDependencies": { + "d3-selection": "2 - 3" } }, - "node_modules/http-parser-js": { - "version": "0.5.10", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.10.tgz", - "integrity": "sha512-Pysuw9XpUq5dVc/2SMHpuTY01RFl8fttgcyunjL7eEMhGM3cI4eOmiCycJDVCo/7O7ClfQD3SaI6ftDzqOXYMA==", - "dev": true - }, - "node_modules/http-proxy": { - "version": "1.18.1", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", - "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", - "dev": true, + "node_modules/d3-zoom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz", + "integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==", "dependencies": { - "eventemitter3": "^4.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" + "d3-dispatch": "1 - 3", + "d3-drag": "2 - 3", + "d3-interpolate": "1 - 3", + "d3-selection": "2 - 3", + "d3-transition": "2 - 3" }, "engines": { - "node": ">=8.0.0" + "node": ">=12" } }, - "node_modules/http-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", - "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "node_modules/date-format": { + "version": "4.0.14", + "resolved": "https://registry.npmjs.org/date-format/-/date-format-4.0.14.tgz", + "integrity": "sha512-39BOQLs9ZjKh0/patS9nrT8wc3ioX3/eA/zgbKNopnF2wCqJEoxywwwElATYvRsXdnOxA/OQeQoFZ3rFjVajhg==", "dev": true, - "dependencies": { - "agent-base": "^7.1.0", - "debug": "^4.3.4" - }, "engines": { - "node": ">= 14" + "node": ">=4.0" } }, - "node_modules/http-proxy-middleware": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-3.0.5.tgz", - "integrity": "sha512-GLZZm1X38BPY4lkXA01jhwxvDoOkkXqjgVyUzVxiEK4iuRu03PZoYHhHRwxnfhQMDuaxi3vVri0YgSro/1oWqg==", + "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": { - "@types/http-proxy": "^1.17.15", - "debug": "^4.3.6", - "http-proxy": "^1.18.1", - "is-glob": "^4.0.3", - "is-plain-object": "^5.0.0", - "micromatch": "^4.0.8" + "ms": "^2.1.3" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/https-proxy-agent": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", - "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "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/delaunator": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.0.1.tgz", + "integrity": "sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==", "dependencies": { - "agent-base": "^7.1.2", - "debug": "4" - }, - "engines": { - "node": ">= 14" + "robust-predicates": "^3.0.2" } }, - "node_modules/hyperdyperid": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/hyperdyperid/-/hyperdyperid-1.2.0.tgz", - "integrity": "sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A==", + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", "dev": true, "engines": { - "node": ">=10.18" + "node": ">= 0.8" } }, - "node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" } }, - "node_modules/icss-utils": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", - "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", "dev": true, + "license": "Apache-2.0", + "optional": true, "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" + "node": ">=8" } }, - "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" - } - ] + "node_modules/di": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz", + "integrity": "sha512-uJaamHkagcZtHPqCIHZxnFrXlunQXgBOsZSUOWwFw31QJCAbyTBoHMW75YOTur5ZNx8pIeAKgf6GWIgaqqiLhA==", + "dev": true }, - "node_modules/ignore": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", - "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "node_modules/dom-serialize": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz", + "integrity": "sha512-Yra4DbvoW7/Z6LBN560ZwXMjoNOSAN2wRsKFGc4iBeso+mpIA6qj1vfdf9HpMaKAqG6wXTy+1SYEzmNpKXOSsQ==", "dev": true, - "engines": { - "node": ">= 4" + "dependencies": { + "custom-event": "~1.0.0", + "ent": "~2.2.0", + "extend": "^3.0.0", + "void-elements": "^2.0.0" } }, - "node_modules/ignore-walk": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-7.0.0.tgz", - "integrity": "sha512-T4gbf83A4NH95zvhVYZc+qWocBBGlpzUXLPGurJggw/WIOwicfXJChLDP/iBZnN5WqROSu5Bm3hhle4z8a8YGQ==", + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", "dev": true, + "license": "MIT", "dependencies": { - "minimatch": "^9.0.0" + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" }, - "engines": { - "node": "^18.17.0 || >=20.5.0" + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" } }, - "node_modules/ignore-walk/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==", + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" }, - "node_modules/ignore-walk/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "brace-expansion": "^2.0.1" + "domelementtype": "^2.3.0" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": ">= 4" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/fb55/domhandler?sponsor=1" } }, - "node_modules/image-size": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz", - "integrity": "sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==", + "node_modules/domutils": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", + "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", "dev": true, - "optional": true, - "bin": { - "image-size": "bin/image-size.js" + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" }, - "engines": { - "node": ">=0.10.0" + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" } }, - "node_modules/immutable": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.3.tgz", - "integrity": "sha512-+chQdDfvscSF1SJqv2gn4SRO2ZyS3xL3r7IW/wWEEzrzLisnOlKiQu5ytC/BVNcS15C39WT2Hg/bjKjDMcu+zg==", - "dev": true - }, - "node_modules/import-fresh": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", - "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "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, "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" }, "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 0.4" } }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, - "engines": { - "node": ">=0.8.19" - } + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "dev": true }, - "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.", + "node_modules/electron-to-chromium": { + "version": "1.5.286", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.286.tgz", + "integrity": "sha512-9tfDXhJ4RKFNerfjdCcZfufu49vg620741MNs26a9+bhLThdB+plgMeou98CAaHu/WATj2iHOOHTp1hWtABj2A==", "dev": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } + "license": "ISC" }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + "node_modules/emoji-regex": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz", + "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==", + "dev": true }, - "node_modules/ini": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ini/-/ini-5.0.0.tgz", - "integrity": "sha512-+N0ngpO3e7cRUWOJAS7qw0IZIVc6XPrW4MlFBdD066F2L4k1L6ker3hLqSq7iXxU5tgS4WGkIUElWn5vogAEnw==", + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", "dev": true, + "license": "MIT", "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/internmap": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", - "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", - "engines": { - "node": ">=12" + "node": ">= 0.8" } }, - "node_modules/ip-address": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", - "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", + "node_modules/encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", "dev": true, + "license": "MIT", + "optional": true, "dependencies": { - "jsbn": "1.1.0", - "sprintf-js": "^1.1.3" - }, - "engines": { - "node": ">= 12" - } - }, - "node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "engines": { - "node": ">= 0.10" + "iconv-lite": "^0.6.2" } }, - "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 - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "node_modules/engine.io": { + "version": "6.6.4", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.6.4.tgz", + "integrity": "sha512-ZCkIjSYNDyGn0R6ewHDtXgns/Zre/NT6Agvq1/WobF7JXgFff4SeDroKiCO3fNJreU9YG429Sc81o4w5ok/W5g==", "dev": true, "dependencies": { - "binary-extensions": "^2.0.0" + "@types/cors": "^2.8.12", + "@types/node": ">=10.0.0", + "accepts": "~1.3.4", + "base64id": "2.0.0", + "cookie": "~0.7.2", + "cors": "~2.8.5", + "debug": "~4.3.1", + "engine.io-parser": "~5.2.1", + "ws": "~8.17.1" }, "engines": { - "node": ">=8" + "node": ">=10.2.0" } }, - "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==", + "node_modules/engine.io-parser": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz", + "integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==", "dev": true, - "dependencies": { - "hasown": "^2.0.2" - }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=10.0.0" } }, - "node_modules/is-docker": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", - "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "node_modules/engine.io/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "dev": true, - "bin": { - "is-docker": "cli.js" + "dependencies": { + "ms": "^2.1.3" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=6.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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, - "engines": { - "node": ">=0.10.0" + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/is-fullwidth-code-point": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", - "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", + "node_modules/engine.io/node_modules/ws": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", "dev": true, "engines": { - "node": ">=12" + "node": ">=10.0.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } } }, - "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==", + "node_modules/ent": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.2.tgz", + "integrity": "sha512-kKvD1tO6BM+oK9HzCPpUdRb4vKFQY/FPTFmurMvh6LlN68VMrdj77w8yp51/kDbpkFOS9J8w5W6zIzgM2H8/hw==", "dev": true, "dependencies": { - "is-extglob": "^2.1.1" + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "punycode": "^1.4.1", + "safe-regex-test": "^1.1.0" }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" } }, - "node_modules/is-inside-container": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", - "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", - "dev": true, - "dependencies": { - "is-docker": "^3.0.0" - }, - "bin": { - "is-inside-container": "cli.js" - }, + "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": ">=14.16" + "node": ">=0.12" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/fb55/entities?sponsor=1" } }, - "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==", + "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, "engines": { - "node": ">=8" + "node": ">=6" } }, - "node_modules/is-network-error": { + "node_modules/environment": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-network-error/-/is-network-error-1.1.0.tgz", - "integrity": "sha512-tUdRRAnhT+OtCZR/LxZelH/C7QtjtFrTu5tXCA8pl55eTUElUHT+GPYV8MBMBvea/j+NxQqVt3LbWMRir7Gx9g==", + "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", + "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==", "dev": true, "engines": { - "node": ">=16" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "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==", + "node_modules/err-code": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", + "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", "dev": true, - "engines": { - "node": ">=0.12.0" - } + "license": "MIT" }, - "node_modules/is-plain-obj": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", - "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", + "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, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 0.4" } }, - "node_modules/is-plain-object": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "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, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" } }, - "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==", + "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, "dependencies": { - "call-bound": "^1.0.2", - "gopd": "^1.2.0", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.2" + "es-errors": "^1.3.0" }, "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==", + "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, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=6" } }, - "node_modules/is-what": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/is-what/-/is-what-3.14.1.tgz", - "integrity": "sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==", + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", "dev": true }, - "node_modules/is-wsl": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", - "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==", + "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, - "dependencies": { - "is-inside-container": "^1.0.0" - }, + "license": "MIT", "engines": { - "node": ">=16" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true - }, - "node_modules/isbinaryfile": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz", - "integrity": "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==", - "dev": true, + "node_modules/eslint": { + "version": "9.39.2", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.2.tgz", + "integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.21.1", + "@eslint/config-helpers": "^0.4.2", + "@eslint/core": "^0.17.0", + "@eslint/eslintrc": "^3.3.1", + "@eslint/js": "9.39.2", + "@eslint/plugin-kit": "^0.4.1", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "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": ">= 8.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://github.com/sponsors/gjtorikian/" + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } } }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "node_modules/isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "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, - "engines": { - "node": ">=0.10.0" + "license": "MIT", + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "funding": { + "url": "https://opencollective.com/eslint-config-prettier" + }, + "peerDependencies": { + "eslint": ">=7.0.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==", + "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": ">=8" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "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==", + "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": { - "@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" + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" }, - "engines": { - "node": ">=10" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "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==", + "node_modules/eslint/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": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^4.0.0", - "supports-color": "^7.1.0" + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" }, "engines": { - "node": ">=10" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "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==", + "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, - "dependencies": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - }, + "license": "Apache-2.0", "engines": { - "node": ">=10" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/istanbul-lib-source-maps/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==", + "node_modules/eslint/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": ">=0.10.0" + "node": ">=4.0" } }, - "node_modules/istanbul-reports": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", - "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", + "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, - "dependencies": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - }, + "license": "MIT", "engines": { - "node": ">=8" + "node": ">= 4" } }, - "node_modules/jackspeak": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", - "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "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/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": { - "@isaacs/cliui": "^8.0.2" + "acorn": "^8.15.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.1" }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/jasmine-core": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-5.6.0.tgz", - "integrity": "sha512-niVlkeYVRwKFpmfWg6suo6H9CrNnydfBLEqefM5UjibYS+UoTjZdmvPJSiuyrRLGnFj1eYRhFd/ch+5hSlsFVA==", - "dev": true - }, - "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==", + "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, - "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, + "license": "Apache-2.0", "engines": { - "node": ">= 10.13.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "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==", + "node_modules/esquery": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", + "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { - "has-flag": "^4.0.0" + "estraverse": "^5.1.0" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" + "node": ">=0.10" } }, - "node_modules/jiti": { - "version": "1.21.7", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz", - "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", + "node_modules/esquery/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, - "bin": { - "jiti": "bin/jiti.js" + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" } }, - "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 - }, - "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==", + "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, "dependencies": { - "argparse": "^2.0.1" + "estraverse": "^5.2.0" }, - "bin": { - "js-yaml": "bin/js-yaml.js" + "engines": { + "node": ">=4.0" } }, - "node_modules/jsbn": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", - "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", - "dev": true + "node_modules/esrecurse/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, + "engines": { + "node": ">=4.0" + } }, - "node_modules/jsesc": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", - "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "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, - "bin": { - "jsesc": "bin/jsesc" - }, "engines": { - "node": ">=6" + "node": ">=0.10.0" } }, - "node_modules/json-parse-even-better-errors": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-4.0.0.tgz", - "integrity": "sha512-lR4MXjGNgkJc7tkQ97kb2nuEMnNCyU//XYVH0MKTGcXEiSudQ5MKGKen3C5QubYy0vmq+JGitUg92uuywGEwIA==", + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", "dev": true, + "license": "MIT", "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": ">= 0.6" } }, - "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==", + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", "dev": true }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "node_modules/eventsource": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-3.0.7.tgz", + "integrity": "sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==", "dev": true, - "bin": { - "json5": "lib/cli.js" + "license": "MIT", + "dependencies": { + "eventsource-parser": "^3.0.1" }, "engines": { - "node": ">=6" + "node": ">=18.0.0" } }, - "node_modules/jsonc-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", - "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", - "dev": true - }, - "node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "node_modules/eventsource-parser": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.6.tgz", + "integrity": "sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==", "dev": true, - "optionalDependencies": { - "graceful-fs": "^4.1.6" + "license": "MIT", + "engines": { + "node": ">=18.0.0" } }, - "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==", + "node_modules/exponential-backoff": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.3.tgz", + "integrity": "sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA==", "dev": true, - "engines": [ - "node >= 0.2.0" - ] + "license": "Apache-2.0" }, - "node_modules/karma": { - "version": "6.4.4", - "resolved": "https://registry.npmjs.org/karma/-/karma-6.4.4.tgz", - "integrity": "sha512-LrtUxbdvt1gOpo3gxG+VAJlJAEMhbWlM4YrFQgql98FwF7+K8K12LYO4hnDdUkNjeztYrOXEMqgTajSWgmtI/w==", - "dev": true, - "dependencies": { - "@colors/colors": "1.5.0", - "body-parser": "^1.19.0", - "braces": "^3.0.2", - "chokidar": "^3.5.1", - "connect": "^3.7.0", - "di": "^0.0.1", - "dom-serialize": "^2.2.1", - "glob": "^7.1.7", - "graceful-fs": "^4.2.6", - "http-proxy": "^1.18.1", - "isbinaryfile": "^4.0.8", - "lodash": "^4.17.21", - "log4js": "^6.4.1", - "mime": "^2.5.2", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.5", - "qjobs": "^1.2.0", + "node_modules/express": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz", + "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "accepts": "^2.0.0", + "body-parser": "^2.2.1", + "content-disposition": "^1.0.0", + "content-type": "^1.0.5", + "cookie": "^0.7.1", + "cookie-signature": "^1.2.1", + "debug": "^4.4.0", + "depd": "^2.0.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "finalhandler": "^2.1.0", + "fresh": "^2.0.0", + "http-errors": "^2.0.0", + "merge-descriptors": "^2.0.0", + "mime-types": "^3.0.0", + "on-finished": "^2.4.1", + "once": "^1.4.0", + "parseurl": "^1.3.3", + "proxy-addr": "^2.0.7", + "qs": "^6.14.0", "range-parser": "^1.2.1", - "rimraf": "^3.0.2", - "socket.io": "^4.7.2", - "source-map": "^0.6.1", - "tmp": "^0.2.1", - "ua-parser-js": "^0.7.30", - "yargs": "^16.1.1" - }, - "bin": { - "karma": "bin/karma" + "router": "^2.2.0", + "send": "^1.1.0", + "serve-static": "^2.2.0", + "statuses": "^2.0.1", + "type-is": "^2.0.1", + "vary": "^1.1.2" }, "engines": { - "node": ">= 10" + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/karma-chrome-launcher": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-3.2.0.tgz", - "integrity": "sha512-rE9RkUPI7I9mAxByQWkGJFXfFD6lE4gC5nPuZdobf/QdTEJI6EU4yIay/cfU/xV4ZxlM5JiTv7zWYgA64NpS5Q==", + "node_modules/express-rate-limit": { + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.2.1.tgz", + "integrity": "sha512-PCZEIEIxqwhzw4KF0n7QF4QqruVTcF73O5kFKUnGOyjbCCgizBBiFaYpd/fnBLUMPw/BWw9OsiN7GgrNYr7j6g==", "dev": true, + "license": "MIT", "dependencies": { - "which": "^1.2.1" + "ip-address": "10.0.1" + }, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/express-rate-limit" + }, + "peerDependencies": { + "express": ">= 4.11" } }, - "node_modules/karma-coverage": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/karma-coverage/-/karma-coverage-2.2.1.tgz", - "integrity": "sha512-yj7hbequkQP2qOSb20GuNSIyE//PgJWHwC2IydLE6XRtsnaflv+/OSGNssPjobYUlhVVagy99TQpqUt3vAUG7A==", + "node_modules/express/node_modules/accepts": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", + "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", "dev": true, + "license": "MIT", "dependencies": { - "istanbul-lib-coverage": "^3.2.0", - "istanbul-lib-instrument": "^5.1.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.1", - "istanbul-reports": "^3.0.5", - "minimatch": "^3.0.4" + "mime-types": "^3.0.0", + "negotiator": "^1.0.0" }, "engines": { - "node": ">=10.0.0" + "node": ">= 0.6" } }, - "node_modules/karma-coverage/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==", + "node_modules/express/node_modules/body-parser": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.2.tgz", + "integrity": "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==", "dev": true, + "license": "MIT", "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" + "bytes": "^3.1.2", + "content-type": "^1.0.5", + "debug": "^4.4.3", + "http-errors": "^2.0.0", + "iconv-lite": "^0.7.0", + "on-finished": "^2.4.1", + "qs": "^6.14.1", + "raw-body": "^3.0.1", + "type-is": "^2.0.1" }, "engines": { - "node": ">=8" - } - }, - "node_modules/karma-coverage/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, - "bin": { - "semver": "bin/semver.js" + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/karma-jasmine": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/karma-jasmine/-/karma-jasmine-5.1.0.tgz", - "integrity": "sha512-i/zQLFrfEpRyQoJF9fsCdTMOF5c2dK7C7OmsuKg2D0YSsuZSfQDiLuaiktbuio6F2wiCsZSnSnieIQ0ant/uzQ==", + "node_modules/express/node_modules/iconv-lite": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz", + "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==", "dev": true, + "license": "MIT", "dependencies": { - "jasmine-core": "^4.1.0" + "safer-buffer": ">= 2.1.2 < 3.0.0" }, "engines": { - "node": ">=12" + "node": ">=0.10.0" }, - "peerDependencies": { - "karma": "^6.0.0" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/karma-jasmine-html-reporter": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/karma-jasmine-html-reporter/-/karma-jasmine-html-reporter-2.1.0.tgz", - "integrity": "sha512-sPQE1+nlsn6Hwb5t+HHwyy0A1FNCVKuL1192b+XNauMYWThz2kweiBVW1DqloRpVvZIJkIoHVB7XRpK78n1xbQ==", + "node_modules/express/node_modules/media-typer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", + "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", "dev": true, - "peerDependencies": { - "jasmine-core": "^4.0.0 || ^5.0.0", - "karma": "^6.0.0", - "karma-jasmine": "^5.0.0" + "license": "MIT", + "engines": { + "node": ">= 0.8" } }, - "node_modules/karma-jasmine/node_modules/jasmine-core": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-4.6.1.tgz", - "integrity": "sha512-VYz/BjjmC3klLJlLwA4Kw8ytk0zDSmbbDLNs794VnWmkcCB7I9aAL/D48VNQtmITyPvea2C3jdUMfc3kAoy0PQ==", - "dev": true + "node_modules/express/node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } }, - "node_modules/karma-source-map-support": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/karma-source-map-support/-/karma-source-map-support-1.4.0.tgz", - "integrity": "sha512-RsBECncGO17KAoJCYXjv+ckIz+Ii9NCi+9enk+rq6XC81ezYkb4/RHE6CTXdA7IOJqoF3wcaLfVG0CPmE5ca6A==", + "node_modules/express/node_modules/mime-types": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", "dev": true, + "license": "MIT", "dependencies": { - "source-map-support": "^0.5.5" + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/karma/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==", + "node_modules/express/node_modules/negotiator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", + "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", "dev": true, + "license": "MIT", "engines": { - "node": ">=8" + "node": ">= 0.6" } }, - "node_modules/karma/node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "node_modules/express/node_modules/qs": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.0.tgz", + "integrity": "sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" + "side-channel": "^1.1.0" }, "engines": { - "node": ">= 8.10.0" + "node": ">=0.6" }, "funding": { - "url": "https://paulmillr.com/funding/" + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/express/node_modules/raw-body": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz", + "integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "~3.1.2", + "http-errors": "~2.0.1", + "iconv-lite": "~0.7.0", + "unpipe": "~1.0.0" }, - "optionalDependencies": { - "fsevents": "~2.3.2" + "engines": { + "node": ">= 0.10" } }, - "node_modules/karma/node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "node_modules/express/node_modules/type-is": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", + "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", "dev": true, + "license": "MIT", "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" + "content-type": "^1.0.5", + "media-typer": "^1.1.0", + "mime-types": "^3.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "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 + }, + "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, + "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/karma/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 - }, - "node_modules/karma/node_modules/glob-parent": { + "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==", @@ -9361,1554 +7939,1630 @@ "node": ">= 6" } }, - "node_modules/karma/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==", + "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, - "engines": { - "node": ">=8" - } + "license": "MIT" }, - "node_modules/karma/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "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, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } + "license": "MIT" }, - "node_modules/karma/node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "node_modules/fast-uri": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz", + "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ] + }, + "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, "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" + "reusify": "^1.0.4" } }, - "node_modules/karma/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==", + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", "dev": true, + "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } } }, - "node_modules/karma/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==", + "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 + }, + "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": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" + "flat-cache": "^4.0.0" }, "engines": { - "node": ">=8" + "node": ">=16.0.0" } }, - "node_modules/karma/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==", + "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, "dependencies": { - "ansi-regex": "^5.0.1" + "to-regex-range": "^5.0.1" }, "engines": { "node": ">=8" } }, - "node_modules/karma/node_modules/tmp": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", - "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==", + "node_modules/finalhandler": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz", + "integrity": "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==", "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "on-finished": "^2.4.1", + "parseurl": "^1.3.3", + "statuses": "^2.0.1" + }, "engines": { - "node": ">=14.14" + "node": ">= 18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/karma/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==", + "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": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" }, "engines": { "node": ">=10" }, "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/karma/node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "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": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" + "flatted": "^3.2.9", + "keyv": "^4.5.4" }, "engines": { - "node": ">=10" + "node": ">=16" } }, - "node_modules/karma/node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "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 + }, + "node_modules/follow-redirects": { + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], "engines": { - "node": ">=10" + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } } }, - "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==", + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", "dev": true, + "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": ">= 0.6" } }, - "node_modules/launch-editor": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.10.0.tgz", - "integrity": "sha512-D7dBRJo/qcGX9xlvt/6wUYzQxjh5G1RvZPgPv8vi4KRU99DVQL/oW7tnVOCCTm2HGeo3C5HvGE5Yrh6UBoZ0vA==", + "node_modules/fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", + "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", "dev": true, - "dependencies": { - "picocolors": "^1.0.0", - "shell-quote": "^1.8.1" + "license": "MIT", + "engines": { + "node": ">= 0.8" } }, - "node_modules/less": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/less/-/less-4.2.2.tgz", - "integrity": "sha512-tkuLHQlvWUTeQ3doAqnHbNn8T6WX1KA8yvbKG9x4VtKtIjHsVKQZCH11zRgAfbDAXC2UNIg/K9BYAAcEzUIrNg==", + "node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", "dev": true, "dependencies": { - "copy-anything": "^2.0.1", - "parse-node-version": "^1.0.1", - "tslib": "^2.3.0" - }, - "bin": { - "lessc": "bin/lessc" + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" }, "engines": { - "node": ">=6" - }, - "optionalDependencies": { - "errno": "^0.1.1", - "graceful-fs": "^4.1.2", - "image-size": "~0.5.0", - "make-dir": "^2.1.0", - "mime": "^1.4.1", - "needle": "^3.1.0", - "source-map": "~0.6.0" + "node": ">=6 <7 || >=8" } }, - "node_modules/less-loader": { - "version": "12.2.0", - "resolved": "https://registry.npmjs.org/less-loader/-/less-loader-12.2.0.tgz", - "integrity": "sha512-MYUxjSQSBUQmowc0l5nPieOYwMzGPUaTzB6inNW/bdPEG9zOL3eAAD1Qw5ZxSPk7we5dMojHwNODYMV1hq4EVg==", + "node_modules/fs-minipass": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz", + "integrity": "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==", "dev": true, - "engines": { - "node": ">= 18.12.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "@rspack/core": "0.x || 1.x", - "less": "^3.5.0 || ^4.0.0", - "webpack": "^5.0.0" + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" }, - "peerDependenciesMeta": { - "@rspack/core": { - "optional": true - }, - "webpack": { - "optional": true - } + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/less/node_modules/make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "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 + }, + "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, "optional": true, - "dependencies": { - "pify": "^4.0.1", - "semver": "^5.6.0" - }, + "os": [ + "darwin" + ], "engines": { - "node": ">=6" + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "node_modules/less/node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "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, - "optional": true, - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/less/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "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, - "optional": true, - "bin": { - "semver": "bin/semver" + "engines": { + "node": ">=6.9.0" } }, - "node_modules/less/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==", + "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, - "optional": true, "engines": { - "node": ">=0.10.0" + "node": "6.* || 8.* || >= 10.*" } }, - "node_modules/license-webpack-plugin": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/license-webpack-plugin/-/license-webpack-plugin-4.0.2.tgz", - "integrity": "sha512-771TFWFD70G1wLTC4oU2Cw4qvtmNrIw+wRvBtn+okgHl7slJVi7zfNcdmqDL72BojM30VNJ2UHylr1o77U37Jw==", + "node_modules/get-east-asian-width": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.4.0.tgz", + "integrity": "sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==", "dev": true, - "dependencies": { - "webpack-sources": "^3.0.0" + "license": "MIT", + "engines": { + "node": ">=18" }, - "peerDependenciesMeta": { - "webpack": { - "optional": true - }, - "webpack-sources": { - "optional": true - } + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "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 - }, - "node_modules/listr2": { - "version": "8.2.5", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-8.2.5.tgz", - "integrity": "sha512-iyAZCeyD+c1gPyE9qpFu8af0Y+MRtmKOncdGoA2S5EY8iFq99dmmvkNnHiWo+pj0s7yH7l3KPIgee77tKpXPWQ==", + "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, "dependencies": { - "cli-truncate": "^4.0.0", - "colorette": "^2.0.20", - "eventemitter3": "^5.0.1", - "log-update": "^6.1.0", - "rfdc": "^1.4.1", - "wrap-ansi": "^9.0.0" + "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": ">=18.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/listr2/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "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, - "engines": { - "node": ">=12" + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "engines": { + "node": ">= 0.4" } }, - "node_modules/listr2/node_modules/eventemitter3": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", - "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", - "dev": true - }, - "node_modules/listr2/node_modules/wrap-ansi": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", - "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", + "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, "dependencies": { - "ansi-styles": "^6.2.1", - "string-width": "^7.0.0", - "strip-ansi": "^7.1.0" + "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": ">=18" + "node": "*" }, "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/lmdb": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/lmdb/-/lmdb-3.2.6.tgz", - "integrity": "sha512-SuHqzPl7mYStna8WRotY8XX/EUZBjjv3QyKIByeCLFfC9uXT/OIHByEcA07PzbMfQAM0KYJtLgtpMRlIe5dErQ==", + "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, - "hasInstallScript": true, - "optional": true, "dependencies": { - "msgpackr": "^1.11.2", - "node-addon-api": "^6.1.0", - "node-gyp-build-optional-packages": "5.2.2", - "ordered-binary": "^1.5.3", - "weak-lru-cache": "^1.2.2" - }, - "bin": { - "download-lmdb-prebuilds": "bin/download-prebuilds.js" + "is-glob": "^4.0.3" }, - "optionalDependencies": { - "@lmdb/lmdb-darwin-arm64": "3.2.6", - "@lmdb/lmdb-darwin-x64": "3.2.6", - "@lmdb/lmdb-linux-arm": "3.2.6", - "@lmdb/lmdb-linux-arm64": "3.2.6", - "@lmdb/lmdb-linux-x64": "3.2.6", - "@lmdb/lmdb-win32-x64": "3.2.6" + "engines": { + "node": ">=10.13.0" } }, - "node_modules/loader-runner": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", - "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "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, - "engines": { - "node": ">=6.11.5" - } + "license": "BSD-2-Clause" }, - "node_modules/loader-utils": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.3.1.tgz", - "integrity": "sha512-FMJTLMXfCLMLfJxcX9PFqX5qD88Z5MRGaZCVzfuqeZSPsyiBzs+pahDQjbIWz2QIzPZz0NX9Zy4FX3lmK6YHIg==", + "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": ">= 12.13.0" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "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==", + "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, - "dependencies": { - "p-locate": "^6.0.0" - }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "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 }, - "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 + "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/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==", + "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, - "dependencies": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - }, "engines": { - "node": ">=10" + "node": ">=8" + } + }, + "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, + "engines": { + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/log-update": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.1.0.tgz", - "integrity": "sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==", + "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, "dependencies": { - "ansi-escapes": "^7.0.0", - "cli-cursor": "^5.0.0", - "slice-ansi": "^7.1.0", - "strip-ansi": "^7.1.0", - "wrap-ansi": "^9.0.0" + "has-symbols": "^1.0.3" }, "engines": { - "node": ">=18" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/log-update/node_modules/ansi-escapes": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.0.0.tgz", - "integrity": "sha512-GdYO7a61mR0fOlAsvC9/rIHf7L96sBc6dEWzeOu+KAea5bZyQRPIpojrVoI4AXGJS/ycu/fBTdLrUkA4ODrvjw==", + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "dev": true, "dependencies": { - "environment": "^1.0.0" + "function-bind": "^1.1.2" }, "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 0.4" } }, - "node_modules/log-update/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "node_modules/hono": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/hono/-/hono-4.11.9.tgz", + "integrity": "sha512-Eaw2YTGM6WOxA6CXbckaEvslr2Ne4NFsKrvc0v97JD5awbmeBLO5w9Ho9L9kmKonrwF9RJlW6BxT1PVv/agBHQ==", "dev": true, + "license": "MIT", "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "node": ">=16.9.0" } }, - "node_modules/log-update/node_modules/is-fullwidth-code-point": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.0.0.tgz", - "integrity": "sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==", + "node_modules/hosted-git-info": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-9.0.2.tgz", + "integrity": "sha512-M422h7o/BR3rmCQ8UHi7cyyMqKltdP9Uo+J2fXK+RSAY+wTcKOIRyhTuKv4qn+DJf3g+PL890AzId5KZpX+CBg==", "dev": true, + "license": "ISC", "dependencies": { - "get-east-asian-width": "^1.0.0" + "lru-cache": "^11.1.0" }, "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/log-update/node_modules/slice-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.0.tgz", - "integrity": "sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==", + "node_modules/hosted-git-info/node_modules/lru-cache": { + "version": "11.2.6", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.6.tgz", + "integrity": "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "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 + }, + "node_modules/htmlparser2": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-10.1.0.tgz", + "integrity": "sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ==", "dev": true, + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", "dependencies": { - "ansi-styles": "^6.2.1", - "is-fullwidth-code-point": "^5.0.0" - }, + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.2.2", + "entities": "^7.0.1" + } + }, + "node_modules/htmlparser2/node_modules/entities": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz", + "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==", + "dev": true, + "license": "BSD-2-Clause", "engines": { - "node": ">=18" + "node": ">=0.12" }, "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" + "url": "https://github.com/fb55/entities?sponsor=1" } }, - "node_modules/log-update/node_modules/wrap-ansi": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", - "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", + "node_modules/http-cache-semantics": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", + "integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==", "dev": true, - "dependencies": { - "ansi-styles": "^6.2.1", - "string-width": "^7.0.0", - "strip-ansi": "^7.1.0" + "license": "BSD-2-Clause" + }, + "node_modules/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" }, "engines": { - "node": ">=18" + "node": ">= 0.8" }, "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/log4js": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/log4js/-/log4js-6.9.1.tgz", - "integrity": "sha512-1somDdy9sChrr9/f4UlzhdaGfDR2c/SaD2a4T7qEkG4jTS57/B3qmnjLYePwQ8cqWnUHZI0iAKxMBpCZICiZ2g==", + "node_modules/http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", "dev": true, "dependencies": { - "date-format": "^4.0.14", - "debug": "^4.3.4", - "flatted": "^3.2.7", - "rfdc": "^1.3.0", - "streamroller": "^3.1.5" + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" }, "engines": { - "node": ">=8.0" + "node": ">=8.0.0" } }, - "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==", + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", "dev": true, + "license": "MIT", "dependencies": { - "yallist": "^3.0.2" + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" } }, - "node_modules/magic-string": { - "version": "0.30.17", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", - "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", "dev": true, + "license": "MIT", "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0" + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" } }, - "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==", + "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, - "dependencies": { - "semver": "^7.5.3" + "license": "MIT", + "bin": { + "husky": "bin.js" }, "engines": { - "node": ">=10" + "node": ">=18" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/typicode" } }, - "node_modules/make-fetch-happen": { - "version": "14.0.3", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-14.0.3.tgz", - "integrity": "sha512-QMjGbFTP0blj97EeidG5hk/QhKQ3T4ICckQGLgz38QF7Vgbk6e6FTARN8KhKxyBbWn8R0HU+bnw8aSoFPD4qtQ==", - "dev": true, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", "dependencies": { - "@npmcli/agent": "^3.0.0", - "cacache": "^19.0.1", - "http-cache-semantics": "^4.1.1", - "minipass": "^7.0.2", - "minipass-fetch": "^4.0.0", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "negotiator": "^1.0.0", - "proc-log": "^5.0.0", - "promise-retry": "^2.0.1", - "ssri": "^12.0.0" + "safer-buffer": ">= 2.1.2 < 3.0.0" }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": ">=0.10.0" } }, - "node_modules/make-fetch-happen/node_modules/negotiator": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", - "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", + "node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", "dev": true, "engines": { - "node": ">= 0.6" + "node": ">= 4" } }, - "node_modules/material-icons": { - "version": "1.13.14", - "resolved": "https://registry.npmjs.org/material-icons/-/material-icons-1.13.14.tgz", - "integrity": "sha512-kZOfc7xCC0rAT8Q3DQixYAeT+tBqZnxkseQtp2bxBxz7q5pMAC+wmit7vJn1g/l7wRU+HEPq23gER4iPjGs5Cg==" - }, - "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==", + "node_modules/ignore-walk": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-8.0.0.tgz", + "integrity": "sha512-FCeMZT4NiRQGh+YkeKMtWrOmBgWjHjMJ26WQWrRQyoyzqevdaGSakUaJW5xQYmjLlUVk2qUnCjYVBax9EKKg8A==", + "dev": true, + "license": "ISC", + "dependencies": { + "minimatch": "^10.0.3" + }, "engines": { - "node": ">= 0.4" + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "node_modules/ignore-walk/node_modules/balanced-match": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.2.tgz", + "integrity": "sha512-x0K50QvKQ97fdEz2kPehIerj+YTeptKF9hyYkKf6egnwmMWAkADiO0QCzSp0R5xN8FTZgYaBfSaue46Ej62nMg==", + "dev": true, + "license": "MIT", + "dependencies": { + "jackspeak": "^4.2.3" + }, "engines": { - "node": ">= 0.6" + "node": "20 || >=22" } }, - "node_modules/memfs": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.17.2.tgz", - "integrity": "sha512-NgYhCOWgovOXSzvYgUW0LQ7Qy72rWQMGGFJDoWg4G30RHd3z77VbYdtJ4fembJXBy8pMIUA31XNAupobOQlwdg==", + "node_modules/ignore-walk/node_modules/brace-expansion": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.2.tgz", + "integrity": "sha512-Pdk8c9poy+YhOgVWw1JNN22/HcivgKWwpxKq04M/jTmHyCZn12WPJebZxdjSa5TmBqISrUSgNYU3eRORljfCCw==", "dev": true, + "license": "MIT", "dependencies": { - "@jsonjoy.com/json-pack": "^1.0.3", - "@jsonjoy.com/util": "^1.3.0", - "tree-dump": "^1.0.1", - "tslib": "^2.0.0" + "balanced-match": "^4.0.2" }, "engines": { - "node": ">= 4.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - } - }, - "node_modules/merge-descriptors": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", - "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": "20 || >=22" } }, - "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 - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "node_modules/ignore-walk/node_modules/minimatch": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.0.tgz", + "integrity": "sha512-ugkC31VaVg9cF0DFVoADH12k6061zNZkZON+aX8AWsR9GhPcErkcMBceb6znR8wLERM2AkkOxy2nWRLpT9Jq5w==", "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.2" + }, "engines": { - "node": ">= 8" + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "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==", + "node_modules/immutable": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.3.tgz", + "integrity": "sha512-+chQdDfvscSF1SJqv2gn4SRO2ZyS3xL3r7IW/wWEEzrzLisnOlKiQu5ytC/BVNcS15C39WT2Hg/bjKjDMcu+zg==", "dev": true }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/micromatch": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "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, "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" }, "engines": { - "node": ">=8.6" - } - }, - "node_modules/micromatch/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "engines": { - "node": ">=8.6" + "node": ">=6" }, "funding": { - "url": "https://github.com/sponsors/jonschlinkert" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/mime": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", - "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, - "bin": { - "mime": "cli.js" - }, "engines": { - "node": ">=4.0.0" + "node": ">=0.8.19" } }, - "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==", - "engines": { - "node": ">= 0.6" + "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, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" } }, - "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==", - "dependencies": { - "mime-db": "1.52.0" - }, + "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 + }, + "node_modules/ini": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-6.0.0.tgz", + "integrity": "sha512-IBTdIkzZNOpqm7q3dRqJvMaldXjDHWkEDfrwGEQTs5eaQMWV+djAhR+wahyNNMAa+qpbDUhBMVt4ZKNwpPm7xQ==", + "dev": true, + "license": "ISC", "engines": { - "node": ">= 0.6" + "node": "^20.17.0 || >=22.9.0" } }, - "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, + "node_modules/internmap": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", + "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", "engines": { - "node": ">=6" + "node": ">=12" } }, - "node_modules/mimic-function": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", - "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==", + "node_modules/ip-address": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.0.1.tgz", + "integrity": "sha512-NWv9YLW4PoW2B7xtzaS3NCot75m6nK7Icdv0o3lfMceJVRfSoQwqD4wEH5rLwoKJwUiZ/rfpiVBhnaF0FK4HoA==", "dev": true, + "license": "MIT", "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 12" } }, - "node_modules/mini-css-extract-plugin": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.2.tgz", - "integrity": "sha512-GJuACcS//jtq4kCtd5ii/M0SZf7OZRH+BxdqXZHaJfb8TJiVl+NgQRPwiYt2EuqeSkNydn/7vP+bcE27C5mb9w==", + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", "dev": true, - "dependencies": { - "schema-utils": "^4.0.0", - "tapable": "^2.2.1" - }, + "license": "MIT", "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.0.0" + "node": ">= 0.10" } }, - "node_modules/minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "dev": true, "dependencies": { - "brace-expansion": "^1.1.7" + "binary-extensions": "^2.0.0" }, "engines": { - "node": "*" + "node": ">=8" } }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "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/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "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, "engines": { - "node": ">=16 || 14 >=14.17" + "node": ">=0.10.0" } }, - "node_modules/minipass-collect": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-2.0.1.tgz", - "integrity": "sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==", + "node_modules/is-fullwidth-code-point": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.1.0.tgz", + "integrity": "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==", "dev": true, + "license": "MIT", "dependencies": { - "minipass": "^7.0.3" + "get-east-asian-width": "^1.3.1" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/minipass-fetch": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-4.0.1.tgz", - "integrity": "sha512-j7U11C5HXigVuutxebFadoYBbd7VSdZWggSe64NVdvWNBqGAiXPL2QVCehjmw7lY1oF9gOllYbORh+hiNgfPgQ==", + "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, "dependencies": { - "minipass": "^7.0.3", - "minipass-sized": "^1.0.3", - "minizlib": "^3.0.1" + "is-extglob": "^2.1.1" }, "engines": { - "node": "^18.17.0 || >=20.5.0" - }, - "optionalDependencies": { - "encoding": "^0.1.13" + "node": ">=0.10.0" } }, - "node_modules/minipass-flush": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", - "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", + "node_modules/is-interactive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz", + "integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==", "dev": true, - "dependencies": { - "minipass": "^3.0.0" - }, + "license": "MIT", "engines": { - "node": ">= 8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/minipass-flush/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "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, - "dependencies": { - "yallist": "^4.0.0" - }, "engines": { - "node": ">=8" + "node": ">=0.12.0" } }, - "node_modules/minipass-flush/node_modules/yallist": { + "node_modules/is-promise": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", + "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", + "dev": true, + "license": "MIT" }, - "node_modules/minipass-pipeline": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", - "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", + "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, "dependencies": { - "minipass": "^3.0.0" + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" }, "engines": { - "node": ">=8" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/minipass-pipeline/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "node_modules/is-unicode-supported": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz", + "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==", "dev": true, - "dependencies": { - "yallist": "^4.0.0" + "license": "MIT", + "engines": { + "node": ">=18" }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isbinaryfile": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz", + "integrity": "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==", + "dev": true, "engines": { - "node": ">=8" + "node": ">= 8.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/gjtorikian/" } }, - "node_modules/minipass-pipeline/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, - "node_modules/minipass-sized": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", - "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", + "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, - "dependencies": { - "minipass": "^3.0.0" - }, "engines": { "node": ">=8" } }, - "node_modules/minipass-sized/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "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": { - "yallist": "^4.0.0" + "@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": ">=8" + "node": ">=10" } }, - "node_modules/minipass-sized/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/minizlib": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.0.2.tgz", - "integrity": "sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA==", + "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, "dependencies": { - "minipass": "^7.1.2" + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">= 18" + "node": ">=10" } }, - "node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "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, "dependencies": { - "minimist": "^1.2.6" + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" }, - "bin": { - "mkdirp": "bin/cmd.js" + "engines": { + "node": ">=10" } }, - "node_modules/mrmime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", - "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==", + "node_modules/istanbul-lib-source-maps/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, "engines": { - "node": ">=10" + "node": ">=0.10.0" } }, - "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==" - }, - "node_modules/msgpackr": { - "version": "1.11.4", - "resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.11.4.tgz", - "integrity": "sha512-uaff7RG9VIC4jacFW9xzL3jc0iM32DNHe4jYVycBcjUePT/Klnfj7pqtWJt9khvDFizmjN2TlYniYmSS2LIaZg==", + "node_modules/istanbul-reports": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", + "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", "dev": true, - "optional": true, - "optionalDependencies": { - "msgpackr-extract": "^3.0.2" + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" } }, - "node_modules/msgpackr-extract": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/msgpackr-extract/-/msgpackr-extract-3.0.3.tgz", - "integrity": "sha512-P0efT1C9jIdVRefqjzOQ9Xml57zpOXnIuS+csaB4MdZbTdmGDLo8XhzBG1N7aO11gKDDkJvBLULeFTo46wwreA==", + "node_modules/jackspeak": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.2.3.tgz", + "integrity": "sha512-ykkVRwrYvFm1nb2AJfKKYPr0emF6IiXDYUaFx4Zn9ZuIH7MrzEZ3sD5RlqGXNRpHtvUHJyOnCEFxOlNDtGo7wg==", "dev": true, - "hasInstallScript": true, - "optional": true, + "license": "BlueOak-1.0.0", "dependencies": { - "node-gyp-build-optional-packages": "5.2.2" + "@isaacs/cliui": "^9.0.0" }, - "bin": { - "download-msgpackr-prebuilds": "bin/download-prebuilds.js" + "engines": { + "node": "20 || >=22" }, - "optionalDependencies": { - "@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.3", - "@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.3", - "@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.3", - "@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.3", - "@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.3", - "@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.3" + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/jasmine-core": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-5.6.0.tgz", + "integrity": "sha512-niVlkeYVRwKFpmfWg6suo6H9CrNnydfBLEqefM5UjibYS+UoTjZdmvPJSiuyrRLGnFj1eYRhFd/ch+5hSlsFVA==", + "dev": true + }, + "node_modules/jose": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/jose/-/jose-6.1.3.tgz", + "integrity": "sha512-0TpaTfihd4QMNwrz/ob2Bp7X04yuxJkjRGi4aKmOqwhov54i6u79oCv7T+C7lo70MKH6BesI3vscD1yb/yzKXQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/panva" } }, - "node_modules/multicast-dns": { - "version": "7.2.5", - "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", - "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", + "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 + }, + "node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", "dev": true, + "license": "MIT", "dependencies": { - "dns-packet": "^5.2.2", - "thunky": "^1.0.2" + "argparse": "^2.0.1" }, "bin": { - "multicast-dns": "cli.js" + "js-yaml": "bin/js-yaml.js" } }, - "node_modules/mute-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-2.0.0.tgz", - "integrity": "sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==", + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": ">=6" } }, - "node_modules/nanoid": { - "version": "3.3.11", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", - "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "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, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "bin": { - "nanoid": "bin/nanoid.cjs" - }, + "license": "MIT" + }, + "node_modules/json-parse-even-better-errors": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-5.0.0.tgz", + "integrity": "sha512-ZF1nxZ28VhQouRWhUcVlUIN3qwSgPuswK05s/HIaoetAoE/9tngVmCHjSxmSQPav1nd+lPtTL0YZ/2AFdR/iYQ==", + "dev": true, + "license": "MIT", "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/needle": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/needle/-/needle-3.3.1.tgz", - "integrity": "sha512-6k0YULvhpw+RoLNiQCRKOl09Rv1dPLr8hHnVjHqdolKwDrdNyk+Hmrthi4lIGPPz3r39dLx0hsF5s40sZ3Us4Q==", + "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 + }, + "node_modules/json-schema-typed": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-8.0.2.tgz", + "integrity": "sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==", + "dev": true, + "license": "BSD-2-Clause" + }, + "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, - "optional": true, - "dependencies": { - "iconv-lite": "^0.6.3", - "sax": "^1.2.4" - }, "bin": { - "needle": "bin/needle" + "json5": "lib/cli.js" }, "engines": { - "node": ">= 4.4.x" - } - }, - "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "engines": { - "node": ">= 0.6" + "node": ">=6" } }, - "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==", + "node_modules/jsonc-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", + "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", "dev": true }, - "node_modules/node-addon-api": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-6.1.0.tgz", - "integrity": "sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==", + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", "dev": true, - "optional": true + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } }, - "node_modules/node-forge": { + "node_modules/jsonparse": { "version": "1.3.1", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", - "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", "dev": true, - "engines": { - "node": ">= 6.13.0" - } + "engines": [ + "node >= 0.2.0" + ], + "license": "MIT" }, - "node_modules/node-gyp": { - "version": "11.2.0", - "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-11.2.0.tgz", - "integrity": "sha512-T0S1zqskVUSxcsSTkAsLc7xCycrRYmtDHadDinzocrThjyQCn5kMlEBSj6H4qDbgsIOSLmmlRIeb0lZXj+UArA==", + "node_modules/karma": { + "version": "6.4.4", + "resolved": "https://registry.npmjs.org/karma/-/karma-6.4.4.tgz", + "integrity": "sha512-LrtUxbdvt1gOpo3gxG+VAJlJAEMhbWlM4YrFQgql98FwF7+K8K12LYO4hnDdUkNjeztYrOXEMqgTajSWgmtI/w==", "dev": true, "dependencies": { - "env-paths": "^2.2.0", - "exponential-backoff": "^3.1.1", + "@colors/colors": "1.5.0", + "body-parser": "^1.19.0", + "braces": "^3.0.2", + "chokidar": "^3.5.1", + "connect": "^3.7.0", + "di": "^0.0.1", + "dom-serialize": "^2.2.1", + "glob": "^7.1.7", "graceful-fs": "^4.2.6", - "make-fetch-happen": "^14.0.3", - "nopt": "^8.0.0", - "proc-log": "^5.0.0", - "semver": "^7.3.5", - "tar": "^7.4.3", - "tinyglobby": "^0.2.12", - "which": "^5.0.0" + "http-proxy": "^1.18.1", + "isbinaryfile": "^4.0.8", + "lodash": "^4.17.21", + "log4js": "^6.4.1", + "mime": "^2.5.2", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.5", + "qjobs": "^1.2.0", + "range-parser": "^1.2.1", + "rimraf": "^3.0.2", + "socket.io": "^4.7.2", + "source-map": "^0.6.1", + "tmp": "^0.2.1", + "ua-parser-js": "^0.7.30", + "yargs": "^16.1.1" }, "bin": { - "node-gyp": "bin/node-gyp.js" + "karma": "bin/karma" }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": ">= 10" } }, - "node_modules/node-gyp-build-optional-packages": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.2.2.tgz", - "integrity": "sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw==", + "node_modules/karma-chrome-launcher": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-3.2.0.tgz", + "integrity": "sha512-rE9RkUPI7I9mAxByQWkGJFXfFD6lE4gC5nPuZdobf/QdTEJI6EU4yIay/cfU/xV4ZxlM5JiTv7zWYgA64NpS5Q==", "dev": true, - "optional": true, "dependencies": { - "detect-libc": "^2.0.1" - }, - "bin": { - "node-gyp-build-optional-packages": "bin.js", - "node-gyp-build-optional-packages-optional": "optional.js", - "node-gyp-build-optional-packages-test": "build-test.js" + "which": "^1.2.1" } }, - "node_modules/node-gyp/node_modules/chownr": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", - "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", + "node_modules/karma-coverage": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/karma-coverage/-/karma-coverage-2.2.1.tgz", + "integrity": "sha512-yj7hbequkQP2qOSb20GuNSIyE//PgJWHwC2IydLE6XRtsnaflv+/OSGNssPjobYUlhVVagy99TQpqUt3vAUG7A==", "dev": true, + "dependencies": { + "istanbul-lib-coverage": "^3.2.0", + "istanbul-lib-instrument": "^5.1.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.1", + "istanbul-reports": "^3.0.5", + "minimatch": "^3.0.4" + }, "engines": { - "node": ">=18" + "node": ">=10.0.0" } }, - "node_modules/node-gyp/node_modules/isexe": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", - "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "node_modules/karma-coverage/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, + "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": ">=16" + "node": ">=8" } }, - "node_modules/node-gyp/node_modules/mkdirp": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", - "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", + "node_modules/karma-coverage/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, "bin": { - "mkdirp": "dist/cjs/src/bin.js" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "semver": "bin/semver.js" } }, - "node_modules/node-gyp/node_modules/tar": { - "version": "7.4.3", - "resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz", - "integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==", + "node_modules/karma-jasmine": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/karma-jasmine/-/karma-jasmine-5.1.0.tgz", + "integrity": "sha512-i/zQLFrfEpRyQoJF9fsCdTMOF5c2dK7C7OmsuKg2D0YSsuZSfQDiLuaiktbuio6F2wiCsZSnSnieIQ0ant/uzQ==", "dev": true, "dependencies": { - "@isaacs/fs-minipass": "^4.0.0", - "chownr": "^3.0.0", - "minipass": "^7.1.2", - "minizlib": "^3.0.1", - "mkdirp": "^3.0.1", - "yallist": "^5.0.0" + "jasmine-core": "^4.1.0" }, "engines": { - "node": ">=18" + "node": ">=12" + }, + "peerDependencies": { + "karma": "^6.0.0" } }, - "node_modules/node-gyp/node_modules/which": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz", - "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==", + "node_modules/karma-jasmine-html-reporter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/karma-jasmine-html-reporter/-/karma-jasmine-html-reporter-2.1.0.tgz", + "integrity": "sha512-sPQE1+nlsn6Hwb5t+HHwyy0A1FNCVKuL1192b+XNauMYWThz2kweiBVW1DqloRpVvZIJkIoHVB7XRpK78n1xbQ==", "dev": true, - "dependencies": { - "isexe": "^3.1.1" - }, - "bin": { - "node-which": "bin/which.js" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" + "peerDependencies": { + "jasmine-core": "^4.0.0 || ^5.0.0", + "karma": "^6.0.0", + "karma-jasmine": "^5.0.0" } }, - "node_modules/node-gyp/node_modules/yallist": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", - "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", + "node_modules/karma-jasmine/node_modules/jasmine-core": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-4.6.1.tgz", + "integrity": "sha512-VYz/BjjmC3klLJlLwA4Kw8ytk0zDSmbbDLNs794VnWmkcCB7I9aAL/D48VNQtmITyPvea2C3jdUMfc3kAoy0PQ==", + "dev": true + }, + "node_modules/karma/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, "engines": { - "node": ">=18" + "node": ">=8" } }, - "node_modules/node-releases": { - "version": "2.0.19", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", - "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", - "dev": true - }, - "node_modules/nopt": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-8.1.0.tgz", - "integrity": "sha512-ieGu42u/Qsa4TFktmaKEwM6MQH0pOWnaB3htzh0JRtx84+Mebc0cbZYN5bC+6WTZ4+77xrL9Pn5m7CV6VIkV7A==", + "node_modules/karma/node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", "dev": true, "dependencies": { - "abbrev": "^3.0.0" - }, - "bin": { - "nopt": "bin/nopt.js" + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" } }, - "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==", + "node_modules/karma/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dev": true, - "engines": { - "node": ">=0.10.0" + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" } }, - "node_modules/normalize-range": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", - "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } + "node_modules/karma/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 }, - "node_modules/npm-bundled": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-4.0.0.tgz", - "integrity": "sha512-IxaQZDMsqfQ2Lz37VvyyEtKLe8FsRZuysmedy/N06TU1RyVppYKXrO4xIhR0F+7ubIBox6Q7nir6fQI3ej39iA==", + "node_modules/karma/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, "dependencies": { - "npm-normalize-package-bin": "^4.0.0" + "is-glob": "^4.0.1" }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": ">= 6" } }, - "node_modules/npm-install-checks": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-7.1.1.tgz", - "integrity": "sha512-u6DCwbow5ynAX5BdiHQ9qvexme4U3qHW3MWe5NqH+NeBm0LbiH6zvGjNNew1fY+AZZUtVHbOPF3j7mJxbUzpXg==", + "node_modules/karma/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, - "dependencies": { - "semver": "^7.1.1" - }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": ">=8" } }, - "node_modules/npm-normalize-package-bin": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-4.0.0.tgz", - "integrity": "sha512-TZKxPvItzai9kN9H/TkmCtx/ZN/hvr3vUycjlfmH0ootY9yFBzNOpiXAdIn1Iteqsvk4lQn6B5PTrt+n6h8k/w==", + "node_modules/karma/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/npm-package-arg": { - "version": "12.0.2", - "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-12.0.2.tgz", - "integrity": "sha512-f1NpFjNI9O4VbKMOlA5QoBq/vSQPORHcTZ2feJpFkTHJ9eQkdlmZEKSjcAhxTGInC7RlEyScT9ui67NaOsjFWA==", + "node_modules/karma/node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, "dependencies": { - "hosted-git-info": "^8.0.0", - "proc-log": "^5.0.0", - "semver": "^7.3.5", - "validate-npm-package-name": "^6.0.0" + "picomatch": "^2.2.1" }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": ">=8.10.0" } }, - "node_modules/npm-packlist": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-9.0.0.tgz", - "integrity": "sha512-8qSayfmHJQTx3nJWYbbUmflpyarbLMBc6LCAjYsiGtXxDB68HaZpb8re6zeaLGxZzDuMdhsg70jryJe+RrItVQ==", + "node_modules/karma/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, - "dependencies": { - "ignore-walk": "^7.0.0" - }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": ">=0.10.0" } }, - "node_modules/npm-pick-manifest": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-10.0.0.tgz", - "integrity": "sha512-r4fFa4FqYY8xaM7fHecQ9Z2nE9hgNfJR+EmoKv0+chvzWkBcORX3r0FpTByP+CbOVJDladMXnPQGVN8PBLGuTQ==", + "node_modules/karma/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, "dependencies": { - "npm-install-checks": "^7.1.0", - "npm-normalize-package-bin": "^4.0.0", - "npm-package-arg": "^12.0.0", - "semver": "^7.3.5" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": ">=8" } }, - "node_modules/npm-registry-fetch": { - "version": "18.0.2", - "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-18.0.2.tgz", - "integrity": "sha512-LeVMZBBVy+oQb5R6FDV9OlJCcWDU+al10oKpe+nsvcHnG24Z3uM3SvJYKfGJlfGjVU8v9liejCrUR/M5HO5NEQ==", + "node_modules/karma/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, "dependencies": { - "@npmcli/redact": "^3.0.0", - "jsonparse": "^1.3.1", - "make-fetch-happen": "^14.0.0", - "minipass": "^7.0.2", - "minipass-fetch": "^4.0.0", - "minizlib": "^3.0.1", - "npm-package-arg": "^12.0.0", - "proc-log": "^5.0.0" + "ansi-regex": "^5.0.1" }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": ">=8" } }, - "node_modules/nth-check": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", - "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "node_modules/karma/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, "dependencies": { - "boolbase": "^1.0.0" + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" }, - "funding": { - "url": "https://github.com/fb55/nth-check?sponsor=1" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, "engines": { - "node": ">=0.10.0" - } - }, - "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==", - "engines": { - "node": ">= 0.4" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/obuf": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", - "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", - "dev": true - }, - "node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "node_modules/karma/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, "dependencies": { - "ee-first": "1.1.1" + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" }, "engines": { - "node": ">= 0.8" + "node": ">=10" } }, - "node_modules/on-headers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "node_modules/karma/node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", "dev": true, "engines": { - "node": ">= 0.8" + "node": ">=10" } }, - "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==", + "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": { - "wrappy": "1" + "json-buffer": "3.0.1" } }, - "node_modules/onetime": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", - "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", + "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": { - "mimic-function": "^5.0.0" + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" }, "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 0.8.0" } }, - "node_modules/open": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/open/-/open-10.1.0.tgz", - "integrity": "sha512-mnkeQ1qP5Ue2wd+aivTD3NHd/lZ96Lu0jgf0pwktLPtx6cTZiH7tyeGRRHs0zX0rbrahXPnXlUnbeXyaBBuIaw==", + "node_modules/lint-staged": { + "version": "16.2.7", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-16.2.7.tgz", + "integrity": "sha512-lDIj4RnYmK7/kXMya+qJsmkRFkGolciXjrsZ6PC25GdTfWOAWetR0ZbsNXRAj1EHHImRSalc+whZFg56F5DVow==", "dev": true, + "license": "MIT", "dependencies": { - "default-browser": "^5.2.1", - "define-lazy-prop": "^3.0.0", - "is-inside-container": "^1.0.0", - "is-wsl": "^3.1.0" - }, - "engines": { - "node": ">=18" + "commander": "^14.0.2", + "listr2": "^9.0.5", + "micromatch": "^4.0.8", + "nano-spawn": "^2.0.0", + "pidtree": "^0.6.0", + "string-argv": "^0.3.2", + "yaml": "^2.8.1" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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, - "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" + "bin": { + "lint-staged": "bin/lint-staged.js" }, "engines": { - "node": ">=10" + "node": ">=20.17" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://opencollective.com/lint-staged" } }, - "node_modules/ora/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==", + "node_modules/lint-staged/node_modules/commander": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.3.tgz", + "integrity": "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==", "dev": true, + "license": "MIT", "engines": { - "node": ">=8" + "node": ">=20" } }, - "node_modules/ora/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==", + "node_modules/listr2": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-9.0.5.tgz", + "integrity": "sha512-ME4Fb83LgEgwNw96RKNvKV4VTLuXfoKudAmm2lP8Kk87KaMK0/Xrx/aAkMWmT8mDb+3MlFDspfbCs7adjRxA2g==", "dev": true, + "license": "MIT", "dependencies": { - "restore-cursor": "^3.1.0" + "cli-truncate": "^5.0.0", + "colorette": "^2.0.20", + "eventemitter3": "^5.0.1", + "log-update": "^6.1.0", + "rfdc": "^1.4.1", + "wrap-ansi": "^9.0.0" }, "engines": { - "node": ">=8" + "node": ">=20.0.0" } }, - "node_modules/ora/node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "node_modules/listr2/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, - "dependencies": { - "mimic-fn": "^2.1.0" - }, + "license": "MIT", "engines": { - "node": ">=6" + "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/ora/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==", + "node_modules/listr2/node_modules/eventemitter3": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz", + "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/listr2/node_modules/wrap-ansi": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", "dev": true, + "license": "MIT", "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" }, "engines": { - "node": ">=8" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/ora/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 + "node_modules/lmdb": { + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/lmdb/-/lmdb-3.4.4.tgz", + "integrity": "sha512-+Y2DqovevLkb6DrSQ6SXTYLEd6kvlRbhsxzgJrk7BUfOVA/mt21ak6pFDZDKxiAczHMWxrb02kXBTSTIA0O94A==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "msgpackr": "^1.11.2", + "node-addon-api": "^6.1.0", + "node-gyp-build-optional-packages": "5.2.2", + "ordered-binary": "^1.5.3", + "weak-lru-cache": "^1.2.2" + }, + "bin": { + "download-lmdb-prebuilds": "bin/download-prebuilds.js" + }, + "optionalDependencies": { + "@lmdb/lmdb-darwin-arm64": "3.4.4", + "@lmdb/lmdb-darwin-x64": "3.4.4", + "@lmdb/lmdb-linux-arm": "3.4.4", + "@lmdb/lmdb-linux-arm64": "3.4.4", + "@lmdb/lmdb-linux-x64": "3.4.4", + "@lmdb/lmdb-win32-arm64": "3.4.4", + "@lmdb/lmdb-win32-x64": "3.4.4" + } }, - "node_modules/ora/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==", + "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": { - "ansi-regex": "^5.0.1" + "p-locate": "^5.0.0" }, "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ordered-binary": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/ordered-binary/-/ordered-binary-1.6.0.tgz", - "integrity": "sha512-IQh2aMfMIDbPjI/8a3Edr+PiOpcsB7yo8NdW7aHWVaoR/pcDldunMvnnwbk/auPGqmKeAdxtZl7MHX/QmPwhvQ==", + "node_modules/lodash": { + "version": "4.17.23", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz", + "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==", "dev": true, - "optional": true + "license": "MIT" }, - "node_modules/os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "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, - "engines": { - "node": ">=0.10.0" - } + "license": "MIT" }, - "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==", + "node_modules/log-symbols": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-7.0.1.tgz", + "integrity": "sha512-ja1E3yCr9i/0hmBVaM0bfwDjnGy8I/s6PP4DFp+yP+a+mrHO4Rm7DtmnqROTUkHIkqffC84YY7AeqX6oFk0WFg==", "dev": true, + "license": "MIT", "dependencies": { - "yocto-queue": "^1.0.0" + "is-unicode-supported": "^2.0.0", + "yoctocolors": "^2.1.1" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=18" }, "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==", + "node_modules/log-update": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.1.0.tgz", + "integrity": "sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==", "dev": true, "dependencies": { - "p-limit": "^4.0.0" + "ansi-escapes": "^7.0.0", + "cli-cursor": "^5.0.0", + "slice-ansi": "^7.1.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/p-map": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-7.0.3.tgz", - "integrity": "sha512-VkndIv2fIB99swvQoA65bm+fsmt6UNdGeIB0oxBs+WhAhdh08QA04JXpI7rbB9r08/nkbysKoya9rtDERYOYMA==", + "node_modules/log-update/node_modules/ansi-escapes": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.0.0.tgz", + "integrity": "sha512-GdYO7a61mR0fOlAsvC9/rIHf7L96sBc6dEWzeOu+KAea5bZyQRPIpojrVoI4AXGJS/ycu/fBTdLrUkA4ODrvjw==", "dev": true, + "dependencies": { + "environment": "^1.0.0" + }, "engines": { "node": ">=18" }, @@ -10916,901 +9570,784 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/p-retry": { + "node_modules/log-update/node_modules/ansi-styles": { "version": "6.2.1", - "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-6.2.1.tgz", - "integrity": "sha512-hEt02O4hUct5wtwg4H4KcWgDdm+l1bOaEy/hWzd8xtXB9BqxTWBBhb+2ImAtH4Cv4rPjV76xN3Zumqk3k3AhhQ==", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", "dev": true, - "dependencies": { - "@types/retry": "0.12.2", - "is-network-error": "^1.0.0", - "retry": "^0.13.1" - }, "engines": { - "node": ">=16.17" + "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-retry/node_modules/retry": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", - "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", - "dev": true, - "engines": { - "node": ">= 4" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "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 - }, - "node_modules/pacote": { - "version": "20.0.0", - "resolved": "https://registry.npmjs.org/pacote/-/pacote-20.0.0.tgz", - "integrity": "sha512-pRjC5UFwZCgx9kUFDVM9YEahv4guZ1nSLqwmWiLUnDbGsjs+U5w7z6Uc8HNR1a6x8qnu5y9xtGE6D1uAuYz+0A==", + "node_modules/log-update/node_modules/wrap-ansi": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", + "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", "dev": true, "dependencies": { - "@npmcli/git": "^6.0.0", - "@npmcli/installed-package-contents": "^3.0.0", - "@npmcli/package-json": "^6.0.0", - "@npmcli/promise-spawn": "^8.0.0", - "@npmcli/run-script": "^9.0.0", - "cacache": "^19.0.0", - "fs-minipass": "^3.0.0", - "minipass": "^7.0.2", - "npm-package-arg": "^12.0.0", - "npm-packlist": "^9.0.0", - "npm-pick-manifest": "^10.0.0", - "npm-registry-fetch": "^18.0.0", - "proc-log": "^5.0.0", - "promise-retry": "^2.0.1", - "sigstore": "^3.0.0", - "ssri": "^12.0.0", - "tar": "^6.1.11" - }, - "bin": { - "pacote": "bin/index.js" + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" }, "engines": { - "node": "^18.17.0 || >=20.5.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, - "dependencies": { - "callsites": "^3.0.0" + "node": ">=18" }, - "engines": { - "node": ">=6" + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/parquet-wasm": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/parquet-wasm/-/parquet-wasm-0.7.1.tgz", - "integrity": "sha512-fjEGpMApzt3mpI2pUxdRgQGu5G+s4nr0vm5xn43JO7jxdYzzu2fHrVrTHtfeEhtB6vfvTzJBz0WydDYzLWvszQ==", - "license": "MIT OR Apache-2.0" - }, - "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==", + "node_modules/log4js": { + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/log4js/-/log4js-6.9.1.tgz", + "integrity": "sha512-1somDdy9sChrr9/f4UlzhdaGfDR2c/SaD2a4T7qEkG4jTS57/B3qmnjLYePwQ8cqWnUHZI0iAKxMBpCZICiZ2g==", "dev": true, "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" + "date-format": "^4.0.14", + "debug": "^4.3.4", + "flatted": "^3.2.7", + "rfdc": "^1.3.0", + "streamroller": "^3.1.5" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8.0" } }, - "node_modules/parse-json/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 - }, - "node_modules/parse-node-version": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz", - "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==", + "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, - "engines": { - "node": ">= 0.10" + "dependencies": { + "yallist": "^3.0.2" } }, - "node_modules/parse5": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", - "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", "dev": true, + "license": "MIT", "dependencies": { - "entities": "^6.0.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" + "@jridgewell/sourcemap-codec": "^1.5.5" } }, - "node_modules/parse5-html-rewriting-stream": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/parse5-html-rewriting-stream/-/parse5-html-rewriting-stream-7.0.0.tgz", - "integrity": "sha512-mazCyGWkmCRWDI15Zp+UiCqMp/0dgEmkZRvhlsqqKYr4SsVm/TvnSpD9fCvqCA2zoWJcfRym846ejWBBHRiYEg==", + "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, "dependencies": { - "entities": "^4.3.0", - "parse5": "^7.0.0", - "parse5-sax-parser": "^7.0.0" + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" }, "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/parse5-sax-parser": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/parse5-sax-parser/-/parse5-sax-parser-7.0.0.tgz", - "integrity": "sha512-5A+v2SNsq8T6/mG3ahcz8ZtQ0OUFTatxPbeidoMB7tkJSGDY3tdfl4MHovtLQHkEn5CGxijNWRQHhRQ6IRpXKg==", + "node_modules/make-fetch-happen": { + "version": "15.0.3", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-15.0.3.tgz", + "integrity": "sha512-iyyEpDty1mwW3dGlYXAJqC/azFn5PPvgKVwXayOGBSmKLxhKZ9fg4qIan2ePpp1vJIwfFiO34LAPZgq9SZW9Aw==", "dev": true, + "license": "ISC", "dependencies": { - "parse5": "^7.0.0" + "@npmcli/agent": "^4.0.0", + "cacache": "^20.0.1", + "http-cache-semantics": "^4.1.1", + "minipass": "^7.0.2", + "minipass-fetch": "^5.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^1.0.0", + "proc-log": "^6.0.0", + "promise-retry": "^2.0.1", + "ssri": "^13.0.0" }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/parse5/node_modules/entities": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", - "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "node_modules/make-fetch-happen/node_modules/negotiator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", + "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", "dev": true, + "license": "MIT", "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" + "node": ">= 0.6" } }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "node_modules/material-icons": { + "version": "1.13.14", + "resolved": "https://registry.npmjs.org/material-icons/-/material-icons-1.13.14.tgz", + "integrity": "sha512-kZOfc7xCC0rAT8Q3DQixYAeT+tBqZnxkseQtp2bxBxz7q5pMAC+wmit7vJn1g/l7wRU+HEPq23gER4iPjGs5Cg==" + }, + "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, "engines": { - "node": ">= 0.8" + "node": ">= 0.4" } }, - "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==", + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", "dev": true, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">= 0.6" } }, - "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==", + "node_modules/merge-descriptors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", + "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", "dev": true, + "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "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==", + "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, "engines": { - "node": ">=8" + "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==", + "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 }, - "node_modules/path-scurry": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", - "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "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, "dependencies": { - "lru-cache": "^10.2.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + "braces": "^3.0.3", + "picomatch": "^2.3.1" }, "engines": { - "node": ">=16 || 14 >=14.18" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": ">=8.6" } }, - "node_modules/path-scurry/node_modules/lru-cache": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "dev": true - }, - "node_modules/path-to-regexp": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", - "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==" - }, - "node_modules/path-type": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-6.0.0.tgz", - "integrity": "sha512-Vj7sf++t5pBD637NSfkxpHSMfWaeig5+DKWLhcqIYx6mWQz5hdJTGDVMQiJcw1ZYkhs7AazKDGpRVji1LJCZUQ==", + "node_modules/micromatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, "engines": { - "node": ">=18" + "node": ">=8.6" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/jonschlinkert" } }, - "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 - }, - "node_modules/picomatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", - "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "node_modules/mime": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", "dev": true, - "engines": { - "node": ">=12" + "bin": { + "mime": "cli.js" }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" + "engines": { + "node": ">=4.0.0" } }, - "node_modules/pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "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, - "optional": true, "engines": { - "node": ">=6" + "node": ">= 0.6" } }, - "node_modules/piscina": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/piscina/-/piscina-4.8.0.tgz", - "integrity": "sha512-EZJb+ZxDrQf3dihsUL7p42pjNyrNIFJCrRHPMgxu/svsj+P3xS3fuEWp7k2+rfsavfl1N0G29b1HGs7J0m8rZA==", + "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, - "optionalDependencies": { - "@napi-rs/nice": "^1.0.1" + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" } }, - "node_modules/pkg-dir": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-7.0.0.tgz", - "integrity": "sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==", + "node_modules/mimic-function": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", + "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==", "dev": true, - "dependencies": { - "find-up": "^6.3.0" - }, "engines": { - "node": ">=14.16" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/postcss": { - "version": "8.5.2", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.2.tgz", - "integrity": "sha512-MjOadfU3Ys9KYoX0AdkBlFEF1Vx37uCCeN4ZHnmwm9FfpbsGWMZeBLMmmpY+6Ocqod7mkdZ0DT31OlbsFrLlkA==", + "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, - "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" - } - ], "dependencies": { - "nanoid": "^3.3.8", - "picocolors": "^1.1.1", - "source-map-js": "^1.2.1" + "brace-expansion": "^1.1.7" }, "engines": { - "node": "^10 || ^12 || >=14" + "node": "*" } }, - "node_modules/postcss-loader": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-8.1.1.tgz", - "integrity": "sha512-0IeqyAsG6tYiDRCYKQJLAmgQr47DX6N7sFSWvQxt6AcupX8DIdmykuk/o/tx0Lze3ErGHJEp5OSRxrelC6+NdQ==", + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", "dev": true, - "dependencies": { - "cosmiconfig": "^9.0.0", - "jiti": "^1.20.0", - "semver": "^7.5.4" - }, - "engines": { - "node": ">= 18.12.0" - }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "@rspack/core": "0.x || 1.x", - "postcss": "^7.0.0 || ^8.0.1", - "webpack": "^5.0.0" - }, - "peerDependenciesMeta": { - "@rspack/core": { - "optional": true - }, - "webpack": { - "optional": true - } + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/postcss-media-query-parser": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz", - "integrity": "sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==", - "dev": true - }, - "node_modules/postcss-modules-extract-imports": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz", - "integrity": "sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==", + "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": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" + "node": ">=16 || 14 >=14.17" } }, - "node_modules/postcss-modules-local-by-default": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.2.0.tgz", - "integrity": "sha512-5kcJm/zk+GJDSfw+V/42fJ5fhjL5YbFDl8nVdXkJPLLW+Vf9mTD5Xe0wqIaDnLuL2U6cDNpTr+UQ+v2HWIBhzw==", + "node_modules/minipass-collect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-2.0.1.tgz", + "integrity": "sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==", "dev": true, + "license": "ISC", "dependencies": { - "icss-utils": "^5.0.0", - "postcss-selector-parser": "^7.0.0", - "postcss-value-parser": "^4.1.0" + "minipass": "^7.0.3" }, "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" + "node": ">=16 || 14 >=14.17" } }, - "node_modules/postcss-modules-scope": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.1.tgz", - "integrity": "sha512-m9jZstCVaqGjTAuny8MdgE88scJnCiQSlSrOWcTQgM2t32UBe+MUmFSO5t7VMSfAf/FJKImAxBav8ooCHJXCJA==", + "node_modules/minipass-fetch": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-5.0.1.tgz", + "integrity": "sha512-yHK8pb0iCGat0lDrs/D6RZmCdaBT64tULXjdxjSMAqoDi18Q3qKEUTHypHQZQd9+FYpIS+lkvpq6C/R6SbUeRw==", "dev": true, + "license": "MIT", "dependencies": { - "postcss-selector-parser": "^7.0.0" + "minipass": "^7.0.3", + "minipass-sized": "^2.0.0", + "minizlib": "^3.0.1" }, "engines": { - "node": "^10 || ^12 || >= 14" + "node": "^20.17.0 || >=22.9.0" }, - "peerDependencies": { - "postcss": "^8.1.0" + "optionalDependencies": { + "encoding": "^0.1.13" } }, - "node_modules/postcss-modules-values": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", - "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", + "node_modules/minipass-flush": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", + "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", "dev": true, + "license": "ISC", "dependencies": { - "icss-utils": "^5.0.0" + "minipass": "^3.0.0" }, "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" + "node": ">= 8" } }, - "node_modules/postcss-selector-parser": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", - "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", + "node_modules/minipass-flush/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", "dev": true, + "license": "ISC", "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" + "yallist": "^4.0.0" }, "engines": { - "node": ">=4" + "node": ">=8" } }, - "node_modules/postcss-value-parser": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", - "dev": true - }, - "node_modules/proc-log": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-5.0.0.tgz", - "integrity": "sha512-Azwzvl90HaF0aCz1JrDdXQykFakSSNPaPoiZ9fm5qJIMHioDZEi7OAdRwSm6rSoPtY3Qutnm3L7ogmg3dc+wbQ==", + "node_modules/minipass-flush/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true + "license": "ISC" }, - "node_modules/promise-retry": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", - "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", + "node_modules/minipass-pipeline": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", + "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", "dev": true, + "license": "ISC", "dependencies": { - "err-code": "^2.0.2", - "retry": "^0.12.0" + "minipass": "^3.0.0" }, "engines": { - "node": ">=10" + "node": ">=8" } }, - "node_modules/proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "node_modules/minipass-pipeline/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "license": "ISC", "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" + "yallist": "^4.0.0" }, "engines": { - "node": ">= 0.10" + "node": ">=8" } }, - "node_modules/prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==", + "node_modules/minipass-pipeline/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true, - "optional": true - }, - "node_modules/punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", - "dev": true + "license": "ISC" }, - "node_modules/pyodide": { - "version": "0.28.0", - "resolved": "https://registry.npmjs.org/pyodide/-/pyodide-0.28.0.tgz", - "integrity": "sha512-QML/Gh8eu50q5zZKLNpW6rgS0XUdK+94OSL54AUSKV8eJAxgwZrMebqj+CyM0EbF3EUX8JFJU3ryaxBViHammQ==", + "node_modules/minipass-sized": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-2.0.0.tgz", + "integrity": "sha512-zSsHhto5BcUVM2m1LurnXY6M//cGhVaegT71OfOXoprxT6o780GZd792ea6FfrQkuU4usHZIUczAQMRUE2plzA==", + "dev": true, + "license": "ISC", "dependencies": { - "ws": "^8.5.0" + "minipass": "^7.1.2" }, "engines": { - "node": ">=18.0.0" + "node": ">=8" } }, - "node_modules/qjobs": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz", - "integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==", + "node_modules/minizlib": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz", + "integrity": "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==", "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.1.2" + }, "engines": { - "node": ">=0.9" + "node": ">= 18" } }, - "node_modules/qs": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", - "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, "dependencies": { - "side-channel": "^1.0.6" + "minimist": "^1.2.6" }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "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": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=10" } }, - "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==", + "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 + }, + "node_modules/msgpackr": { + "version": "1.11.8", + "resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.11.8.tgz", + "integrity": "sha512-bC4UGzHhVvgDNS7kn9tV8fAucIYUBuGojcaLiz7v+P63Lmtm0Xeji8B/8tYKddALXxJLpwIeBmUN3u64C4YkRA==", "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", + "optional": true, + "optionalDependencies": { + "msgpackr-extract": "^3.0.2" + } }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "node_modules/msgpackr-extract": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/msgpackr-extract/-/msgpackr-extract-3.0.3.tgz", + "integrity": "sha512-P0efT1C9jIdVRefqjzOQ9Xml57zpOXnIuS+csaB4MdZbTdmGDLo8XhzBG1N7aO11gKDDkJvBLULeFTo46wwreA==", "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, "dependencies": { - "safe-buffer": "^5.1.0" + "node-gyp-build-optional-packages": "5.2.2" + }, + "bin": { + "download-msgpackr-prebuilds": "bin/download-prebuilds.js" + }, + "optionalDependencies": { + "@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.3", + "@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.3" } }, - "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "node_modules/mute-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-2.0.0.tgz", + "integrity": "sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==", + "dev": true, + "license": "ISC", "engines": { - "node": ">= 0.6" + "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/raw-body": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", - "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, + "node_modules/nano-spawn": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/nano-spawn/-/nano-spawn-2.0.0.tgz", + "integrity": "sha512-tacvGzUY5o2D8CBh2rrwxyNojUsZNU2zjNTzKQrkgGJQTbGAfArVWXSKMBokBeeg6C7OLRGUEyoFlYbfeWQIqw==", + "dev": true, + "license": "MIT", "engines": { - "node": ">= 0.8" - } - }, - "node_modules/raw-body/node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" + "node": ">=20.17" }, - "engines": { - "node": ">=0.10.0" + "funding": { + "url": "https://github.com/sindresorhus/nano-spawn?sponsor=1" } }, - "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==", + "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, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" }, "engines": { - "node": ">= 6" + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, - "node_modules/readdirp": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", - "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "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/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", "dev": true, "engines": { - "node": ">= 14.18.0" - }, - "funding": { - "type": "individual", - "url": "https://paulmillr.com/funding/" + "node": ">= 0.6" } }, - "node_modules/reflect-metadata": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz", - "integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==", - "dev": true - }, - "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 + "node_modules/node-addon-api": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-6.1.0.tgz", + "integrity": "sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==", + "dev": true, + "license": "MIT", + "optional": true }, - "node_modules/regenerate-unicode-properties": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.0.tgz", - "integrity": "sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA==", + "node_modules/node-gyp": { + "version": "12.2.0", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-12.2.0.tgz", + "integrity": "sha512-q23WdzrQv48KozXlr0U1v9dwO/k59NHeSzn6loGcasyf0UnSrtzs8kRxM+mfwJSf0DkX0s43hcqgnSO4/VNthQ==", "dev": true, + "license": "MIT", "dependencies": { - "regenerate": "^1.4.2" + "env-paths": "^2.2.0", + "exponential-backoff": "^3.1.1", + "graceful-fs": "^4.2.6", + "make-fetch-happen": "^15.0.0", + "nopt": "^9.0.0", + "proc-log": "^6.0.0", + "semver": "^7.3.5", + "tar": "^7.5.4", + "tinyglobby": "^0.2.12", + "which": "^6.0.0" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" }, "engines": { - "node": ">=4" + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/regenerator-runtime": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", - "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", - "dev": true - }, - "node_modules/regex-parser": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/regex-parser/-/regex-parser-2.3.1.tgz", - "integrity": "sha512-yXLRqatcCuKtVHsWrNg0JL3l1zGfdXeEvDa0bdu4tCDQw0RpMDZsqbkyRTUnKMR0tXF627V2oEWjBEaEdqTwtQ==", - "dev": true - }, - "node_modules/regexpu-core": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.2.0.tgz", - "integrity": "sha512-H66BPQMrv+V16t8xtmq+UC0CBpiTBA60V8ibS1QVReIp8T1z8hwFxqcGzm9K6lgsN7sB5edVH8a+ze6Fqm4weA==", + "node_modules/node-gyp-build-optional-packages": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.2.2.tgz", + "integrity": "sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw==", "dev": true, + "license": "MIT", + "optional": true, "dependencies": { - "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^10.2.0", - "regjsgen": "^0.8.0", - "regjsparser": "^0.12.0", - "unicode-match-property-ecmascript": "^2.0.0", - "unicode-match-property-value-ecmascript": "^2.1.0" + "detect-libc": "^2.0.1" }, - "engines": { - "node": ">=4" + "bin": { + "node-gyp-build-optional-packages": "bin.js", + "node-gyp-build-optional-packages-optional": "optional.js", + "node-gyp-build-optional-packages-test": "build-test.js" } }, - "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 + "node_modules/node-gyp/node_modules/isexe": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-4.0.0.tgz", + "integrity": "sha512-FFUtZMpoZ8RqHS3XeXEmHWLA4thH+ZxCv2lOiPIn1Xc7CxrqhWzNSDzD+/chS/zbYezmiwWLdQC09JdQKmthOw==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=20" + } }, - "node_modules/regjsparser": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.12.0.tgz", - "integrity": "sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==", + "node_modules/node-gyp/node_modules/which": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/which/-/which-6.0.1.tgz", + "integrity": "sha512-oGLe46MIrCRqX7ytPUf66EAYvdeMIZYn3WaocqqKZAxrBpkqHfL/qvTyJ/bTk5+AqHCjXmrv3CEWgy368zhRUg==", "dev": true, + "license": "ISC", "dependencies": { - "jsesc": "~3.0.2" + "isexe": "^4.0.0" }, "bin": { - "regjsparser": "bin/parser" + "node-which": "bin/which.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/regjsparser/node_modules/jsesc": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", - "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", + "node_modules/node-releases": { + "version": "2.0.27", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", + "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/nopt": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-9.0.0.tgz", + "integrity": "sha512-Zhq3a+yFKrYwSBluL4H9XP3m3y5uvQkB/09CwDruCiRmR/UJYnn9W4R48ry0uGC70aeTPKLynBtscP9efFFcPw==", "dev": true, + "license": "ISC", + "dependencies": { + "abbrev": "^4.0.0" + }, "bin": { - "jsesc": "bin/jsesc" + "nopt": "bin/nopt.js" }, "engines": { - "node": ">=6" + "node": "^20.17.0 || >=22.9.0" } }, - "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==", + "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, "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==", + "node_modules/npm-bundled": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-5.0.0.tgz", + "integrity": "sha512-JLSpbzh6UUXIEoqPsYBvVNVmyrjVZ1fzEFbqxKkTJQkWBO3xFzFT+KDnSKQWwOQNbuWRwt5LSD6HOTLGIWzfrw==", "dev": true, + "license": "ISC", + "dependencies": { + "npm-normalize-package-bin": "^5.0.0" + }, "engines": { - "node": ">=0.10.0" + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", - "dev": true - }, - "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==", + "node_modules/npm-install-checks": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-8.0.0.tgz", + "integrity": "sha512-ScAUdMpyzkbpxoNekQ3tNRdFI8SJ86wgKZSQZdUxT+bj0wVFpsEMWnkXP0twVe1gJyNF5apBWDJhhIbgrIViRA==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "is-core-module": "^2.16.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" + "semver": "^7.1.1" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "^20.17.0 || >=22.9.0" } }, - "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==", + "node_modules/npm-normalize-package-bin": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-5.0.0.tgz", + "integrity": "sha512-CJi3OS4JLsNMmr2u07OJlhcrPxCeOeP/4xq67aWNai6TNWWbTrlNDgl8NcFKVlcBKp18GPj+EzbNIgrBfZhsag==", "dev": true, + "license": "ISC", "engines": { - "node": ">=4" + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/resolve-url-loader": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-5.0.0.tgz", - "integrity": "sha512-uZtduh8/8srhBoMx//5bwqjQ+rfYOUq8zC9NrMUGtjBiGTtFJM42s58/36+hTqeqINcnYe08Nj3LkK9lW4N8Xg==", + "node_modules/npm-package-arg": { + "version": "13.0.2", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-13.0.2.tgz", + "integrity": "sha512-IciCE3SY3uE84Ld8WZU23gAPPV9rIYod4F+rc+vJ7h7cwAJt9Vk6TVsK60ry7Uj3SRS3bqRRIGuTp9YVlk6WNA==", "dev": true, + "license": "ISC", "dependencies": { - "adjust-sourcemap-loader": "^4.0.0", - "convert-source-map": "^1.7.0", - "loader-utils": "^2.0.0", - "postcss": "^8.2.14", - "source-map": "0.6.1" + "hosted-git-info": "^9.0.0", + "proc-log": "^6.0.0", + "semver": "^7.3.5", + "validate-npm-package-name": "^7.0.0" }, "engines": { - "node": ">=12" + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/resolve-url-loader/node_modules/loader-utils": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", - "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", + "node_modules/npm-packlist": { + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-10.0.3.tgz", + "integrity": "sha512-zPukTwJMOu5X5uvm0fztwS5Zxyvmk38H/LfidkOMt3gbZVCyro2cD/ETzwzVPcWZA3JOyPznfUN/nkyFiyUbxg==", "dev": true, + "license": "ISC", "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" + "ignore-walk": "^8.0.0", + "proc-log": "^6.0.0" }, "engines": { - "node": ">=8.9.0" + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/resolve-url-loader/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==", + "node_modules/npm-pick-manifest": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-11.0.3.tgz", + "integrity": "sha512-buzyCfeoGY/PxKqmBqn1IUJrZnUi1VVJTdSSRPGI60tJdUhUoSQFhs0zycJokDdOznQentgrpf8LayEHyyYlqQ==", "dev": true, + "license": "ISC", + "dependencies": { + "npm-install-checks": "^8.0.0", + "npm-normalize-package-bin": "^5.0.0", + "npm-package-arg": "^13.0.0", + "semver": "^7.3.5" + }, "engines": { - "node": ">=0.10.0" + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/restore-cursor": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", - "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", + "node_modules/npm-registry-fetch": { + "version": "19.1.1", + "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-19.1.1.tgz", + "integrity": "sha512-TakBap6OM1w0H73VZVDf44iFXsOS3h+L4wVMXmbWOQroZgFhMch0juN6XSzBNlD965yIKvWg2dfu7NSiaYLxtw==", "dev": true, + "license": "ISC", "dependencies": { - "onetime": "^7.0.0", - "signal-exit": "^4.1.0" + "@npmcli/redact": "^4.0.0", + "jsonparse": "^1.3.1", + "make-fetch-happen": "^15.0.0", + "minipass": "^7.0.2", + "minipass-fetch": "^5.0.0", + "minizlib": "^3.0.1", + "npm-package-arg": "^13.0.0", + "proc-log": "^6.0.0" }, "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", "dev": true, - "engines": { - "node": ">= 4" + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" } }, - "node_modules/reusify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", - "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", "dev": true, "engines": { - "iojs": ">=1.0.0", "node": ">=0.10.0" } }, - "node_modules/rfdc": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", - "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", - "dev": true - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", + "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, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" + "engines": { + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/robust-predicates": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.2.tgz", - "integrity": "sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==" - }, - "node_modules/rollup": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.34.8.tgz", - "integrity": "sha512-489gTVMzAYdiZHFVA/ig/iYFllCcWFHMvUHI1rpFmkoUtRlQxqh6/yiNqnYibjMZ2b/+FUQwldG+aLsEt6bglQ==", + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", "dev": true, "dependencies": { - "@types/estree": "1.0.6" - }, - "bin": { - "rollup": "dist/bin/rollup" + "ee-first": "1.1.1" }, "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.34.8", - "@rollup/rollup-android-arm64": "4.34.8", - "@rollup/rollup-darwin-arm64": "4.34.8", - "@rollup/rollup-darwin-x64": "4.34.8", - "@rollup/rollup-freebsd-arm64": "4.34.8", - "@rollup/rollup-freebsd-x64": "4.34.8", - "@rollup/rollup-linux-arm-gnueabihf": "4.34.8", - "@rollup/rollup-linux-arm-musleabihf": "4.34.8", - "@rollup/rollup-linux-arm64-gnu": "4.34.8", - "@rollup/rollup-linux-arm64-musl": "4.34.8", - "@rollup/rollup-linux-loongarch64-gnu": "4.34.8", - "@rollup/rollup-linux-powerpc64le-gnu": "4.34.8", - "@rollup/rollup-linux-riscv64-gnu": "4.34.8", - "@rollup/rollup-linux-s390x-gnu": "4.34.8", - "@rollup/rollup-linux-x64-gnu": "4.34.8", - "@rollup/rollup-linux-x64-musl": "4.34.8", - "@rollup/rollup-win32-arm64-msvc": "4.34.8", - "@rollup/rollup-win32-ia32-msvc": "4.34.8", - "@rollup/rollup-win32-x64-msvc": "4.34.8", - "fsevents": "~2.3.2" + "node": ">= 0.8" + } + }, + "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, + "dependencies": { + "wrappy": "1" } }, - "node_modules/run-applescript": { + "node_modules/onetime": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.0.0.tgz", - "integrity": "sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", + "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", "dev": true, + "dependencies": { + "mimic-function": "^5.0.0" + }, "engines": { "node": ">=18" }, @@ -11818,1994 +10355,2055 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "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==", + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "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" - } - ], - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/rw": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", - "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==" - }, - "node_modules/rxjs": { - "version": "7.8.2", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", - "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", + "license": "MIT", "dependencies": { - "tslib": "^2.1.0" + "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/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==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "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==", + "node_modules/ora": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/ora/-/ora-9.0.0.tgz", + "integrity": "sha512-m0pg2zscbYgWbqRR6ABga5c3sZdEon7bSgjnlXC64kxtxLOyjRcbbUkLj7HFyy/FTD+P2xdBWu8snGhYI0jc4A==", "dev": true, + "license": "MIT", "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "is-regex": "^1.2.1" + "chalk": "^5.6.2", + "cli-cursor": "^5.0.0", + "cli-spinners": "^3.2.0", + "is-interactive": "^2.0.0", + "is-unicode-supported": "^2.1.0", + "log-symbols": "^7.0.1", + "stdin-discarder": "^0.2.2", + "string-width": "^8.1.0", + "strip-ansi": "^7.1.2" }, "engines": { - "node": ">= 0.4" + "node": ">=20" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "node_modules/sass": { - "version": "1.85.0", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.85.0.tgz", - "integrity": "sha512-3ToiC1xZ1Y8aU7+CkgCI/tqyuPXEmYGJXO7H4uqp0xkLXUqp88rQQ4j1HmP37xSJLbCJPaIiv+cT1y+grssrww==", + "node_modules/ora/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, - "dependencies": { - "chokidar": "^4.0.0", - "immutable": "^5.0.2", - "source-map-js": ">=0.6.2 <2.0.0" - }, - "bin": { - "sass": "sass.js" - }, + "license": "MIT", "engines": { - "node": ">=14.0.0" + "node": "^12.17.0 || ^14.13 || >=16.0.0" }, - "optionalDependencies": { - "@parcel/watcher": "^2.4.1" + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/sass-loader": { - "version": "16.0.5", - "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-16.0.5.tgz", - "integrity": "sha512-oL+CMBXrj6BZ/zOq4os+UECPL+bWqt6OAC6DWS8Ln8GZRcMDjlJ4JC3FBDuHJdYaFWIdKNIBYmtZtK2MaMkNIw==", + "node_modules/ora/node_modules/string-width": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.1.1.tgz", + "integrity": "sha512-KpqHIdDL9KwYk22wEOg/VIqYbrnLeSApsKT/bSj6Ez7pn3CftUiLAv2Lccpq1ALcpLV9UX1Ppn92npZWu2w/aw==", "dev": true, + "license": "MIT", "dependencies": { - "neo-async": "^2.6.2" + "get-east-asian-width": "^1.3.0", + "strip-ansi": "^7.1.0" }, "engines": { - "node": ">= 18.12.0" + "node": ">=20" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "@rspack/core": "0.x || 1.x", - "node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0", - "sass": "^1.3.0", - "sass-embedded": "*", - "webpack": "^5.0.0" - }, - "peerDependenciesMeta": { - "@rspack/core": { - "optional": true - }, - "node-sass": { - "optional": true - }, - "sass": { - "optional": true - }, - "sass-embedded": { - "optional": true - }, - "webpack": { - "optional": true - } + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/sax": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", - "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==", + "node_modules/ordered-binary": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/ordered-binary/-/ordered-binary-1.6.1.tgz", + "integrity": "sha512-QkCdPooczexPLiXIrbVOPYkR3VO3T6v2OyKRkR1Xbhpy7/LAVXwahnRCgRp78Oe/Ehf0C/HATAxfSr6eA1oX+w==", "dev": true, + "license": "MIT", "optional": true }, - "node_modules/schema-utils": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.2.tgz", - "integrity": "sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ==", + "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": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.9.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.1.0" + "yocto-queue": "^0.1.0" }, "engines": { - "node": ">= 10.13.0" + "node": ">=10" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/schema-utils/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==", + "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": { - "ajv": "^8.0.0" + "p-limit": "^3.0.2" }, - "peerDependencies": { - "ajv": "^8.0.0" + "engines": { + "node": ">=10" }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/select-hose": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", - "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==", - "dev": true - }, - "node_modules/selfsigned": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz", - "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", + "node_modules/p-map": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-7.0.4.tgz", + "integrity": "sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ==", "dev": true, - "dependencies": { - "@types/node-forge": "^1.3.0", - "node-forge": "^1" - }, + "license": "MIT", "engines": { - "node": ">=10" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/semver": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", - "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", - "dev": true, + "node_modules/pacote": { + "version": "21.0.4", + "resolved": "https://registry.npmjs.org/pacote/-/pacote-21.0.4.tgz", + "integrity": "sha512-RplP/pDW0NNNDh3pnaoIWYPvNenS7UqMbXyvMqJczosiFWTeGGwJC2NQBLqKf4rGLFfwCOnntw1aEp9Jiqm1MA==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/git": "^7.0.0", + "@npmcli/installed-package-contents": "^4.0.0", + "@npmcli/package-json": "^7.0.0", + "@npmcli/promise-spawn": "^9.0.0", + "@npmcli/run-script": "^10.0.0", + "cacache": "^20.0.0", + "fs-minipass": "^3.0.0", + "minipass": "^7.0.2", + "npm-package-arg": "^13.0.0", + "npm-packlist": "^10.0.1", + "npm-pick-manifest": "^11.0.1", + "npm-registry-fetch": "^19.0.0", + "proc-log": "^6.0.0", + "promise-retry": "^2.0.1", + "sigstore": "^4.0.0", + "ssri": "^13.0.0", + "tar": "^7.4.3" + }, "bin": { - "semver": "bin/semver.js" + "pacote": "bin/index.js" }, "engines": { - "node": ">=10" + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/send": { - "version": "0.19.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", - "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", + "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, "dependencies": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" + "callsites": "^3.0.0" }, "engines": { - "node": ">= 0.8.0" + "node": ">=6" } }, - "node_modules/send/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "node_modules/parse5": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-8.0.0.tgz", + "integrity": "sha512-9m4m5GSgXjL4AjumKzq1Fgfp3Z8rsvjRNbnkVwfu2ImRqE5D0LnY2QfDen18FSY9C573YU5XxSapdHZTZ2WolA==", + "dev": true, + "license": "MIT", "dependencies": { - "ms": "2.0.0" + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" } }, - "node_modules/send/node_modules/debug/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/send/node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", - "engines": { - "node": ">= 0.8" + "node_modules/parse5-html-rewriting-stream": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/parse5-html-rewriting-stream/-/parse5-html-rewriting-stream-8.0.0.tgz", + "integrity": "sha512-wzh11mj8KKkno1pZEu+l2EVeWsuKDfR5KNWZOTsslfUX8lPDZx77m9T0kIoAVkFtD1nx6YF8oh4BnPHvxMtNMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "entities": "^6.0.0", + "parse5": "^8.0.0", + "parse5-sax-parser": "^8.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" } }, - "node_modules/send/node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "bin": { - "mime": "cli.js" - }, + "node_modules/parse5-html-rewriting-stream/node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "dev": true, + "license": "BSD-2-Clause", "engines": { - "node": ">=4" + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" } }, - "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==", + "node_modules/parse5-sax-parser": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/parse5-sax-parser/-/parse5-sax-parser-8.0.0.tgz", + "integrity": "sha512-/dQ8UzHZwnrzs3EvDj6IkKrD/jIZyTlB+8XrHJvcjNgRdmWruNdN9i9RK/JtxakmlUdPwKubKPTCqvbTgzGhrw==", "dev": true, + "license": "MIT", "dependencies": { - "randombytes": "^2.1.0" + "parse5": "^8.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" } }, - "node_modules/serve-index": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", - "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", + "node_modules/parse5/node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", "dev": true, - "dependencies": { - "accepts": "~1.3.4", - "batch": "0.6.1", - "debug": "2.6.9", - "escape-html": "~1.0.3", - "http-errors": "~1.6.2", - "mime-types": "~2.1.17", - "parseurl": "~1.3.2" + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "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": ">= 0.8.0" + "node": ">=8" } }, - "node_modules/serve-index/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "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, - "dependencies": { - "ms": "2.0.0" + "engines": { + "node": ">=0.10.0" } }, - "node_modules/serve-index/node_modules/depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "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, "engines": { - "node": ">= 0.6" + "node": ">=8" } }, - "node_modules/serve-index/node_modules/http-errors": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", + "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.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.1.tgz", + "integrity": "sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==", "dev": true, + "license": "BlueOak-1.0.0", "dependencies": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": ">= 1.4.0 < 2" + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" }, "engines": { - "node": ">= 0.6" + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/serve-index/node_modules/inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", - "dev": true + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "11.2.6", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.6.tgz", + "integrity": "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } }, - "node_modules/serve-index/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true + "node_modules/path-to-regexp": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz", + "integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==", + "dev": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } }, - "node_modules/serve-index/node_modules/setprototypeof": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "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 }, - "node_modules/serve-index/node_modules/statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, + "license": "MIT", "engines": { - "node": ">= 0.6" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/serve-static": { - "version": "1.16.2", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", - "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", - "dependencies": { - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.19.0" + "node_modules/pidtree": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.6.0.tgz", + "integrity": "sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==", + "dev": true, + "license": "MIT", + "bin": { + "pidtree": "bin/pidtree.js" }, "engines": { - "node": ">= 0.8.0" + "node": ">=0.10" } }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" - }, - "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==", + "node_modules/piscina": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/piscina/-/piscina-5.1.4.tgz", + "integrity": "sha512-7uU4ZnKeQq22t9AsmHGD2w4OYQGonwFnTypDypaWi7Qr2EvQIFVtG8J5D/3bE7W123Wdc9+v4CZDu5hJXVCtBg==", "dev": true, - "dependencies": { - "kind-of": "^6.0.2" + "license": "MIT", + "engines": { + "node": ">=20.x" }, + "optionalDependencies": { + "@napi-rs/nice": "^1.0.4" + } + }, + "node_modules/pkce-challenge": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-5.0.1.tgz", + "integrity": "sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==", + "dev": true, + "license": "MIT", "engines": { - "node": ">=8" + "node": ">=16.20.0" } }, - "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==", + "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": { - "shebang-regex": "^3.0.0" + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" }, "engines": { - "node": ">=8" + "node": "^10 || ^12 || >=14" } }, - "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==", + "node_modules/postcss-media-query-parser": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz", + "integrity": "sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==", + "dev": true, + "license": "MIT" + }, + "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": ">=8" + "node": ">= 0.8.0" } }, - "node_modules/shell-quote": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.3.tgz", - "integrity": "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==", + "node_modules/prettier": { + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.1.tgz", + "integrity": "sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==", "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, "engines": { - "node": ">= 0.4" + "node": ">=14" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/prettier/prettier?sponsor=1" } }, - "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==", - "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" - }, + "node_modules/proc-log": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-6.1.0.tgz", + "integrity": "sha512-iG+GYldRf2BQ0UDUAd6JQ/RwzaQy6mXmsk/IzlYyal4A4SNFw54MeH4/tLkF4I5WoWG9SQwuqWzS99jaFQHBuQ==", + "dev": true, + "license": "ISC", "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "^20.17.0 || >=22.9.0" } }, - "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==", + "node_modules/promise-retry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", + "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", + "dev": true, + "license": "MIT", "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.3" + "err-code": "^2.0.2", + "retry": "^0.12.0" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=10" } }, - "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==", + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "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" + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">= 0.10" } }, - "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==", + "node_modules/punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", + "dev": true + }, + "node_modules/pyodide": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/pyodide/-/pyodide-0.28.0.tgz", + "integrity": "sha512-QML/Gh8eu50q5zZKLNpW6rgS0XUdK+94OSL54AUSKV8eJAxgwZrMebqj+CyM0EbF3EUX8JFJU3ryaxBViHammQ==", "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" + "ws": "^8.5.0" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=18.0.0" } }, - "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==", + "node_modules/qjobs": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz", + "integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==", "dev": true, "engines": { - "node": ">=14" + "node": ">=0.9" + } + }, + "node_modules/qs": { + "version": "6.14.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.2.tgz", + "integrity": "sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">=0.6" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/sigstore": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/sigstore/-/sigstore-3.1.0.tgz", - "integrity": "sha512-ZpzWAFHIFqyFE56dXqgX/DkDRZdz+rRcjoIk/RQU4IX0wiCv1l8S7ZrXDHcCc+uaf+6o7w3h2l3g6GYG5TKN9Q==", + "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" + } + ] + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", "dev": true, - "dependencies": { - "@sigstore/bundle": "^3.1.0", - "@sigstore/core": "^2.0.0", - "@sigstore/protobuf-specs": "^0.4.0", - "@sigstore/sign": "^3.1.0", - "@sigstore/tuf": "^3.1.0", - "@sigstore/verify": "^2.1.0" - }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": ">= 0.6" } }, - "node_modules/slash": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", - "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", + "node_modules/raw-body": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.3.tgz", + "integrity": "sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==", "dev": true, - "engines": { - "node": ">=14.16" + "license": "MIT", + "dependencies": { + "bytes": "~3.1.2", + "http-errors": "~2.0.1", + "iconv-lite": "~0.4.24", + "unpipe": "~1.0.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">= 0.8" } }, - "node_modules/slice-ansi": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", - "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", + "node_modules/raw-body/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "dev": true, + "license": "MIT", "dependencies": { - "ansi-styles": "^6.0.0", - "is-fullwidth-code-point": "^4.0.0" + "safer-buffer": ">= 2.1.2 < 3" }, "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" + "node": ">=0.10.0" } }, - "node_modules/slice-ansi/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", "dev": true, "engines": { - "node": ">=12" + "node": ">= 14.18.0" }, "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "type": "individual", + "url": "https://paulmillr.com/funding/" } }, - "node_modules/smart-buffer": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", - "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "node_modules/reflect-metadata": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz", + "integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==", "dev": true, - "engines": { - "node": ">= 6.0.0", - "npm": ">= 3.0.0" - } + "license": "Apache-2.0" }, - "node_modules/socket.io": { - "version": "4.8.1", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.8.1.tgz", - "integrity": "sha512-oZ7iUCxph8WYRHHcjBEc9unw3adt5CmSNlppj/5Q4k2RIrhl8Z5yY2Xr4j9zj0+wzVZ0bxmYoGSzKJnRl6A4yg==", + "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, - "dependencies": { - "accepts": "~1.3.4", - "base64id": "~2.0.0", - "cors": "~2.8.5", - "debug": "~4.3.2", - "engine.io": "~6.6.0", - "socket.io-adapter": "~2.5.2", - "socket.io-parser": "~4.2.4" - }, "engines": { - "node": ">=10.2.0" + "node": ">=0.10.0" } }, - "node_modules/socket.io-adapter": { - "version": "2.5.5", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.5.tgz", - "integrity": "sha512-eLDQas5dzPgOWCk9GuuJC2lBqItuhKI4uxGgo9aIV7MYbk2h9Q6uULEh8WBzThoI7l+qU9Ast9fVUmkqPP9wYg==", + "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, - "dependencies": { - "debug": "~4.3.4", - "ws": "~8.17.1" + "engines": { + "node": ">=0.10.0" } }, - "node_modules/socket.io-adapter/node_modules/debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "dev": true + }, + "node_modules/resolve": { + "version": "1.22.11", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", + "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", "dev": true, + "license": "MIT", "dependencies": { - "ms": "^2.1.3" + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" }, - "engines": { - "node": ">=6.0" + "bin": { + "resolve": "bin/resolve" }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/socket.io-adapter/node_modules/ws": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", - "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", - "dev": true, "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" + "node": ">= 0.4" }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/socket.io-parser": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz", - "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==", + "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, - "dependencies": { - "@socket.io/component-emitter": "~3.1.0", - "debug": "~4.3.1" - }, "engines": { - "node": ">=10.0.0" + "node": ">=4" } }, - "node_modules/socket.io-parser/node_modules/debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "node_modules/restore-cursor": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", + "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", "dev": true, "dependencies": { - "ms": "^2.1.3" + "onetime": "^7.0.0", + "signal-exit": "^4.1.0" }, "engines": { - "node": ">=6.0" + "node": ">=18" }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/socket.io/node_modules/debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "node_modules/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", "dev": true, - "dependencies": { - "ms": "^2.1.3" - }, + "license": "MIT", "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/sockjs": { - "version": "0.3.24", - "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", - "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", - "dev": true, - "dependencies": { - "faye-websocket": "^0.11.3", - "uuid": "^8.3.2", - "websocket-driver": "^0.7.4" + "node": ">= 4" } }, - "node_modules/socks": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.5.tgz", - "integrity": "sha512-iF+tNDQla22geJdTyJB1wM/qrX9DMRwWrciEPwWLPRWAUEM8sQiyxgckLxWT1f7+9VabJS0jTGGr4QgBuvi6Ww==", + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", "dev": true, - "dependencies": { - "ip-address": "^9.0.5", - "smart-buffer": "^4.2.0" - }, "engines": { - "node": ">= 10.0.0", - "npm": ">= 3.0.0" + "iojs": ">=1.0.0", + "node": ">=0.10.0" } }, - "node_modules/socks-proxy-agent": { - "version": "8.0.5", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz", - "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==", + "node_modules/rfdc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", + "dev": true + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", "dev": true, "dependencies": { - "agent-base": "^7.1.2", - "debug": "^4.3.4", - "socks": "^2.8.3" + "glob": "^7.1.3" }, - "engines": { - "node": ">= 14" + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/source-map": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", - "dev": true, - "engines": { - "node": ">= 8" - } + "node_modules/robust-predicates": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.2.tgz", + "integrity": "sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==" }, - "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==", + "node_modules/rolldown": { + "version": "1.0.0-beta.58", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-beta.58.tgz", + "integrity": "sha512-v1FCjMZCan7f+xGAHBi+mqiE4MlH7I+SXEHSQSJoMOGNNB2UYtvMiejsq9YuUOiZjNeUeV/a21nSFbrUR+4ZCQ==", "dev": true, + "license": "MIT", + "dependencies": { + "@oxc-project/types": "=0.106.0", + "@rolldown/pluginutils": "1.0.0-beta.58" + }, + "bin": { + "rolldown": "bin/cli.mjs" + }, "engines": { - "node": ">=0.10.0" + "node": "^20.19.0 || >=22.12.0" + }, + "optionalDependencies": { + "@rolldown/binding-android-arm64": "1.0.0-beta.58", + "@rolldown/binding-darwin-arm64": "1.0.0-beta.58", + "@rolldown/binding-darwin-x64": "1.0.0-beta.58", + "@rolldown/binding-freebsd-x64": "1.0.0-beta.58", + "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-beta.58", + "@rolldown/binding-linux-arm64-gnu": "1.0.0-beta.58", + "@rolldown/binding-linux-arm64-musl": "1.0.0-beta.58", + "@rolldown/binding-linux-x64-gnu": "1.0.0-beta.58", + "@rolldown/binding-linux-x64-musl": "1.0.0-beta.58", + "@rolldown/binding-openharmony-arm64": "1.0.0-beta.58", + "@rolldown/binding-wasm32-wasi": "1.0.0-beta.58", + "@rolldown/binding-win32-arm64-msvc": "1.0.0-beta.58", + "@rolldown/binding-win32-x64-msvc": "1.0.0-beta.58" } }, - "node_modules/source-map-loader": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/source-map-loader/-/source-map-loader-5.0.0.tgz", - "integrity": "sha512-k2Dur7CbSLcAH73sBcIkV5xjPV4SzqO1NJ7+XaQl8if3VODDUj3FNchNGpqgJSKbvUfJuhVdv8K2Eu8/TNl2eA==", + "node_modules/rollup": { + "version": "4.52.3", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.52.3.tgz", + "integrity": "sha512-RIDh866U8agLgiIcdpB+COKnlCreHJLfIhWC3LVflku5YHfpnsIKigRZeFfMfCc4dVcqNVfQQ5gO/afOck064A==", "dev": true, + "license": "MIT", "dependencies": { - "iconv-lite": "^0.6.3", - "source-map-js": "^1.0.2" + "@types/estree": "1.0.8" }, - "engines": { - "node": ">= 18.12.0" + "bin": { + "rollup": "dist/bin/rollup" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" }, - "peerDependencies": { - "webpack": "^5.72.1" + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.52.3", + "@rollup/rollup-android-arm64": "4.52.3", + "@rollup/rollup-darwin-arm64": "4.52.3", + "@rollup/rollup-darwin-x64": "4.52.3", + "@rollup/rollup-freebsd-arm64": "4.52.3", + "@rollup/rollup-freebsd-x64": "4.52.3", + "@rollup/rollup-linux-arm-gnueabihf": "4.52.3", + "@rollup/rollup-linux-arm-musleabihf": "4.52.3", + "@rollup/rollup-linux-arm64-gnu": "4.52.3", + "@rollup/rollup-linux-arm64-musl": "4.52.3", + "@rollup/rollup-linux-loong64-gnu": "4.52.3", + "@rollup/rollup-linux-ppc64-gnu": "4.52.3", + "@rollup/rollup-linux-riscv64-gnu": "4.52.3", + "@rollup/rollup-linux-riscv64-musl": "4.52.3", + "@rollup/rollup-linux-s390x-gnu": "4.52.3", + "@rollup/rollup-linux-x64-gnu": "4.52.3", + "@rollup/rollup-linux-x64-musl": "4.52.3", + "@rollup/rollup-openharmony-arm64": "4.52.3", + "@rollup/rollup-win32-arm64-msvc": "4.52.3", + "@rollup/rollup-win32-ia32-msvc": "4.52.3", + "@rollup/rollup-win32-x64-gnu": "4.52.3", + "@rollup/rollup-win32-x64-msvc": "4.52.3", + "fsevents": "~2.3.2" } }, - "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==", + "node_modules/router": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", + "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==", "dev": true, + "license": "MIT", "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/source-map-support/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, + "debug": "^4.4.0", + "depd": "^2.0.0", + "is-promise": "^4.0.0", + "parseurl": "^1.3.3", + "path-to-regexp": "^8.0.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">= 18" } }, - "node_modules/spdx-correct": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", - "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "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" + } + ], "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" + "queue-microtask": "^1.2.2" } }, - "node_modules/spdx-exceptions": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", - "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", - "dev": true + "node_modules/rw": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", + "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==" }, - "node_modules/spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "dev": true, + "node_modules/rxjs": { + "version": "7.8.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", + "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" + "tslib": "^2.1.0" } }, - "node_modules/spdx-license-ids": { - "version": "3.0.21", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.21.tgz", - "integrity": "sha512-Bvg/8F5XephndSK3JffaRqdT+gyhfqIPwDHpX80tJrF8QQRYMo8sNMeaZ2Dp5+jhwKnUmIOyFFQfHRkjJm5nXg==", - "dev": true - }, - "node_modules/spdy": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", - "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", + "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, "dependencies": { - "debug": "^4.1.0", - "handle-thing": "^2.0.0", - "http-deceiver": "^1.2.7", - "select-hose": "^2.0.0", - "spdy-transport": "^3.0.0" + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" }, "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/spdy-transport": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", - "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", - "dev": true, - "dependencies": { - "debug": "^4.1.0", - "detect-node": "^2.0.4", - "hpack.js": "^2.1.6", - "obuf": "^1.1.2", - "readable-stream": "^3.0.6", - "wbuf": "^1.7.3" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/sprintf-js": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", - "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", - "dev": true + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, - "node_modules/ssri": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-12.0.0.tgz", - "integrity": "sha512-S7iGNosepx9RadX82oimUkvr0Ct7IjJbEbs4mJcTxst8um95J3sDYU1RBEOvdu6oL1Wek2ODI5i4MAw+dZ6cAQ==", + "node_modules/sass": { + "version": "1.97.1", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.97.1.tgz", + "integrity": "sha512-uf6HoO8fy6ClsrShvMgaKUn14f2EHQLQRtpsZZLeU/Mv0Q1K5P0+x2uvH6Cub39TVVbWNSrraUhDAoFph6vh0A==", "dev": true, + "license": "MIT", "dependencies": { - "minipass": "^7.0.3" + "chokidar": "^4.0.0", + "immutable": "^5.0.2", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": ">=14.0.0" + }, + "optionalDependencies": { + "@parcel/watcher": "^2.4.1" } }, - "node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "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": ">= 0.8" + "node": ">=10" } }, - "node_modules/streamroller": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-3.1.5.tgz", - "integrity": "sha512-KFxaM7XT+irxvdqSP1LGLgNWbYN7ay5owZ3r/8t77p+EtSUAfUgtl7be3xtqtOmGUl9K9YPO2ca8133RlTjvKw==", - "dev": true, - "dependencies": { - "date-format": "^4.0.14", - "debug": "^4.3.4", - "fs-extra": "^8.1.0" + "node_modules/send": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz", + "integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.4.3", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "fresh": "^2.0.0", + "http-errors": "^2.0.1", + "mime-types": "^3.0.2", + "ms": "^2.1.3", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "statuses": "^2.0.2" }, "engines": { - "node": ">=8.0" + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "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==", + "node_modules/send/node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", "dev": true, - "dependencies": { - "safe-buffer": "~5.2.0" + "license": "MIT", + "engines": { + "node": ">= 0.6" } }, - "node_modules/string-width": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", - "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "node_modules/send/node_modules/mime-types": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", "dev": true, + "license": "MIT", "dependencies": { - "emoji-regex": "^10.3.0", - "get-east-asian-width": "^1.0.0", - "strip-ansi": "^7.1.0" + "mime-db": "^1.54.0" }, "engines": { "node": ">=18" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "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==", + "node_modules/serve-static": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz", + "integrity": "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==", "dev": true, + "license": "MIT", "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "parseurl": "^1.3.3", + "send": "^1.2.0" }, "engines": { - "node": ">=8" + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/string-width-cjs/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==", + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "dev": true + }, + "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, + "dependencies": { + "shebang-regex": "^3.0.0" + }, "engines": { "node": ">=8" } }, - "node_modules/string-width-cjs/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 - }, - "node_modules/string-width-cjs/node_modules/is-fullwidth-code-point": { + "node_modules/shebang-regex": { "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==", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, "engines": { "node": ">=8" } }, - "node_modules/string-width-cjs/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==", + "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, "dependencies": { - "ansi-regex": "^5.0.1" + "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": ">=8" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "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, "dependencies": { - "ansi-regex": "^6.0.1" + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" }, "engines": { - "node": ">=12" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" + "url": "https://github.com/sponsors/ljharb" } }, - "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==", + "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, "dependencies": { - "ansi-regex": "^5.0.1" + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" }, "engines": { - "node": ">=8" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/strip-ansi-cjs/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==", + "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, + "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": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, "engines": { - "node": ">=8" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "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==", + "node_modules/sigstore": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/sigstore/-/sigstore-4.1.0.tgz", + "integrity": "sha512-/fUgUhYghuLzVT/gaJoeVehLCgZiUxPCPMcyVNY0lIf/cTCz58K/WTI7PefDarXxp9nUKpEwg1yyz3eSBMTtgA==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "has-flag": "^4.0.0" + "@sigstore/bundle": "^4.0.0", + "@sigstore/core": "^3.1.0", + "@sigstore/protobuf-specs": "^0.5.0", + "@sigstore/sign": "^4.1.0", + "@sigstore/tuf": "^4.0.1", + "@sigstore/verify": "^3.1.0" }, "engines": { - "node": ">=8" + "node": "^20.17.0 || >=22.9.0" } }, - "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==", + "node_modules/slice-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.2.tgz", + "integrity": "sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w==", "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "is-fullwidth-code-point": "^5.0.0" + }, "engines": { - "node": ">= 0.4" + "node": ">=18" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, - "node_modules/symbol-observable": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-4.0.0.tgz", - "integrity": "sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==", + "node_modules/slice-ansi/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": ">=0.10" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/tapable": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.2.tgz", - "integrity": "sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==", + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", "dev": true, + "license": "MIT", "engines": { - "node": ">=6" + "node": ">= 6.0.0", + "npm": ">= 3.0.0" } }, - "node_modules/tar": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", - "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", + "node_modules/socket.io": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.8.1.tgz", + "integrity": "sha512-oZ7iUCxph8WYRHHcjBEc9unw3adt5CmSNlppj/5Q4k2RIrhl8Z5yY2Xr4j9zj0+wzVZ0bxmYoGSzKJnRl6A4yg==", "dev": true, "dependencies": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^5.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" + "accepts": "~1.3.4", + "base64id": "~2.0.0", + "cors": "~2.8.5", + "debug": "~4.3.2", + "engine.io": "~6.6.0", + "socket.io-adapter": "~2.5.2", + "socket.io-parser": "~4.2.4" }, "engines": { - "node": ">=10" + "node": ">=10.2.0" } }, - "node_modules/tar/node_modules/fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "node_modules/socket.io-adapter": { + "version": "2.5.5", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.5.tgz", + "integrity": "sha512-eLDQas5dzPgOWCk9GuuJC2lBqItuhKI4uxGgo9aIV7MYbk2h9Q6uULEh8WBzThoI7l+qU9Ast9fVUmkqPP9wYg==", "dev": true, "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" + "debug": "~4.3.4", + "ws": "~8.17.1" } }, - "node_modules/tar/node_modules/fs-minipass/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "node_modules/socket.io-adapter/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "dev": true, "dependencies": { - "yallist": "^4.0.0" + "ms": "^2.1.3" }, "engines": { - "node": ">=8" + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/tar/node_modules/minipass": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", - "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "node_modules/socket.io-adapter/node_modules/ws": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", "dev": true, "engines": { - "node": ">=8" + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } } }, - "node_modules/tar/node_modules/minizlib": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "node_modules/socket.io-parser": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz", + "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==", "dev": true, "dependencies": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1" }, "engines": { - "node": ">= 8" + "node": ">=10.0.0" } }, - "node_modules/tar/node_modules/minizlib/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "node_modules/socket.io-parser/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "dev": true, "dependencies": { - "yallist": "^4.0.0" + "ms": "^2.1.3" }, "engines": { - "node": ">=8" + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/tar/node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "node_modules/socket.io/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "dev": true, - "bin": { - "mkdirp": "bin/cmd.js" + "dependencies": { + "ms": "^2.1.3" }, "engines": { - "node": ">=10" + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/tar/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/terser": { - "version": "5.39.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.39.0.tgz", - "integrity": "sha512-LBAhFyLho16harJoWMg/nZsQYgTrg5jXOn2nCYjRUcZZEdE3qa2zb8QEDRUGVZBW4rlazf2fxkg8tztybTaqWw==", + "node_modules/socks": { + "version": "2.8.7", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.7.tgz", + "integrity": "sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==", "dev": true, + "license": "MIT", "dependencies": { - "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.8.2", - "commander": "^2.20.0", - "source-map-support": "~0.5.20" - }, - "bin": { - "terser": "bin/terser" + "ip-address": "^10.0.1", + "smart-buffer": "^4.2.0" }, "engines": { - "node": ">=10" + "node": ">= 10.0.0", + "npm": ">= 3.0.0" } }, - "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==", + "node_modules/socks-proxy-agent": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz", + "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==", "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" + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "socks": "^2.8.3" }, "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": ">= 14" } }, - "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 + "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/thingies": { - "version": "1.21.0", - "resolved": "https://registry.npmjs.org/thingies/-/thingies-1.21.0.tgz", - "integrity": "sha512-hsqsJsFMsV+aD4s3CWKk85ep/3I9XzYV/IXaSouJMYIoDlgyi11cBhsqYe9/geRfB0YIikBQg6raRaM+nIMP9g==", + "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, "engines": { - "node": ">=10.18" - }, - "peerDependencies": { - "tslib": "^2" + "node": ">=0.10.0" } }, - "node_modules/three": { - "version": "0.176.0", - "resolved": "https://registry.npmjs.org/three/-/three-0.176.0.tgz", - "integrity": "sha512-PWRKYWQo23ojf9oZSlRGH8K09q7nRSWx6LY/HF/UUrMdYgN9i1e2OwJYHoQjwc6HF/4lvvYLC5YC1X8UJL2ZpA==" + "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, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } }, - "node_modules/thunky": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", - "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", - "dev": true + "node_modules/source-map-support/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, + "engines": { + "node": ">=0.10.0" + } }, - "node_modules/tinyglobby": { - "version": "0.2.14", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz", - "integrity": "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==", + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "fdir": "^6.4.4", - "picomatch": "^4.0.2" - }, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/SuperchupuDev" + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" } }, - "node_modules/tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "dev": true, + "license": "CC-BY-3.0" + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", "dev": true, + "license": "MIT", "dependencies": { - "os-tmpdir": "~1.0.2" - }, - "engines": { - "node": ">=0.6.0" + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" } }, - "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==", + "node_modules/spdx-license-ids": { + "version": "3.0.22", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.22.tgz", + "integrity": "sha512-4PRT4nh1EImPbt2jASOKHX7PB7I+e4IWNLvkKFDxNhJlfjbYlleYQh285Z/3mPTHSAK/AvdMmw5BNNuYH8ShgQ==", "dev": true, + "license": "CC0-1.0" + }, + "node_modules/ssri": { + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-13.0.1.tgz", + "integrity": "sha512-QUiRf1+u9wPTL/76GTYlKttDEBWV1ga9ZXW8BG6kfdeyyM8LGPix9gROyg9V2+P0xNyF3X2Go526xKFdMZrHSQ==", + "dev": true, + "license": "ISC", "dependencies": { - "is-number": "^7.0.0" + "minipass": "^7.0.3" }, "engines": { - "node": ">=8.0" + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "node_modules/statuses": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "dev": true, + "license": "MIT", "engines": { - "node": ">=0.6" + "node": ">= 0.8" } }, - "node_modules/tree-dump": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tree-dump/-/tree-dump-1.0.3.tgz", - "integrity": "sha512-il+Cv80yVHFBwokQSfd4bldvr1Md951DpgAGfmhydt04L+YzHgubm2tQ7zueWDcGENKHq0ZvGFR/hjvNXilHEg==", + "node_modules/stdin-discarder": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/stdin-discarder/-/stdin-discarder-0.2.2.tgz", + "integrity": "sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==", "dev": true, + "license": "MIT", "engines": { - "node": ">=10.0" + "node": ">=18" }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/tree-kill": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", - "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "node_modules/streamroller": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-3.1.5.tgz", + "integrity": "sha512-KFxaM7XT+irxvdqSP1LGLgNWbYN7ay5owZ3r/8t77p+EtSUAfUgtl7be3xtqtOmGUl9K9YPO2ca8133RlTjvKw==", "dev": true, - "bin": { - "tree-kill": "cli.js" + "dependencies": { + "date-format": "^4.0.14", + "debug": "^4.3.4", + "fs-extra": "^8.1.0" + }, + "engines": { + "node": ">=8.0" } }, - "node_modules/tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" - }, - "node_modules/tuf-js": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/tuf-js/-/tuf-js-3.1.0.tgz", - "integrity": "sha512-3T3T04WzowbwV2FDiGXBbr81t64g1MUGGJRgT4x5o97N+8ArdhVCAF9IxFrxuSJmM3E5Asn7nKHkao0ibcZXAg==", + "node_modules/string-argv": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", + "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", "dev": true, - "dependencies": { - "@tufjs/models": "3.0.1", - "debug": "^4.4.1", - "make-fetch-happen": "^14.0.3" - }, + "license": "MIT", "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": ">=0.6.19" } }, - "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==", + "node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", "dev": true, + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, "engines": { - "node": ">=10" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "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": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" + "ansi-regex": "^6.0.1" }, "engines": { - "node": ">= 0.6" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "node_modules/typed-assert": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/typed-assert/-/typed-assert-1.0.9.tgz", - "integrity": "sha512-KNNZtayBCtmnNmbo5mG47p1XsCyrx6iVqomjcZnec/1Y5GGARaxPs6r49RnSPeUP3YjNYiU9sQHAtY4BBvnZwg==", - "dev": true - }, - "node_modules/typescript": { - "version": "5.7.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz", - "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==", + "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, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, + "license": "MIT", "engines": { - "node": ">=14.17" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ua-parser-js": { - "version": "0.7.40", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.40.tgz", - "integrity": "sha512-us1E3K+3jJppDBa3Tl0L3MOJiGhe1C6P0+nIvQAFYbxlMAx0h81eOwLmU57xgqToduDDPx3y5QsdjPfDu+FgOQ==", + "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, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/ua-parser-js" - }, - { - "type": "paypal", - "url": "https://paypal.me/faisalman" - }, - { - "type": "github", - "url": "https://github.com/sponsors/faisalman" - } - ], - "bin": { - "ua-parser-js": "script/cli.js" + "dependencies": { + "has-flag": "^4.0.0" }, "engines": { - "node": "*" + "node": ">=8" } }, - "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "dev": true - }, - "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==", + "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": ">=4" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "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==", + "node_modules/tar": { + "version": "7.5.9", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.9.tgz", + "integrity": "sha512-BTLcK0xsDh2+PUe9F6c2TlRp4zOOBMTkoQHQIWSIzI0R7KG46uEwq4OPk2W7bZcprBMsuaeFsqwYr7pjh6CuHg==", "dev": true, + "license": "BlueOak-1.0.0", "dependencies": { - "unicode-canonical-property-names-ecmascript": "^2.0.0", - "unicode-property-aliases-ecmascript": "^2.0.0" + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.1.0", + "yallist": "^5.0.0" }, "engines": { - "node": ">=4" + "node": ">=18" } }, - "node_modules/unicode-match-property-value-ecmascript": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.0.tgz", - "integrity": "sha512-4IehN3V/+kkr5YeSSDDQG8QLqO26XpL2XP3GQtqwlT/QYSECAwFztxVHjlbh0+gjJ3XmNLS0zDsbgs9jWKExLg==", + "node_modules/tar/node_modules/yallist": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", "dev": true, + "license": "BlueOak-1.0.0", "engines": { - "node": ">=4" + "node": ">=18" } }, - "node_modules/unicode-property-aliases-ecmascript": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", - "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", - "dev": true, - "engines": { - "node": ">=4" - } + "node_modules/three": { + "version": "0.176.0", + "resolved": "https://registry.npmjs.org/three/-/three-0.176.0.tgz", + "integrity": "sha512-PWRKYWQo23ojf9oZSlRGH8K09q7nRSWx6LY/HF/UUrMdYgN9i1e2OwJYHoQjwc6HF/4lvvYLC5YC1X8UJL2ZpA==" }, - "node_modules/unicorn-magic": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz", - "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==", + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, "engines": { - "node": ">=18" + "node": ">=12.0.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/SuperchupuDev" } }, - "node_modules/unique-filename": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-4.0.0.tgz", - "integrity": "sha512-XSnEewXmQ+veP7xX2dS5Q4yZAvO40cBN2MWkJ7D/6sW4Dg6wYBNwM1Vrnz1FhH5AdeLIlUXRI9e28z1YZi71NQ==", + "node_modules/tmp": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.5.tgz", + "integrity": "sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==", "dev": true, - "dependencies": { - "unique-slug": "^5.0.0" - }, + "license": "MIT", "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": ">=14.14" } }, - "node_modules/unique-slug": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-5.0.0.tgz", - "integrity": "sha512-9OdaqO5kwqR+1kVgHAhsp5vPNU0hnxRa26rBFNfNgM7M6pNtgzeBn3s/xbyCQL3dcjzOatcef6UUHpB/6MaETg==", + "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, "dependencies": { - "imurmurhash": "^0.1.4" + "is-number": "^7.0.0" }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": ">=8.0" } }, - "node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", "dev": true, "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "engines": { - "node": ">= 0.8" + "node": ">=0.6" } }, - "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==", + "node_modules/ts-api-utils": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.4.0.tgz", + "integrity": "sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==", "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" - } - ], - "dependencies": { - "escalade": "^3.2.0", - "picocolors": "^1.1.1" - }, - "bin": { - "update-browserslist-db": "cli.js" + "license": "MIT", + "engines": { + "node": ">=18.12" }, "peerDependencies": { - "browserslist": ">= 4.21.0" + "typescript": ">=4.8.4" } }, - "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 - }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", - "engines": { - "node": ">= 0.4.0" - } + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" }, - "node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "node_modules/tuf-js": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/tuf-js/-/tuf-js-4.1.0.tgz", + "integrity": "sha512-50QV99kCKH5P/Vs4E2Gzp7BopNV+KzTXqWeaxrfu5IQJBOULRsTIS9seSsOVT8ZnGXzCyx55nYWAi4qJzpZKEQ==", "dev": true, - "bin": { - "uuid": "dist/bin/uuid" + "license": "MIT", + "dependencies": { + "@tufjs/models": "4.1.0", + "debug": "^4.4.3", + "make-fetch-happen": "^15.0.1" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "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": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" } }, - "node_modules/validate-npm-package-name": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-6.0.1.tgz", - "integrity": "sha512-OaI//3H0J7ZkR1OqlhGA8cA+Cbk/2xFOQpJOt5+s27/ta9eZwpeervh4Mxh4w0im/kdgktowaqVNR7QOrUd7Yg==", + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", "dev": true, + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": ">= 0.6" } }, - "node_modules/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "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": ">= 0.8" + "node": ">=14.17" } }, - "node_modules/vite": { - "version": "6.2.7", - "resolved": "https://registry.npmjs.org/vite/-/vite-6.2.7.tgz", - "integrity": "sha512-qg3LkeuinTrZoJHHF94coSaTfIPyBYoywp+ys4qu20oSJFbKMYoIJo0FWJT9q6Vp49l6z9IsJRbHdcGtiKbGoQ==", + "node_modules/typescript-eslint": { + "version": "8.46.4", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.46.4.tgz", + "integrity": "sha512-KALyxkpYV5Ix7UhvjTwJXZv76VWsHG+NjNlt/z+a17SOQSiOcBdUXdbJdyXi7RPxrBFECtFOiPwUJQusJuCqrg==", "dev": true, + "license": "MIT", "dependencies": { - "esbuild": "^0.25.0", - "postcss": "^8.5.3", - "rollup": "^4.30.1" - }, - "bin": { - "vite": "bin/vite.js" + "@typescript-eslint/eslint-plugin": "8.46.4", + "@typescript-eslint/parser": "8.46.4", + "@typescript-eslint/typescript-estree": "8.46.4", + "@typescript-eslint/utils": "8.46.4" }, "engines": { - "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", - "jiti": ">=1.21.0", - "less": "*", - "lightningcss": "^1.21.0", - "sass": "*", - "sass-embedded": "*", - "stylus": "*", - "sugarss": "*", - "terser": "^5.16.0", - "tsx": "^4.8.1", - "yaml": "^2.4.2" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "jiti": { - "optional": true - }, - "less": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "sass": { - "optional": true - }, - "sass-embedded": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - }, - "tsx": { - "optional": true - }, - "yaml": { - "optional": true - } + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" } }, - "node_modules/vite/node_modules/postcss": { - "version": "8.5.6", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", - "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "node_modules/typescript-eslint/node_modules/@typescript-eslint/project-service": { + "version": "8.46.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.46.4.tgz", + "integrity": "sha512-nPiRSKuvtTN+no/2N1kt2tUh/HoFzeEgOm9fQ6XQk4/ApGqjx0zFIIaLJ6wooR1HIoozvj2j6vTi/1fgAz7UYQ==", "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" + "@typescript-eslint/tsconfig-utils": "^8.46.4", + "@typescript-eslint/types": "^8.46.4", + "debug": "^4.3.4" }, "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "node_modules/void-elements": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", - "integrity": "sha512-qZKX4RnBzH2ugr8Lxa7x+0V6XD9Sb/ouARtiasEQCHB1EVU4NXtmHsDDrx1dO4ne5fc3J6EW05BP1Dl0z0iung==", - "dev": true, - "engines": { - "node": ">=0.10.0" + "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/watchpack": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz", - "integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==", + "node_modules/typescript-eslint/node_modules/@typescript-eslint/scope-manager": { + "version": "8.46.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.46.4.tgz", + "integrity": "sha512-tMDbLGXb1wC+McN1M6QeDx7P7c0UWO5z9CXqp7J8E+xGcJuUuevWKxuG8j41FoweS3+L41SkyKKkia16jpX7CA==", "dev": true, + "license": "MIT", "dependencies": { - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.1.2" + "@typescript-eslint/types": "8.46.4", + "@typescript-eslint/visitor-keys": "8.46.4" }, "engines": { - "node": ">=10.13.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/wbuf": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", - "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", + "node_modules/typescript-eslint/node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.46.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.46.4.tgz", + "integrity": "sha512-+/XqaZPIAk6Cjg7NWgSGe27X4zMGqrFqZ8atJsX3CWxH/jACqWnrWI68h7nHQld0y+k9eTTjb9r+KU4twLoo9A==", "dev": true, - "dependencies": { - "minimalistic-assert": "^1.0.0" + "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/wcwidth": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", - "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "node_modules/typescript-eslint/node_modules/@typescript-eslint/types": { + "version": "8.46.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.46.4.tgz", + "integrity": "sha512-USjyxm3gQEePdUwJBFjjGNG18xY9A2grDVGuk7/9AkjIF1L+ZrVnwR5VAU5JXtUnBL/Nwt3H31KlRDaksnM7/w==", "dev": true, - "dependencies": { - "defaults": "^1.0.3" + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/weak-lru-cache": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/weak-lru-cache/-/weak-lru-cache-1.2.2.tgz", - "integrity": "sha512-DEAoo25RfSYMuTGc9vPJzZcZullwIqRDSI9LOy+fkCJPi6hykCnfKaXTuPBDuXAUcqHXyOgFtHNp/kB2FjYHbw==", - "dev": true, - "optional": true - }, - "node_modules/webpack": { - "version": "5.98.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.98.0.tgz", - "integrity": "sha512-UFynvx+gM44Gv9qFgj0acCQK2VE1CtdfwFdimkapco3hlPCJ/zeq73n2yVKimVbtm+TnApIugGhLJnkU6gjYXA==", + "node_modules/typescript-eslint/node_modules/@typescript-eslint/typescript-estree": { + "version": "8.46.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.46.4.tgz", + "integrity": "sha512-7oV2qEOr1d4NWNmpXLR35LvCfOkTNymY9oyW+lUHkmCno7aOmIf/hMaydnJBUTBMRCOGZh8YjkFOc8dadEoNGA==", "dev": true, + "license": "MIT", "dependencies": { - "@types/eslint-scope": "^3.7.7", - "@types/estree": "^1.0.6", - "@webassemblyjs/ast": "^1.14.1", - "@webassemblyjs/wasm-edit": "^1.14.1", - "@webassemblyjs/wasm-parser": "^1.14.1", - "acorn": "^8.14.0", - "browserslist": "^4.24.0", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.17.1", - "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.0", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.3.11", - "watchpack": "^2.4.1", - "webpack-sources": "^3.2.3" - }, - "bin": { - "webpack": "bin/webpack.js" + "@typescript-eslint/project-service": "8.46.4", + "@typescript-eslint/tsconfig-utils": "8.46.4", + "@typescript-eslint/types": "8.46.4", + "@typescript-eslint/visitor-keys": "8.46.4", + "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": ">=10.13.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/webpack" + "url": "https://opencollective.com/typescript-eslint" }, - "peerDependenciesMeta": { - "webpack-cli": { - "optional": true - } + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" } }, - "node_modules/webpack-dev-middleware": { - "version": "7.4.2", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-7.4.2.tgz", - "integrity": "sha512-xOO8n6eggxnwYpy1NlzUKpvrjfJTvae5/D6WOK0S2LSo7vjmo5gCM1DbLUmFqrMTJP+W/0YZNctm7jasWvLuBA==", + "node_modules/typescript-eslint/node_modules/@typescript-eslint/utils": { + "version": "8.46.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.46.4.tgz", + "integrity": "sha512-AbSv11fklGXV6T28dp2Me04Uw90R2iJ30g2bgLz529Koehrmkbs1r7paFqr1vPCZi7hHwYxYtxfyQMRC8QaVSg==", "dev": true, + "license": "MIT", "dependencies": { - "colorette": "^2.0.10", - "memfs": "^4.6.0", - "mime-types": "^2.1.31", - "on-finished": "^2.4.1", - "range-parser": "^1.2.1", - "schema-utils": "^4.0.0" + "@eslint-community/eslint-utils": "^4.7.0", + "@typescript-eslint/scope-manager": "8.46.4", + "@typescript-eslint/types": "8.46.4", + "@typescript-eslint/typescript-estree": "8.46.4" }, "engines": { - "node": ">= 18.12.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/webpack" + "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "webpack": "^5.0.0" - }, - "peerDependenciesMeta": { - "webpack": { - "optional": true - } + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" } }, - "node_modules/webpack-dev-server": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-5.2.2.tgz", - "integrity": "sha512-QcQ72gh8a+7JO63TAx/6XZf/CWhgMzu5m0QirvPfGvptOusAxG12w2+aua1Jkjr7hzaWDnJ2n6JFeexMHI+Zjg==", - "dev": true, - "dependencies": { - "@types/bonjour": "^3.5.13", - "@types/connect-history-api-fallback": "^1.5.4", - "@types/express": "^4.17.21", - "@types/express-serve-static-core": "^4.17.21", - "@types/serve-index": "^1.9.4", - "@types/serve-static": "^1.15.5", - "@types/sockjs": "^0.3.36", - "@types/ws": "^8.5.10", - "ansi-html-community": "^0.0.8", - "bonjour-service": "^1.2.1", - "chokidar": "^3.6.0", - "colorette": "^2.0.10", - "compression": "^1.7.4", - "connect-history-api-fallback": "^2.0.0", - "express": "^4.21.2", - "graceful-fs": "^4.2.6", - "http-proxy-middleware": "^2.0.9", - "ipaddr.js": "^2.1.0", - "launch-editor": "^2.6.1", - "open": "^10.0.3", - "p-retry": "^6.2.0", - "schema-utils": "^4.2.0", - "selfsigned": "^2.4.1", - "serve-index": "^1.9.1", - "sockjs": "^0.3.24", - "spdy": "^4.0.2", - "webpack-dev-middleware": "^7.4.2", - "ws": "^8.18.0" - }, - "bin": { - "webpack-dev-server": "bin/webpack-dev-server.js" + "node_modules/typescript-eslint/node_modules/@typescript-eslint/visitor-keys": { + "version": "8.46.4", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.46.4.tgz", + "integrity": "sha512-/++5CYLQqsO9HFGLI7APrxBJYo+5OCMpViuhV8q5/Qa3o5mMrF//eQHks+PXcsAVaLdn817fMuS7zqoXNNZGaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.46.4", + "eslint-visitor-keys": "^4.2.1" }, "engines": { - "node": ">= 18.12.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/webpack" + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/typescript-eslint/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/typescript-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" }, - "peerDependencies": { - "webpack": "^5.0.0" + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/typescript-eslint/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" }, - "peerDependenciesMeta": { - "webpack": { - "optional": true + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/ua-parser-js": { + "version": "0.7.40", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.40.tgz", + "integrity": "sha512-us1E3K+3jJppDBa3Tl0L3MOJiGhe1C6P0+nIvQAFYbxlMAx0h81eOwLmU57xgqToduDDPx3y5QsdjPfDu+FgOQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/ua-parser-js" }, - "webpack-cli": { - "optional": true + { + "type": "paypal", + "url": "https://paypal.me/faisalman" + }, + { + "type": "github", + "url": "https://github.com/sponsors/faisalman" } + ], + "bin": { + "ua-parser-js": "script/cli.js" + }, + "engines": { + "node": "*" } }, - "node_modules/webpack-dev-server/node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "node_modules/undici": { + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.20.0.tgz", + "integrity": "sha512-MJZrkjyd7DeC+uPZh+5/YaMDxFiiEEaDgbUSVMXayofAkDWF1088CDo+2RPg7B1BuS1qf1vgNE7xqwPxE0DuSQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20.18.1" + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, + "node_modules/unique-filename": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-5.0.0.tgz", + "integrity": "sha512-2RaJTAvAb4owyjllTfXzFClJ7WsGxlykkPvCr9pA//LD9goVq+m4PPAeBgNodGZ7nSrntT/auWpJ6Y5IFXcfjg==", "dev": true, + "license": "ISC", "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" + "unique-slug": "^6.0.0" }, "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/unique-slug": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-6.0.0.tgz", + "integrity": "sha512-4Lup7Ezn8W3d52/xBhZBVdx323ckxa7DEvd9kPQHppTkLoJXw6ltrBCyj5pnrxj0qKDxYMJ56CoxNuFCscdTiw==", + "dev": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4" }, - "optionalDependencies": { - "fsevents": "~2.3.2" + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/webpack-dev-server/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==", + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, "engines": { - "node": ">= 6" + "node": ">= 0.8" } }, - "node_modules/webpack-dev-server/node_modules/http-proxy-middleware": { - "version": "2.0.9", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.9.tgz", - "integrity": "sha512-c1IyJYLYppU574+YI7R4QyX2ystMtVXZwIdzazUIPIJsHuWNd+mho2j+bKoHftndicGj9yh+xjd+l0yj7VeT1Q==", + "node_modules/update-browserslist-db": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", "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": { - "@types/http-proxy": "^1.17.8", - "http-proxy": "^1.18.1", - "is-glob": "^4.0.1", - "is-plain-obj": "^3.0.0", - "micromatch": "^4.0.2" + "escalade": "^3.2.0", + "picocolors": "^1.1.1" }, - "engines": { - "node": ">=12.0.0" + "bin": { + "update-browserslist-db": "cli.js" }, "peerDependencies": { - "@types/express": "^4.17.13" - }, - "peerDependenciesMeta": { - "@types/express": { - "optional": true - } + "browserslist": ">= 4.21.0" } }, - "node_modules/webpack-dev-server/node_modules/ipaddr.js": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz", - "integrity": "sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==", + "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, - "engines": { - "node": ">= 10" + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" } }, - "node_modules/webpack-dev-server/node_modules/picomatch": { + "node_modules/uri-js/node_modules/punycode": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true, + "license": "MIT", "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" + "node": ">=6" } }, - "node_modules/webpack-dev-server/node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", "dev": true, - "dependencies": { - "picomatch": "^2.2.1" - }, "engines": { - "node": ">=8.10.0" + "node": ">= 0.4.0" } }, - "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==", + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "clone-deep": "^4.0.1", - "flat": "^5.0.2", - "wildcard": "^2.0.1" - }, - "engines": { - "node": ">=18.0.0" + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.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==", + "node_modules/validate-npm-package-name": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-7.0.2.tgz", + "integrity": "sha512-hVDIBwsRruT73PbK7uP5ebUt+ezEtCmzZz3F59BSr2F6OVFnJ/6h8liuvdLrQ88Xmnk6/+xGGuq+pG9WwTuy3A==", "dev": true, + "license": "ISC", "engines": { - "node": ">=10.13.0" + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/webpack-subresource-integrity": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/webpack-subresource-integrity/-/webpack-subresource-integrity-5.1.0.tgz", - "integrity": "sha512-sacXoX+xd8r4WKsy9MvH/q/vBtEHr86cpImXwyg74pFIpERKt6FmB8cXpeuh0ZLgclOlHI4Wcll7+R5L02xk9Q==", + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", "dev": true, - "dependencies": { - "typed-assert": "^1.0.8" - }, "engines": { - "node": ">= 12" - }, - "peerDependencies": { - "html-webpack-plugin": ">= 5.0.0-beta.1 < 6", - "webpack": "^5.12.0" - }, - "peerDependenciesMeta": { - "html-webpack-plugin": { - "optional": true - } + "node": ">= 0.8" } }, - "node_modules/webpack/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 + "node_modules/void-elements": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", + "integrity": "sha512-qZKX4RnBzH2ugr8Lxa7x+0V6XD9Sb/ouARtiasEQCHB1EVU4NXtmHsDDrx1dO4ne5fc3J6EW05BP1Dl0z0iung==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "node_modules/websocket-driver": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", - "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "node_modules/watchpack": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.5.0.tgz", + "integrity": "sha512-e6vZvY6xboSwLz2GD36c16+O/2Z6fKvIf4pOXptw2rY9MVwE/TXc6RGqxD3I3x0a28lwBY7DE+76uTPSsBrrCA==", "dev": true, + "license": "MIT", "dependencies": { - "http-parser-js": ">=0.5.1", - "safe-buffer": ">=5.1.0", - "websocket-extensions": ">=0.1.1" + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" }, "engines": { - "node": ">=0.8.0" + "node": ">=10.13.0" } }, - "node_modules/websocket-extensions": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", - "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "node_modules/weak-lru-cache": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/weak-lru-cache/-/weak-lru-cache-1.2.2.tgz", + "integrity": "sha512-DEAoo25RfSYMuTGc9vPJzZcZullwIqRDSI9LOy+fkCJPi6hykCnfKaXTuPBDuXAUcqHXyOgFtHNp/kB2FjYHbw==", "dev": true, - "engines": { - "node": ">=0.8.0" - } + "license": "MIT", + "optional": true }, "node_modules/which": { "version": "1.3.1", @@ -13819,17 +12417,22 @@ "which": "bin/which" } }, - "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 + "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/wrap-ansi": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -13839,79 +12442,12 @@ "node": ">=8" } }, - "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, - "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-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi-cjs/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 - }, - "node_modules/wrap-ansi-cjs/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, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi-cjs/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, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi-cjs/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, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/wrap-ansi/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" } @@ -13920,13 +12456,15 @@ "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 + "dev": true, + "license": "MIT" }, "node_modules/wrap-ansi/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" } @@ -13936,6 +12474,7 @@ "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", @@ -13950,6 +12489,7 @@ "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" }, @@ -13983,14 +12523,6 @@ } } }, - "node_modules/xhr2": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/xhr2/-/xhr2-0.2.1.tgz", - "integrity": "sha512-sID0rrVCqkVNUn8t6xuv9+6FViXjUVXq8H5rWOH2rz9fDNQEd4g0EA2XlcEdJXRz5BMEn4O1pJFdT+z4YHhoWw==", - "engines": { - "node": ">= 6" - } - }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", @@ -14006,100 +12538,82 @@ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true }, + "node_modules/yaml": { + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.2.tgz", + "integrity": "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==", + "dev": true, + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + }, + "funding": { + "url": "https://github.com/sponsors/eemeli" + } + }, "node_modules/yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-18.0.0.tgz", + "integrity": "sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg==", "dev": true, + "license": "MIT", "dependencies": { - "cliui": "^8.0.1", + "cliui": "^9.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", + "string-width": "^7.2.0", "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" + "yargs-parser": "^22.0.0" }, "engines": { - "node": ">=12" + "node": "^20.19.0 || ^22.12.0 || >=23" } }, "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, - "engines": { - "node": ">=12" - } - }, - "node_modules/yargs/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, - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/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 - }, - "node_modules/yargs/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==", + "version": "22.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-22.0.0.tgz", + "integrity": "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==", "dev": true, + "license": "ISC", "engines": { - "node": ">=8" + "node": "^20.19.0 || ^22.12.0 || >=23" } }, - "node_modules/yargs/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==", + "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, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, + "license": "MIT", "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/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, - "dependencies": { - "ansi-regex": "^5.0.1" + "node": ">=10" }, - "engines": { - "node": ">=8" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "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==", + "node_modules/yoctocolors": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yoctocolors/-/yoctocolors-2.1.2.tgz", + "integrity": "sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==", "dev": true, + "license": "MIT", "engines": { - "node": ">=12.20" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/yoctocolors-cjs": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yoctocolors-cjs/-/yoctocolors-cjs-2.1.2.tgz", - "integrity": "sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/yoctocolors-cjs/-/yoctocolors-cjs-2.1.3.tgz", + "integrity": "sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw==", "dev": true, + "license": "MIT", "engines": { "node": ">=18" }, @@ -14107,6 +12621,26 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/zod": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.3.5.tgz", + "integrity": "sha512-k7Nwx6vuWx1IJ9Bjuf4Zt1PEllcwe7cls3VNzm4CQ1/hgtFUK2bRNG3rvnpPUhFjmqJKAKtjV576KnUkHocg/g==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/zod-to-json-schema": { + "version": "3.25.1", + "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.25.1.tgz", + "integrity": "sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA==", + "dev": true, + "license": "ISC", + "peerDependencies": { + "zod": "^3.25 || ^4" + } + }, "node_modules/zone.js": { "version": "0.15.1", "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.15.1.tgz", diff --git a/package.json b/package.json index c9ef7f4..bc8d348 100644 --- a/package.json +++ b/package.json @@ -7,24 +7,24 @@ "build": "ng build", "watch": "ng build --watch --configuration development", "test": "ng test", - "deploy": "ng build --base-ref /glyphspace/" + "deploy": "ng build --base-ref /glyphspace/", + "lint": "ng lint", + "format": "prettier --write \"src/**/*.{ts,html,scss,json}\"", + "format:check": "prettier --check \"src/**/*.{ts,html,scss,json}\"", + "prepare": "husky" }, "private": true, "dependencies": { - "@angular/common": "^19.2.0", - "@angular/compiler": "^19.2.0", - "@angular/core": "^19.2.0", - "@angular/forms": "^19.2.0", - "@angular/platform-browser": "^19.2.0", - "@angular/platform-browser-dynamic": "^19.2.0", - "@angular/platform-server": "^19.2.0", - "@angular/router": "^19.2.0", + "@angular/common": "^21.1.4", + "@angular/compiler": "^21.1.4", + "@angular/core": "^21.1.4", + "@angular/forms": "^21.1.4", + "@angular/platform-browser": "^21.1.4", + "@angular/platform-browser-dynamic": "^21.1.4", "@saehrimnir/druidjs": "^0.7.3", "d3": "^7.9.0", "d3-force": "^3.0.0", - "express": "^4.18.2", "material-icons": "^1.13.14", - "parquet-wasm": "^0.7.1", "pyodide": "^0.28.0", "rxjs": "~7.8.0", "three": "^0.176.0", @@ -32,23 +32,40 @@ "zone.js": "~0.15.0" }, "devDependencies": { - "@angular-devkit/build-angular": "^19.2.13", - "@angular/cli": "^19.2.13", - "@angular/compiler-cli": "^19.2.0", + "@angular/build": "^21.1.4", + "@angular/cli": "^21.1.4", + "@angular/compiler-cli": "^21.1.4", "@types/d3": "^7.4.3", "@types/d3-force": "^3.0.10", "@types/d3-quadtree": "^3.0.6", - "@types/express": "^4.17.17", "@types/jasmine": "~5.1.0", "@types/node": "^18.18.0", "@types/three": "^0.176.0", - "@types/uuid": "^10.0.0", + "angular-eslint": "21.0.1", + "eslint": "^9.39.1", + "eslint-config-prettier": "^10.1.8", + "husky": "^9.1.7", "jasmine-core": "~5.6.0", "karma": "~6.4.0", "karma-chrome-launcher": "~3.2.0", "karma-coverage": "~2.2.0", "karma-jasmine": "~5.1.0", "karma-jasmine-html-reporter": "~2.1.0", - "typescript": "~5.7.2" + "lint-staged": "^16.2.7", + "prettier": "^3.8.1", + "typescript": "~5.9.3", + "typescript-eslint": "8.46.4" + }, + "lint-staged": { + "src/**/*.{ts,html}": [ + "eslint --fix", + "prettier --write" + ], + "src/**/*.scss": [ + "prettier --write" + ], + "src/**/*.json": [ + "prettier --write" + ] } -} +} \ No newline at end of file diff --git a/src/app/app.component.html b/src/app/app.component.html index 259fe68..96100db 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -1,23 +1,19 @@ - - + -
- - +
+
+ @for (cell of grid; track cell.id) { + + } +
+ +
- \ No newline at end of file + diff --git a/src/app/app.component.scss b/src/app/app.component.scss index 1612f26..14cf784 100644 --- a/src/app/app.component.scss +++ b/src/app/app.component.scss @@ -1,3 +1,5 @@ +@use '../styles/variables' as v; + :host { display: flex; flex-direction: column; @@ -5,30 +7,34 @@ height: 100vh; width: 100vw; overflow: hidden; - background-color: #f9f9f9; + background-color: v.$app-bg; +} + +.content-area { + flex: 1; + min-height: 0; + display: flex; + overflow: hidden; } .grid { - flex: 1; /* ← fills remaining space */ - min-height: 0; /* ← VERY important */ + flex: 1; + min-height: 0; + min-width: 0; display: grid; - width: 100%; - height: 100%; + overflow: hidden; - box-sizing: border-box; /* ← important */ + box-sizing: border-box; gap: 24px; padding: 24px; } .grid > * { - width: 100%; - height: 100%; - + min-width: 0; min-height: 0; /* Make children fill their grid cell */ box-sizing: border-box; } - diff --git a/src/app/app.component.spec.ts b/src/app/app.component.spec.ts deleted file mode 100644 index 60da88b..0000000 --- a/src/app/app.component.spec.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { TestBed } from '@angular/core/testing'; -import { AppComponent } from './app.component'; - -describe('AppComponent', () => { - beforeEach(async () => { - await TestBed.configureTestingModule({ - imports: [AppComponent], - }).compileComponents(); - }); - - it('should create the app', () => { - const fixture = TestBed.createComponent(AppComponent); - const app = fixture.componentInstance; - expect(app).toBeTruthy(); - }); - - it(`should have the 'glyph-canvas' title`, () => { - const fixture = TestBed.createComponent(AppComponent); - const app = fixture.componentInstance; - expect(app.title).toEqual('glyph-canvas'); - }); - - it('should render title', () => { - const fixture = TestBed.createComponent(AppComponent); - fixture.detectChanges(); - const compiled = fixture.nativeElement as HTMLElement; - expect(compiled.querySelector('h1')?.textContent).toContain('Hello, glyph-canvas'); - }); -}); diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 2b9e99b..0103210 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,24 +1,27 @@ -import { Component, ElementRef, HostListener, NgZone, OnChanges, ViewChild, ViewContainerRef } from '@angular/core'; +import { Component, HostListener, OnInit } from '@angular/core'; import { ConfigService } from './services/config.service'; import { GlyphCanvasComponent } from './canvas/glyph-canvas.component'; -import { CommonModule } from '@angular/common'; -import { DataProviderService } from './services/dataprovider.service'; +import { DataLoaderService } from './services/data-loader.service'; import { checkTextInput } from './shared/helpers/angular-helper'; -import { MenuBarComponent } from "./menubar/menubar.component"; +import { MenuBarComponent } from './menubar/menubar.component'; import { ToastComponent } from './shared/components/toast/toast.component'; +import { SidebarComponent } from './sidebar/sidebar.component'; -interface GlyphCanvasItem { id: number, row: number, col: number } +interface GlyphCanvasItem { + id: number; + row: number; + col: number; +} @Component({ standalone: true, selector: 'app-root', - imports: [CommonModule, GlyphCanvasComponent, MenuBarComponent, ToastComponent], + imports: [GlyphCanvasComponent, MenuBarComponent, ToastComponent, SidebarComponent], templateUrl: './app.component.html', - styleUrl: './app.component.scss' + styleUrl: './app.component.scss', }) -export class AppComponent implements OnChanges { +export class AppComponent implements OnInit { title = 'Glyphboard Royale'; - @ViewChild('canvasGrid', { static: true }) canvasContainer!: ElementRef; grid: GlyphCanvasItem[] = []; totalCells = 1; @@ -26,7 +29,10 @@ export class AppComponent implements OnChanges { cols = 1; readonly minCellSize = 150; // px — change as needed - constructor(private config: ConfigService, private dataProvider: DataProviderService) { } + constructor( + private config: ConfigService, + private dataLoader: DataLoaderService + ) {} ngOnInit() { this.recalculateGrid(); @@ -36,17 +42,15 @@ export class AppComponent implements OnChanges { if (this.totalCells > 1) { this.totalCells--; - console.log("Received remove canvas command: ", change); const canvas = this.grid.find(c => c.id === change); - this.grid.splice(this.grid.indexOf(canvas!), 1); - this.recalculateGrid(); + if (canvas) { + this.grid.splice(this.grid.indexOf(canvas), 1); + this.recalculateGrid(); + } } }); } - ngOnChanges(): void { - } - getNextFreeId(grid: GlyphCanvasItem[]): number { const usedIds = new Set(grid.map(item => item.id)); @@ -66,7 +70,7 @@ export class AppComponent implements OnChanges { this.grid.push({ id: idCounter++, row: r, - col: c + col: c, }); } } @@ -90,12 +94,12 @@ export class AppComponent implements OnChanges { const index = this.grid.length; const r = Math.floor(index / this.cols) + 1; - const c = index % this.cols + 1; + const c = (index % this.cols) + 1; this.grid.push({ id: newId, row: r, - col: c + col: c, }); this.recalculateGrid(); @@ -110,10 +114,6 @@ export class AppComponent implements OnChanges { } } - @HostListener('window:resize') - onResize() { - } - @HostListener('document:keyup', ['$event']) handleKeyboardEvent(event: KeyboardEvent) { if (checkTextInput(event)) return; diff --git a/src/app/app.config.ts b/src/app/app.config.ts index ed2c77a..1c0c942 100644 --- a/src/app/app.config.ts +++ b/src/app/app.config.ts @@ -2,7 +2,5 @@ import { provideHttpClient } from '@angular/common/http'; import { ApplicationConfig } from '@angular/core'; export const appConfig: ApplicationConfig = { - providers: [ - provideHttpClient() - ] + providers: [provideHttpClient()], }; diff --git a/src/app/canvas/glyph-canvas.component.html b/src/app/canvas/glyph-canvas.component.html index 204d767..74c82c5 100644 --- a/src/app/canvas/glyph-canvas.component.html +++ b/src/app/canvas/glyph-canvas.component.html @@ -1,57 +1,48 @@ -
+
+
- - + + (toggleLens)="toggleMagicLens()" + >
\ No newline at end of file + class="selection-rectangle" + [style.left.px]="selectionSvc.selectionBox.left" + [style.top.px]="selectionSvc.selectionBox.top" + [style.width.px]="selectionSvc.selectionBox.width" + [style.height.px]="selectionSvc.selectionBox.height" + [hidden]="!selectionSvc.isSelecting" +>
diff --git a/src/app/canvas/glyph-canvas.component.scss b/src/app/canvas/glyph-canvas.component.scss index 719d857..a2d1607 100644 --- a/src/app/canvas/glyph-canvas.component.scss +++ b/src/app/canvas/glyph-canvas.component.scss @@ -1,31 +1,29 @@ @use '../../styles/variables' as v; .scene-container { - position: relative; // Needed for overlay to anchor properly + position: relative; width: 100%; height: 100%; overflow: hidden; + display: flex; + flex-direction: column; border-radius: 12px; border: 1px solid v.$gray-200; - background: white; + background: v.$white; - overflow: hidden; /* important for canvas clipping */ - - box-shadow: - 0 1px 3px rgba(0,0,0,0.08), - 0 4px 12px rgba(0,0,0,0.05); + box-shadow: v.$shadow-sm; &.active { - border: 1px solid #b3d2ff; /* subtle blue border on first click */ + border: 1px solid v.$ui-active-border; } .canvas-container { position: relative; width: 100%; - height: 100%; + flex: 1; + min-height: 0; display: block; - /* position: relative; */ cursor: default; &.selecting { @@ -51,4 +49,4 @@ background-color: v.$color-gray-bg-light; pointer-events: none; z-index: 1000; -} \ No newline at end of file +} diff --git a/src/app/canvas/glyph-canvas.component.spec.ts b/src/app/canvas/glyph-canvas.component.spec.ts deleted file mode 100644 index 445b5c1..0000000 --- a/src/app/canvas/glyph-canvas.component.spec.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { GlyphCanvasComponent } from './glyph-canvas.component'; - -describe('CanvasComponent', () => { - let component: GlyphCanvasComponent; - let fixture: ComponentFixture; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - imports: [GlyphCanvasComponent] - }) - .compileComponents(); - - fixture = TestBed.createComponent(GlyphCanvasComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/src/app/canvas/glyph-canvas.component.ts b/src/app/canvas/glyph-canvas.component.ts index 59d493b..62638e8 100644 --- a/src/app/canvas/glyph-canvas.component.ts +++ b/src/app/canvas/glyph-canvas.component.ts @@ -1,38 +1,63 @@ -import { Component, ElementRef, HostListener, OnInit, ViewChild, AfterViewInit, OnDestroy, Input, NgZone, ChangeDetectorRef } from '@angular/core'; +import { + Component, + ElementRef, + HostListener, + ViewChild, + AfterViewInit, + OnDestroy, + Input, + NgZone, + ChangeDetectorRef, + OnChanges, +} from '@angular/core'; import { FormsModule } from '@angular/forms'; import * as THREE from 'three'; import { ConfigService } from '../services/config.service'; import { Subscription } from 'rxjs'; -import { DataProviderService } from '../services/dataprovider.service'; +import { DataLoaderService } from '../services/data-loader.service'; +import { FilterService } from '../services/filter.service'; import { GlyphObject } from '../glyph/glyph-object'; import { ZoomLevel } from '../shared/enum/zoom-level'; import { forceCollide, forceSimulation, Simulation } from 'd3-force'; import { clusterGlyphs, getGlyphFromObject } from '../shared/helpers/glyph-helper'; import { InteractionCommand } from '../shared/enum/interaction-command'; import { GlyphCacheObject } from '../glyph/glyph-cache-object'; -import { convertToScreenSpace, exportThreeSceneAsPNG, hitTest, hitTestCandidates, jitterFromVector, nearlyEqual, panCamera, scalePosition, screenToWorld } from '../shared/helpers/three-helper'; -import { TooltipComponent } from "./tooltip/tooltip.component"; -import { MagiclensComponent } from "./magiclens/magiclens.component"; -import { CommonModule } from '@angular/common'; -import { GlyphSizeInfo } from '../glyph/glyph-size-info'; -import { ItemFilter } from '../shared/filter/item-filter'; +import { exportThreeSceneAsPNG, scalePosition } from '../shared/helpers/three-helper'; +import { TooltipComponent } from './tooltip/tooltip.component'; +import { MagiclensComponent } from './magiclens/magiclens.component'; import { IdFilter } from '../shared/filter/id-filter'; -import { FilterMode } from '../shared/enum/filter-mode'; import { checkTextInput } from '../shared/helpers/angular-helper'; import { LoggerService } from '../services/logger-service'; import { RenderTask } from '../shared/enum/render-task'; import { CanvasNavigationControlsComponent } from './navigationcontrols/navigationcontrols.component'; -import { SettingsControlPanelComponent } from "./settingscontrols/settingscontrols.component"; -import { SpatialGrid } from '../shared/helpers/spatial-grid'; +import { SettingsControlPanelComponent } from './settingscontrols/settingscontrols.component'; +import { CanvasCameraService } from './services/canvas-camera.service'; +import { CanvasRendererService } from './services/canvas-renderer.service'; +import { CanvasSelectionService } from './services/canvas-selection.service'; +import { + HIT_TEST_THROTTLE_MS, + MOUSE_IDLE_MS, + CLICK_TIME_THRESHOLD_MS, + CLICK_DISTANCE_THRESHOLD, +} from '../shared/constants/canvas-constants'; +import { DataProcessorService } from '../services/data-processor'; +import { buildGlyphRenderConfig, GlyphRenderConfig } from '../glyph/glyph-render-config'; @Component({ selector: 'glyph-canvas', standalone: true, - imports: [CommonModule, FormsModule, TooltipComponent, MagiclensComponent, CanvasNavigationControlsComponent, SettingsControlPanelComponent], + imports: [ + FormsModule, + TooltipComponent, + MagiclensComponent, + CanvasNavigationControlsComponent, + SettingsControlPanelComponent, + ], + providers: [CanvasCameraService, CanvasRendererService, CanvasSelectionService], templateUrl: './glyph-canvas.component.html', - styleUrls: ['./glyph-canvas.component.scss'] + styleUrls: ['./glyph-canvas.component.scss'], }) -export class GlyphCanvasComponent implements OnInit, AfterViewInit, OnDestroy { +export class GlyphCanvasComponent implements AfterViewInit, OnDestroy, OnChanges { @ViewChild('canvasContainer', { static: true }) canvasContainer!: ElementRef; @ViewChild('sceneContainer') sceneContainer!: ElementRef; @ViewChild('settingsPanel') settingsPanel!: SettingsControlPanelComponent; @@ -40,37 +65,15 @@ export class GlyphCanvasComponent implements OnInit, AfterViewInit, OnDestroy { @ViewChild(MagiclensComponent) magicLensComponent!: MagiclensComponent; @Input() id = 0; - @Input() totalCells: number = 0; + @Input() totalCells = 0; private glyphData: GlyphObject[] = []; - // Infrastructure fields + // Infrastructure private configSub = new Subscription(); private canvasWidth = 0; private canvasHeight = 0; - private sizeInfo = new GlyphSizeInfo(); - private positionBounds: { minX: number; maxX: number; minY: number; maxY: number; } | undefined; - - // Basic THREE.js properties - public scene!: THREE.Scene; - private renderer!: THREE.WebGLRenderer; - private camera!: THREE.OrthographicCamera; - private target: THREE.Vector3 = new THREE.Vector3(0, 0, 0); - glyphGroup = new THREE.Group(); private animationFrameId: number | undefined; - private needsRender = new Set(); private resizeObserver!: ResizeObserver; - private standardBackgroundColor = new THREE.Color(0xffffff); - private disabledBackgroundColor = new THREE.Color(0xf0f0f0); - private viewRect = { left: 0, right: 0, top: 0, bottom: 0 }; - private lastViewRect = { left: 0, right: 0, top: 0, bottom: 0 }; - private clippingFrameCounter = 0; - private spatialGrid = new SpatialGrid(100); // Cell size optimized for typical glyph density - private spatialGridDirty = true; - - // Safety mechanism to prevent infinite render loops - private renderGlyphsCallCount = 0; - private renderGlyphsResetTimer: any = null; - private readonly MAX_RENDER_CALLS_PER_SECOND = 20; // D3 force simulation and aggregation private simulation: Simulation | undefined; @@ -78,48 +81,18 @@ export class GlyphCanvasComponent implements OnInit, AfterViewInit, OnDestroy { private currentTicks = 0; private maxTicks = 50; aggregated = false; - private lensSimulation?: Simulation | undefined; - - // Fields responsible for animating transitions in the scene - private fitAnimationStartTime: number | null = null; - private fitStartPosition!: THREE.Vector3; - private fitEndPosition!: THREE.Vector3; - private fitStartTarget!: THREE.Vector3; - private fitEndTarget!: THREE.Vector3; - private fitStartZoom!: number; - private fitEndZoom!: number; - private fitDuration = 500; // ms private animationSpeed = 0.1; - // Helpers for navigation - private isPanning = false; - mouseInside = false; - private mouseIdleTimer: any; - private readonly MOUSE_IDLE_MS = 2000; - lastMousePosition = new THREE.Vector2(); - lastTouchPosition: { x: number, y: number } | null = { x: 0, y: 0 }; - private mouseDownTime: number = 0; - private readonly clickThreshold = 4; // pixels - private readonly clickTimeThreshold = 300; // milliseconds - private zoomFactor = 1.1; - private touchZoomStartDistance: number | null = null; - private lastZoom: number | null = null; - - // Used for selecting and highlighting logic + // Hover and interaction private mouse = new THREE.Vector2(); private currentHoveredObject: GlyphObject | null = null; private animateGlyph: GlyphObject | null = null; private pulseStartTime = performance.now(); private lastHitTestTime = 0; - private throttleDelay = 50; - - private selectionStart = new THREE.Vector2(); - private selectionEnd = new THREE.Vector2(); - private selectionFilter: ItemFilter = new IdFilter(); - selectionMode = false; - private isShiftDown = false; - isSelecting = false; - selectionBox = { left: 0, top: 0, width: 0, height: 0 }; + lastMousePosition = new THREE.Vector2(); + mouseInside = false; + private mouseIdleTimer: ReturnType | undefined; + private mouseDownTime = 0; // Overlay controls canvasActivated = false; @@ -127,17 +100,28 @@ export class GlyphCanvasComponent implements OnInit, AfterViewInit, OnDestroy { timestamps: string[] = []; algorithms: string[] = []; contexts: string[] = []; - selectedTimestamp = ""; - selectedAlgorithm = ""; - selectedContext = ""; - - constructor(private ngZone: NgZone, private cdr: ChangeDetectorRef, private logger: LoggerService, private config: ConfigService, private dataProvider: DataProviderService) { + selectedTimestamp = ''; + selectedAlgorithm = ''; + selectedContext = ''; + + constructor( + private ngZone: NgZone, + private cdr: ChangeDetectorRef, + private logger: LoggerService, + private config: ConfigService, + private dataLoader: DataLoaderService, + private dataProcessor: DataProcessorService, + private filterService: FilterService, + public cameraSvc: CanvasCameraService, + public rendererSvc: CanvasRendererService, + public selectionSvc: CanvasSelectionService + ) {} + + private buildRenderConfig(): GlyphRenderConfig { + return buildGlyphRenderConfig(this.config, this.dataProcessor); } //#region Life Cycle methods - ngOnInit(): void { - } - ngAfterViewInit(): void { this.initThree(); this.subscribeToEvents(); @@ -145,40 +129,19 @@ export class GlyphCanvasComponent implements OnInit, AfterViewInit, OnDestroy { } ngOnChanges(): void { - this.logger.log("The component has changed " + this.id); + this.logger.log('The component has changed ' + this.id); } ngOnDestroy(): void { - this.logger.log("Destroy " + this.id); + this.logger.log('Destroy ' + this.id); this.glyphData.forEach((glyph: GlyphObject) => { glyph.clearCache(this.id); }); this.configSub.unsubscribe(); - // Cleanup THREE.js if (this.animationFrameId) cancelAnimationFrame(this.animationFrameId); - - this.scene.traverse((obj) => { - if ((obj as THREE.Mesh).geometry) { - (obj as THREE.Mesh).geometry.dispose(); - } - - if ((obj as THREE.Mesh).material) { - const material = (obj as THREE.Mesh).material; - if (Array.isArray(material)) { - material.forEach((m) => m.dispose()); - } else { - material.dispose(); - } - } - }); - this.renderer.forceContextLoss?.(); // Optional for full GPU cleanup - this.renderer.domElement = null!; - this.scene = null!; - this.camera = null!; - this.glyphGroup.clear(); - this.renderer.dispose(); + this.rendererSvc.dispose(); this.resizeObserver.disconnect(); } //#endregion @@ -187,66 +150,43 @@ export class GlyphCanvasComponent implements OnInit, AfterViewInit, OnDestroy { private initThree(): void { const rect = this.canvasContainer.nativeElement.getBoundingClientRect(); const container = this.canvasContainer.nativeElement; - this.canvasWidth = rect.width + this.canvasWidth = rect.width; this.canvasHeight = rect.height; - this.sizeInfo.update(this.canvasWidth, this.canvasHeight); - - // Scene - this.scene = new THREE.Scene(); - this.scene.background = this.standardBackgroundColor; - - // Orthographic Camera Setup - this.camera = new THREE.OrthographicCamera( - (-this.canvasWidth) / 2, - (this.canvasWidth) / 2, - this.canvasHeight / 2, - -this.canvasHeight / 2, - 1, - 1000 - ); - this.camera.position.set(0, 0, 10); // Looking down the Z axis - this.camera.zoom = 1; - this.camera.updateProjectionMatrix(); - - // Renderer - this.renderer = new THREE.WebGLRenderer({ antialias: true }); - // Take retina devices into account / high density displays - let pixelRatio = window.devicePixelRatio > 1 ? window.devicePixelRatio * 4 : window.screen.pixelDepth; - this.renderer.setPixelRatio(pixelRatio); - this.renderer.domElement.style.width = '100%'; - this.renderer.domElement.style.height = '100%'; - this.renderer.domElement.style.display = 'block'; // prevent extra spacing - this.scene.add(this.glyphGroup); - container.appendChild(this.renderer.domElement); + this.cameraSvc.initCamera(this.canvasWidth, this.canvasHeight); + this.rendererSvc.initRenderer(container, this.canvasWidth, this.canvasHeight); + + // Wire up the animation loop — renderer service requests trigger the component's animate loop + this.rendererSvc.setRenderRequestCallback(() => { + if (!this.animationFrameId) { + this.animate(); + } + }); } private subscribeToEvents() { - this.dataProvider.dataSetCollectionSubject$.subscribe(data => { - - }); this.configSub.add( this.config.loadedDataSubject$.subscribe(async loadedData => { - if (loadedData == "") return; + if (loadedData === '') return; - let data = await this.dataProvider.getGlyphData(this.config.loadedData, this.selectedTimestamp); + const data = await this.dataLoader.getGlyphData(this.config.loadedData, this.selectedTimestamp); if (data) this.glyphData = data; this.ngZone.run(() => { - this.timestamps = this.dataProvider.getTimestamps(loadedData); - this.algorithms = this.dataProvider.getPositions(loadedData); - this.contexts = this.dataProvider.getContexts(loadedData); + this.timestamps = this.dataLoader.getTimestamps(loadedData); + this.algorithms = this.dataLoader.getPositions(loadedData); + this.contexts = this.dataLoader.getContexts(loadedData); this.selectedTimestamp = this.timestamps[0]; this.selectedAlgorithm = this.algorithms[0]; this.selectedContext = this.contexts[0]; - this.glyphGroup.clear(); + this.rendererSvc.glyphGroup.clear(); if (data) { - this.positionBounds = undefined; - this.updatePositionBounds(); - this.spatialGridDirty = true; + this.rendererSvc.positionBounds = undefined; + this.rendererSvc.updatePositionBounds(this.glyphData, this.selectedTimestamp, this.selectedAlgorithm); + this.rendererSvc.spatialGridDirty = true; // Note: spatial grid is rebuilt inside fitToView() after positions are scaled this.fitToView(); this.initSimulation(); @@ -259,10 +199,10 @@ export class GlyphCanvasComponent implements OnInit, AfterViewInit, OnDestroy { ); // Subscribe to collection updates to catch new algorithms added by background projections this.configSub.add( - this.dataProvider.dataSetCollectionSubject$.subscribe(() => { + this.dataLoader.dataSetCollectionSubject$.subscribe(() => { const loadedData = this.config.loadedData; if (loadedData) { - const newAlgorithms = this.dataProvider.getPositions(loadedData); + const newAlgorithms = this.dataLoader.getPositions(loadedData); // Only update if we have new algorithms if (newAlgorithms.length > this.algorithms.length) { this.ngZone.run(() => { @@ -276,42 +216,77 @@ export class GlyphCanvasComponent implements OnInit, AfterViewInit, OnDestroy { this.configSub.add( this.config.drawMagicLensGlyphsSubject$.subscribe(glyphs => { if (glyphs != null) { - this.renderMagicLensGlyphs(glyphs); + if (this.magicLenseStatus) { + // This canvas owns the lens — hide glyphs at their original positions + this.rendererSvc.hideLensGlyphs(glyphs, this.id, this.selectedTimestamp, this.selectedAlgorithm); + } else { + // Other canvases — show enlarged/highlighted glyphs + this.rendererSvc.renderMagicLensGlyphs( + glyphs, + this.glyphData, + this.id, + this.selectedTimestamp, + this.selectedAlgorithm, + this.aggregated, + this.buildRenderConfig() + ); + } } }) ); this.configSub.add( - this.config.commandSubject$.subscribe((command) => { - if (command == InteractionCommand.fittoscreen) { + this.config.commandSubject$.subscribe(command => { + if (command === InteractionCommand.fittoscreen) { this.fitToView(); - } else if (command == InteractionCommand.redraw) { - this.renderGlyphs(); - } else if (command == InteractionCommand.rerender) { - this.requestRender(RenderTask.SceneRender); - } else if (command == InteractionCommand.clearselection) { - this.selectionFilter.clear(); - this.renderGlyphs(); - } else if (command == InteractionCommand.exportimage) { - exportThreeSceneAsPNG(this.renderer, this.scene, this.camera, - { - filename: "three-scene-" + this.id + ".png", - scaleFactor: 2, - restoreAfterExport: true, - canvasElement: this.canvasContainer.nativeElement - } - ) + } else if (command === InteractionCommand.redraw) { + this.rendererSvc.renderGlyphs( + this.glyphData, + this.id, + this.selectedTimestamp, + this.selectedAlgorithm, + this.aggregated, + this.buildRenderConfig() + ); + } else if (command === InteractionCommand.rerender) { + this.rendererSvc.requestRender(RenderTask.SceneRender); + } else if (command === InteractionCommand.clearselection) { + this.selectionSvc.selectionFilter.clear(); + this.rendererSvc.renderGlyphs( + this.glyphData, + this.id, + this.selectedTimestamp, + this.selectedAlgorithm, + this.aggregated, + this.buildRenderConfig() + ); + } else if (command === InteractionCommand.exportimage) { + exportThreeSceneAsPNG(this.rendererSvc.renderer, this.rendererSvc.scene, this.cameraSvc.camera, { + filename: 'three-scene-' + this.id + '.png', + scaleFactor: 2, + restoreAfterExport: true, + canvasElement: this.canvasContainer.nativeElement, + }); } }) ); this.configSub.add( this.config.redrawGlyphSubject$.subscribe(glyph => { - if (glyph != null && this.glyphData.includes(glyph)) this.renderGlyph(glyph); + if (glyph != null && this.glyphData.includes(glyph)) { + this.rendererSvc.renderGlyph( + glyph, + this.selectedTimestamp, + this.selectedAlgorithm, + this.id, + this.aggregated, + this.buildRenderConfig() + ); + } }) ); this.configSub.add( this.config.animateGlyphSubject$.subscribe(glyph => { if (this.mouseInside) return; // no animation in current canvas - if (this.animateGlyph == glyph) return; + if (this.animateGlyph === glyph) return; this.resetAnimatedGlyph(); this.startAnimateGlyph(glyph); @@ -319,10 +294,19 @@ export class GlyphCanvasComponent implements OnInit, AfterViewInit, OnDestroy { ); this.configSub.add( this.config.glyphConfigSubject$.subscribe(() => { - if (this.magicLenseStatus) this.magicLensComponent.renderMagicLensGlyphs(this.selectedTimestamp, this.selectedAlgorithm); + if (this.magicLenseStatus) + this.magicLensComponent.renderMagicLensGlyphs(this.selectedTimestamp, this.selectedAlgorithm); // Force render all glyphs when config changes - glyph geometry needs to be // recreated with new features, regardless of current visibility state - this.renderGlyphs(true); + this.rendererSvc.renderGlyphs( + this.glyphData, + this.id, + this.selectedTimestamp, + this.selectedAlgorithm, + this.aggregated, + this.buildRenderConfig(), + true + ); }) ); } @@ -331,22 +315,23 @@ export class GlyphCanvasComponent implements OnInit, AfterViewInit, OnDestroy { const container = this.canvasContainer.nativeElement; this.resizeObserver = new ResizeObserver(entries => { - for (let entry of entries) { + for (const entry of entries) { const width = Math.floor(entry.contentRect.width); const height = Math.floor(entry.contentRect.height); this.canvasWidth = width; this.canvasHeight = height; - this.sizeInfo.update(this.canvasWidth, this.canvasHeight); - - // Note: renderer.setSize causes infinite loops - aspect ratio fix needs different approach - this.camera.left = width / -2; - this.camera.right = width / 2; - this.camera.top = height / 2; - this.camera.bottom = height / -2; - this.camera.updateProjectionMatrix(); - this.simulation?.force('collide', forceCollide(this.sizeInfo.getRadius(ZoomLevel.high))); + this.rendererSvc.updateRendererSize(width, height); + this.cameraSvc.updateCameraBounds(width, height); + this.simulation?.force('collide', forceCollide(this.rendererSvc.sizeInfo.getRadius(ZoomLevel.high))); this.resetAnimatedGlyph(); - this.renderGlyphs(); + this.rendererSvc.renderGlyphs( + this.glyphData, + this.id, + this.selectedTimestamp, + this.selectedAlgorithm, + this.aggregated, + this.buildRenderConfig() + ); } }); @@ -354,22 +339,24 @@ export class GlyphCanvasComponent implements OnInit, AfterViewInit, OnDestroy { } private initSimulation() { - this.simulation = forceSimulation(this.glyphData.map(glyph => glyph.getCacheObject(this.id, this.selectedTimestamp, this.selectedAlgorithm))) - .force('collide', forceCollide(this.sizeInfo.getRadius(ZoomLevel.high))) + this.simulation = forceSimulation( + this.glyphData.map(glyph => glyph.getCacheObject(this.id, this.selectedTimestamp, this.selectedAlgorithm)) + ) + .force('collide', forceCollide(this.rendererSvc.sizeInfo.getRadius(ZoomLevel.high))) .velocityDecay(0.5) .stop(); } //#endregion //#region Mode Changes - toggleNavigationMode(doToggle = true) { + toggleNavigationMode(_doToggle = true) { this.toggleSelectionMode(false); this.toggleMagicLens(false); } toggleSelectionMode(doToggle = true) { - this.selectionMode = !this.selectionMode && doToggle; - if (this.selectionMode) { + const active = this.selectionSvc.toggleSelectionMode(doToggle); + if (active) { this.canvasContainer.nativeElement.classList.add('selecting'); this.clearHoveredGlyph(); this.tooltipComponent.cancelHoverPopup(); @@ -380,7 +367,11 @@ export class GlyphCanvasComponent implements OnInit, AfterViewInit, OnDestroy { } toggleCollisionAvoidance(doToggle = true) { - if (this.needsRender.has(RenderTask.ForceSimulation || this.needsRender.has(RenderTask.OriginalSimulation))) return; + if ( + this.rendererSvc.needsRender.has(RenderTask.ForceSimulation) || + this.rendererSvc.needsRender.has(RenderTask.OriginalSimulation) + ) + return; this.collisionAvoidance = !this.collisionAvoidance && doToggle; @@ -389,11 +380,11 @@ export class GlyphCanvasComponent implements OnInit, AfterViewInit, OnDestroy { const cached = glyph.getCacheObject(this.id, this.selectedTimestamp, this.selectedAlgorithm); cached.x = cached.position.x; cached.y = cached.position.y; - }) + }); this.animationSpeed = 0.1; - this.requestRender(RenderTask.OriginalSimulation); + this.rendererSvc.requestRender(RenderTask.OriginalSimulation); } else { - this.requestRender(RenderTask.ForceSimulation); + this.rendererSvc.requestRender(RenderTask.ForceSimulation); } } @@ -401,11 +392,20 @@ export class GlyphCanvasComponent implements OnInit, AfterViewInit, OnDestroy { this.aggregated = !this.aggregated; if (this.aggregated) { - const glyphs: GlyphCacheObject[] = this.glyphData.map(glyph => glyph.getCacheObject(this.id, this.selectedTimestamp, this.selectedAlgorithm)); + const glyphs: GlyphCacheObject[] = this.glyphData.map(glyph => + glyph.getCacheObject(this.id, this.selectedTimestamp, this.selectedAlgorithm) + ); clusterGlyphs(glyphs, 10); } - this.renderGlyphs(); + this.rendererSvc.renderGlyphs( + this.glyphData, + this.id, + this.selectedTimestamp, + this.selectedAlgorithm, + this.aggregated, + this.buildRenderConfig() + ); } toggleMagicLens(doToggle = true): void { @@ -426,67 +426,52 @@ export class GlyphCanvasComponent implements OnInit, AfterViewInit, OnDestroy { toggleFixMagicLens(doToggle = true): void { this.magicLensComponent.toggleFix(doToggle); if (this.magicLensComponent.isFixed()) { - this.scene.background = this.disabledBackgroundColor; + this.rendererSvc.scene.background = this.rendererSvc.disabledBackgroundColor; this.canvasContainer.nativeElement.classList.remove('lensing'); - this.requestRender(RenderTask.SceneRender); + this.rendererSvc.requestRender(RenderTask.SceneRender); } else { if (this.magicLensComponent.isActive()) { this.canvasContainer.nativeElement.classList.add('lensing'); } - this.scene.background = this.standardBackgroundColor; + this.rendererSvc.scene.background = this.rendererSvc.standardBackgroundColor; } } takeScreenshot() { - exportThreeSceneAsPNG(this.renderer, this.scene, this.camera, - { - filename: "three-scene-" + this.id + ".png", - scaleFactor: 2, - restoreAfterExport: true, - canvasElement: this.canvasContainer.nativeElement - } - ) + exportThreeSceneAsPNG(this.rendererSvc.renderer, this.rendererSvc.scene, this.cameraSvc.camera, { + filename: 'three-scene-' + this.id + '.png', + scaleFactor: 2, + restoreAfterExport: true, + canvasElement: this.canvasContainer.nativeElement, + }); } fitToView() { if (this.collisionAvoidance) this.toggleCollisionAvoidance(); - this.scaleGroupToFit(); + this.rendererSvc.scaleGroupToFit( + this.glyphData, + this.id, + this.selectedTimestamp, + this.selectedAlgorithm, + this.canvasWidth, + this.canvasHeight + ); // Rebuild spatial grid after positions are scaled - this.rebuildSpatialGrid(); - this.sizeInfo.currentZoomLevel = ZoomLevel.low; - this.renderGlyphs(true); - - const box = new THREE.Box3().setFromObject(this.glyphGroup); - const size = box.getSize(new THREE.Vector3()); - const center = box.getCenter(new THREE.Vector3()); - - const margin = 1.1; // 10% padding - const widthWithMargin = size.x * margin; - const heightWithMargin = size.y * margin; - - const cameraWidth = this.camera.right - this.camera.left; - const cameraHeight = this.camera.top - this.camera.bottom; - - const zoomX = cameraWidth / widthWithMargin; - const zoomY = cameraHeight / heightWithMargin; - const requiredZoom = Math.min(zoomX, zoomY); - - // Direction preserved - const direction = new THREE.Vector3().subVectors(this.camera.position, this.target); - const newTarget = center.clone(); - const newPosition = center.clone().add(direction); - - // Save animation state - this.fitStartPosition = this.camera.position.clone(); - this.fitEndPosition = newPosition; - this.fitStartTarget = this.target.clone(); - this.fitEndTarget = newTarget; - this.fitStartZoom = this.camera.zoom; - this.fitEndZoom = requiredZoom; - this.fitAnimationStartTime = performance.now(); - - this.requestRender(RenderTask.FitAnimation); + this.rendererSvc.rebuildSpatialGrid(this.glyphData, this.id, this.selectedTimestamp, this.selectedAlgorithm); + this.rendererSvc.sizeInfo.currentZoomLevel = ZoomLevel.low; + this.rendererSvc.renderGlyphs( + this.glyphData, + this.id, + this.selectedTimestamp, + this.selectedAlgorithm, + this.aggregated, + this.buildRenderConfig(), + true + ); + + this.cameraSvc.startFitAnimation(this.rendererSvc.glyphGroup); + this.rendererSvc.requestRender(RenderTask.FitAnimation); } toggleSettings(): void { @@ -498,10 +483,10 @@ export class GlyphCanvasComponent implements OnInit, AfterViewInit, OnDestroy { } onTogglePlayback() { - if (!this.needsRender.has(RenderTask.OriginalSimulation)) { - this.requestRender(RenderTask.OriginalSimulation); + if (!this.rendererSvc.needsRender.has(RenderTask.OriginalSimulation)) { + this.rendererSvc.requestRender(RenderTask.OriginalSimulation); } else { - this.cancelRender(RenderTask.OriginalSimulation); + this.rendererSvc.cancelRender(RenderTask.OriginalSimulation); } } @@ -510,17 +495,17 @@ export class GlyphCanvasComponent implements OnInit, AfterViewInit, OnDestroy { this.selectedAlgorithm = payload.algorithm; this.selectedContext = payload.context; - this.positionBounds = undefined; - this.updatePositionBounds(); + this.rendererSvc.positionBounds = undefined; + this.rendererSvc.updatePositionBounds(this.glyphData, this.selectedTimestamp, this.selectedAlgorithm); this.glyphData.forEach(glyph => { const cache = glyph.getCacheObject(this.id, this.selectedTimestamp, this.selectedAlgorithm); - if (cache && this.positionBounds) { + if (cache && this.rendererSvc.positionBounds) { const newPos = glyph.getPosition(this.selectedTimestamp, this.selectedAlgorithm); const scalePos = scalePosition( newPos.x, newPos.y, - this.positionBounds, // set this during layout initialization + this.rendererSvc.positionBounds, this.canvasWidth, this.canvasHeight ); @@ -532,10 +517,9 @@ export class GlyphCanvasComponent implements OnInit, AfterViewInit, OnDestroy { }); // Rebuild spatial grid with new positions for correct hit testing - this.rebuildSpatialGrid(); + this.rendererSvc.rebuildSpatialGrid(this.glyphData, this.id, this.selectedTimestamp, this.selectedAlgorithm); - // this.animationSpeed = 0.01; - this.requestRender(RenderTask.OriginalSimulation); + this.rendererSvc.requestRender(RenderTask.OriginalSimulation); this.magicLensComponent.clearLensGlyphs(); } @@ -544,33 +528,33 @@ export class GlyphCanvasComponent implements OnInit, AfterViewInit, OnDestroy { this.mouseIdleTimer = setTimeout(() => { this.mouseInside = false; - }, this.MOUSE_IDLE_MS); + }, MOUSE_IDLE_MS); } private clearMouseIdleTimer(): void { if (this.mouseIdleTimer) { clearTimeout(this.mouseIdleTimer); - this.mouseIdleTimer = null; + this.mouseIdleTimer = undefined; } } onMouseEnter() { this.mouseInside = true; - this.isShiftDown = false; + this.selectionSvc.isShiftDown = false; this.resetMouseIdleTimer(); } onMouseLeave() { this.clearMouseIdleTimer(); this.mouseInside = false; - this.isShiftDown = false; + this.selectionSvc.isShiftDown = false; if (this.magicLensComponent.isActive() && !this.magicLensComponent.isFixed()) { this.toggleMagicLens(); } this.config.animateGlyph(null); this.clearHoveredGlyph(); this.tooltipComponent.cancelHoverPopup(); - this.isPanning = false; + this.cameraSvc.isPanning = false; } get magicLenseStatus(): boolean { @@ -579,86 +563,47 @@ export class GlyphCanvasComponent implements OnInit, AfterViewInit, OnDestroy { //#endregion //#region Helper Methods - private calculateZoomlevel(zoomLevel: number): ZoomLevel { - let level = ZoomLevel.high; - if (zoomLevel < 2) - level = ZoomLevel.low; - else if (zoomLevel < 10) - level = ZoomLevel.medium; - return level; - } - - checkZoomLevelChanged(oldZoom: number, newZoom: number): boolean { - const oldZoomLevel = this.calculateZoomlevel(oldZoom); - const newZoomLevel = this.calculateZoomlevel(newZoom); - if (oldZoomLevel != newZoomLevel) { - this.sizeInfo.currentZoomLevel = newZoomLevel; - this.sizeInfo.update(this.canvasWidth, this.canvasHeight); + private handleZoomLevelChange(oldZoom: number, newZoom: number): boolean { + const oldLevel = this.cameraSvc.calculateZoomLevel(oldZoom); + const newLevel = this.cameraSvc.calculateZoomLevel(newZoom); + if (oldLevel !== newLevel) { + this.rendererSvc.sizeInfo.currentZoomLevel = newLevel; + this.rendererSvc.sizeInfo.update(this.canvasWidth, this.canvasHeight); // Rebuild spatial grid with new radius for correct hit testing - this.rebuildSpatialGrid(); - // Force render all glyphs when zoom level changes - glyph geometry - // needs to be recreated and visibility state may be stale - this.renderGlyphs(true); + this.rendererSvc.rebuildSpatialGrid(this.glyphData, this.id, this.selectedTimestamp, this.selectedAlgorithm); + // Force render all glyphs when zoom level changes + this.rendererSvc.renderGlyphs( + this.glyphData, + this.id, + this.selectedTimestamp, + this.selectedAlgorithm, + this.aggregated, + this.buildRenderConfig(), + true + ); + return true; } - return oldZoomLevel != newZoomLevel; + return false; } updateMousePositions(event: MouseEvent) { // Convert screen (px) to NDC (-1 to 1) - const rect = this.renderer.domElement.getBoundingClientRect(); + const rect = this.rendererSvc.renderer.domElement.getBoundingClientRect(); this.mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1; this.mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1; } - - logStatus() { - this.logger.log("Component " + this.id); - this.logger.log("-- isPanning: " + this.isPanning); - this.logger.log("-- magicLensActive: " + this.magicLensComponent.isActive()); - this.logger.log("-- isSelecting: " + this.isSelecting); - this.logger.log("-- selectionMode: " + this.selectionMode); - } //#endregion //#region Rendering and Glyph Manipulations - public cancelRender(task: RenderTask) { - requestAnimationFrame(() => { - this.needsRender.delete(task); - }); - } - - public requestRender(task: RenderTask) { - if (!this.animationFrameId) { - this.needsRender.add(task); - this.animate(); - } else { - requestAnimationFrame(() => { - this.needsRender.add(task); - }); - } - } - - private updateViewRect(): void { - this.camera.updateMatrixWorld(); // keep pos / rot fresh - - const halfW = (this.camera.right - this.camera.left) / this.camera.zoom * 0.5; - const halfH = (this.camera.top - this.camera.bottom) / this.camera.zoom * 0.5; - - // camera looks down −Z; x‑y plane is world‑aligned - this.viewRect.left = this.camera.position.x - halfW; - this.viewRect.right = this.camera.position.x + halfW; - this.viewRect.bottom = this.camera.position.y - halfH; - this.viewRect.top = this.camera.position.y + halfH; - } - private animate = () => { - if (this.needsRender.size == 0) { + if (this.rendererSvc.needsRender.size === 0) { this.animationFrameId = undefined; // stop the loop return; } this.animationFrameId = requestAnimationFrame(this.animate); - if (this.needsRender.has(RenderTask.ForceSimulation)) { + if (this.rendererSvc.needsRender.has(RenderTask.ForceSimulation)) { this.currentTicks++; this.simulation?.tick(); @@ -670,447 +615,87 @@ export class GlyphCanvasComponent implements OnInit, AfterViewInit, OnDestroy { if (this.currentTicks > this.maxTicks) { this.currentTicks = 0; - this.cancelRender(RenderTask.ForceSimulation); + this.rendererSvc.cancelRender(RenderTask.ForceSimulation); + } + } else if (this.rendererSvc.needsRender.has(RenderTask.OriginalSimulation)) { + const finished = this.rendererSvc.animateBackToOriginal( + this.glyphData, + this.id, + this.selectedTimestamp, + this.selectedAlgorithm, + this.animationSpeed + ); + if (finished) { + this.rendererSvc.needsRender.delete(RenderTask.OriginalSimulation); } - } else if (this.needsRender.has(RenderTask.OriginalSimulation)) { - this.animateBackToOriginal(); } - if (this.needsRender.has(RenderTask.GlyphAnimation) && this.sizeInfo.currentZoomLevel == ZoomLevel.low) { + if ( + this.rendererSvc.needsRender.has(RenderTask.GlyphAnimation) && + this.rendererSvc.sizeInfo.currentZoomLevel === ZoomLevel.low + ) { if (this.animateGlyph != null) { const elapsed = performance.now() - this.pulseStartTime; // Pulsate with sine wave (e.g., 2 Hz frequency) const scaleFactor = 2 + 0.8 * Math.sin((elapsed / 3000) * 2 * Math.PI * 2); - this.animateGlyph.getMesh(this.selectedTimestamp, this.selectedAlgorithm, this.id)?.scale.set(scaleFactor, scaleFactor, scaleFactor); - } - } - - this.updateFitAnimation(); - this.updateClipping(); - this.renderer.render(this.scene, this.camera); - this.cancelRender(RenderTask.SceneRender); - }; - - private animateBackToOriginal() { - let finished = true; - this.glyphData.forEach(glyph => { - const cachedObject = glyph.getCacheObject(this.id, this.selectedTimestamp, this.selectedAlgorithm); - const target = cachedObject.position; - const mesh = cachedObject.mesh; - - if (mesh) { - const finalPosition = nearlyEqual(mesh.position.x, target.x) && nearlyEqual(mesh.position.y, target.y); - finished = finished && finalPosition; - mesh.position.lerp( - new THREE.Vector3(target.x, target.y, 0), - this.animationSpeed - ); + this.animateGlyph + .getMesh(this.selectedTimestamp, this.selectedAlgorithm, this.id) + ?.scale.set(scaleFactor, scaleFactor, scaleFactor); } - }); - if (finished) { - this.needsRender.delete(RenderTask.OriginalSimulation); } - } - - private scaleGroupToFit(): void { - this.glyphData.forEach(glyph => { - if (this.positionBounds == undefined) return; - - const cacheObject = glyph.getCacheObject(this.id, this.selectedTimestamp, this.selectedAlgorithm); - const originalX = glyph.getPosition(this.selectedTimestamp, this.selectedAlgorithm).x ?? 0; - const originalY = glyph.getPosition(this.selectedTimestamp, this.selectedAlgorithm).y ?? 0; - - const { x: scaledX, y: scaledY } = scalePosition( - originalX, - originalY, - this.positionBounds, // set this during layout initialization - this.canvasWidth, - this.canvasHeight - ); - - cacheObject.position.x = scaledX; // save for later reference to restore collision detection etc. - cacheObject.position.y = scaledY; - cacheObject.x = scaledX; - cacheObject.y = scaledY; - cacheObject.mesh?.position.set(scaledX, scaledY, 0); - }); - } - - private updateFitAnimation() { - if (this.fitAnimationStartTime === null) return; - - if (this.glyphData.length > 5000) { - this.fitAnimationStartTime = null; - this.camera.position.copy(this.fitEndPosition); - this.target.copy(this.fitEndTarget); - this.camera.zoom = this.fitEndZoom; - this.camera.updateProjectionMatrix(); - this.camera.lookAt(this.target); - } else { - const now = performance.now(); - const elapsed = now - this.fitAnimationStartTime; - const t = Math.min(elapsed / this.fitDuration, 1); - - // Easing function: easeInOutQuad - const easedT = t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t; - - // Interpolate position - const currentPosition = new THREE.Vector3().lerpVectors( - this.fitStartPosition, - this.fitEndPosition, - easedT - ); - this.camera.position.copy(currentPosition); - - // Interpolate target - const currentTarget = new THREE.Vector3().lerpVectors( - this.fitStartTarget, - this.fitEndTarget, - easedT - ); - this.target.copy(currentTarget); - - // Interpolate zoom - this.camera.zoom = THREE.MathUtils.lerp(this.fitStartZoom, this.fitEndZoom, easedT); - this.camera.updateProjectionMatrix(); - this.camera.lookAt(this.target); - - if (t === 1) { - this.checkZoomLevelChanged(this.fitStartZoom, this.camera.zoom); - this.cancelRender(RenderTask.FitAnimation); - this.fitAnimationStartTime = null; - } - } - } - private updateClipping() { - // Throttle to 30fps (every 2nd frame) - this.clippingFrameCounter++; - if (this.clippingFrameCounter % 2 !== 0) return; - - this.updateViewRect(); - const { left, right, bottom, top } = this.viewRect; - - // Skip if viewport hasn't changed significantly - const threshold = this.sizeInfo.radius * 0.5; - if ( - Math.abs(left - this.lastViewRect.left) < threshold && - Math.abs(right - this.lastViewRect.right) < threshold && - Math.abs(top - this.lastViewRect.top) < threshold && - Math.abs(bottom - this.lastViewRect.bottom) < threshold - ) { - return; + const fitCompleted = this.cameraSvc.updateFitAnimation(this.glyphData.length); + if (fitCompleted) { + this.handleZoomLevelChange(this.cameraSvc.fitStartZoom, this.cameraSvc.camera.zoom); + this.rendererSvc.cancelRender(RenderTask.FitAnimation); } - // Update cached viewport - this.lastViewRect.left = left; - this.lastViewRect.right = right; - this.lastViewRect.top = top; - this.lastViewRect.bottom = bottom; - - const r = this.sizeInfo.radius; - - // Use spatial grid for efficient viewport culling if available - if (this.spatialGrid.size > 0 && this.glyphData.length > 500) { - // For large datasets, use spatial grid O(k) instead of full scan O(n) - // First mark all as not visible - const visibleGlyphs = this.spatialGrid.queryRect(left - r, right + r, bottom - r, top + r); - - // Mark glyphs outside viewport as not visible - for (const glyph of this.glyphData) { - const cachedObject = glyph.getCacheObject(this.id, this.selectedTimestamp, this.selectedAlgorithm); - if (!visibleGlyphs.has(glyph)) { - cachedObject.visible = false; - } - } + this.cameraSvc.updateViewRect(); + this.rendererSvc.updateClipping( + this.glyphData, + this.cameraSvc.viewRect, + this.cameraSvc.lastViewRect, + this.id, + this.selectedTimestamp, + this.selectedAlgorithm, + this.aggregated, + this.buildRenderConfig() + ); - // Mark glyphs inside viewport as visible and render if needed - for (const glyph of visibleGlyphs) { - const cachedObject = glyph.getCacheObject(this.id, this.selectedTimestamp, this.selectedAlgorithm); - if (!cachedObject.visible) { - this.renderGlyph(glyph); - } - cachedObject.visible = true; - } - } else { - // For small datasets, use simple iteration (more efficient due to less overhead) - this.glyphData.forEach(glyph => { - const cachedObject = glyph.getCacheObject(this.id, this.selectedTimestamp, this.selectedAlgorithm); - const cachedMesh = cachedObject.mesh; - if (cachedMesh) { - const isVisible = - cachedMesh.position.x + r > left && - cachedMesh.position.x - r < right && - cachedMesh.position.y + r > bottom && - cachedMesh.position.y - r < top; - if (!cachedObject.visible && isVisible) this.renderGlyph(glyph); - cachedObject.visible = isVisible; - } - }); - } - } + this.rendererSvc.renderer.render(this.rendererSvc.scene, this.cameraSvc.camera); + this.rendererSvc.cancelRender(RenderTask.SceneRender); + }; private startAnimateGlyph(glyph: GlyphObject | null) { if (glyph == null) { this.animateGlyph = null; } else { - this.renderGlyph(glyph); + this.rendererSvc.renderGlyph( + glyph, + this.selectedTimestamp, + this.selectedAlgorithm, + this.id, + this.aggregated, + this.buildRenderConfig() + ); this.animateGlyph = glyph; this.pulseStartTime = performance.now(); - this.requestRender(RenderTask.GlyphAnimation); + this.rendererSvc.requestRender(RenderTask.GlyphAnimation); } } private resetAnimatedGlyph() { this.animateGlyph?.getMesh(this.selectedTimestamp, this.selectedAlgorithm, this.id)?.scale.set(1, 1, 1); // Reset scale - if (this.animateGlyph != null) this.renderGlyph(this.animateGlyph); - this.cancelRender(RenderTask.GlyphAnimation); - } - - private renderGlyphs(force = false): void { - if (this.scene === undefined) return; - - // Safety mechanism to prevent infinite render loops - this.renderGlyphsCallCount++; - if (this.renderGlyphsResetTimer) { - clearTimeout(this.renderGlyphsResetTimer); - } - this.renderGlyphsResetTimer = setTimeout(() => { - this.renderGlyphsCallCount = 0; - }, 1000); - - if (this.renderGlyphsCallCount > this.MAX_RENDER_CALLS_PER_SECOND) { - console.error(`Infinite render loop detected (${this.renderGlyphsCallCount} calls/sec). Breaking loop.`); - this.renderGlyphsCallCount = 0; - return; - } - - this.glyphData.forEach((glyph: GlyphObject) => { - const cacheObject = glyph.getCacheObject(this.id, this.selectedTimestamp, this.selectedAlgorithm); - const oldMesh = cacheObject.mesh; - if (oldMesh) this.glyphGroup.remove(oldMesh); - if (cacheObject.visible || force) { - const mesh = glyph.render(this.sizeInfo, this.selectedTimestamp, this.selectedAlgorithm, this.id, this.aggregated); - if (mesh != null) this.glyphGroup.add(mesh); - } - }); - - this.updatePositionBounds(); - this.requestRender(RenderTask.SceneRender); - } - - private updatePositionBounds() { - if (this.positionBounds == undefined && this.glyphData.length > 0) { - // Single-pass calculation to avoid creating large temporary arrays - let minX = Infinity, maxX = -Infinity; - let minY = Infinity, maxY = -Infinity; - - for (const glyph of this.glyphData) { - const pos = glyph.getPosition(this.selectedTimestamp, this.selectedAlgorithm); - const x = pos.x ?? 0; - const y = pos.y ?? 0; - if (x < minX) minX = x; - if (x > maxX) maxX = x; - if (y < minY) minY = y; - if (y > maxY) maxY = y; - } - - this.positionBounds = { minX, maxX, minY, maxY }; - } - } - - /** - * Rebuild the spatial grid with current glyph positions. - * Called when data is loaded or positions change significantly. - */ - private rebuildSpatialGrid(): void { - this.spatialGrid.clear(); - - // Adjust cell size based on data density and typical viewport - const count = this.glyphData.length; - if (count > 0 && this.positionBounds) { - const width = this.positionBounds.maxX - this.positionBounds.minX; - const height = this.positionBounds.maxY - this.positionBounds.minY; - const area = width * height; - // Target ~100 items per cell for optimal query performance - const targetCellArea = area / (count / 100); - const cellSize = Math.max(50, Math.sqrt(targetCellArea)); - this.spatialGrid.setCellSize(cellSize); - } - - const radius = this.sizeInfo.radius; - for (const glyph of this.glyphData) { - const cacheObject = glyph.getCacheObject(this.id, this.selectedTimestamp, this.selectedAlgorithm); - const x = cacheObject.position.x ?? 0; - const y = cacheObject.position.y ?? 0; - this.spatialGrid.insert(glyph, x, y, radius); - } - - this.spatialGridDirty = false; - } - - /** - * Optimized hit test using spatial grid for large datasets. - * Falls back to full scene scan for small datasets or when grid is unavailable. - */ - private optimizedHitTest(event: MouseEvent): THREE.Object3D | null { - // For small datasets, use standard hit test (less overhead) - if (this.glyphData.length <= 500 || this.spatialGrid.size === 0) { - return hitTest(event, this.renderer, this.glyphGroup, this.camera, this.sizeInfo); - } - - // Convert screen to world coordinates - const worldPos = screenToWorld(event, this.renderer, this.camera); - - // Query spatial grid for nearby glyphs (use generous radius for hit tolerance) - const searchRadius = this.sizeInfo.radius * 3; - const nearbyGlyphs = this.spatialGrid.queryPoint(worldPos.x, worldPos.y, searchRadius); - - if (nearbyGlyphs.size === 0) { - return null; - } - - // Get meshes for nearby glyphs - const candidates: THREE.Object3D[] = []; - for (const glyph of nearbyGlyphs) { - const mesh = glyph.getMesh(this.selectedTimestamp, this.selectedAlgorithm, this.id); - if (mesh) { - candidates.push(mesh); - } - } - - // Run hit test only on candidates - return hitTestCandidates(event, this.renderer, candidates, this.camera, this.sizeInfo); - } - - private resetUnhighlightedGlyphs(highlighted: Set) { - for (const glyph of this.glyphData) { - if (highlighted.has(glyph.id)) continue; - - const node = glyph.getCacheObject( - this.id, + if (this.animateGlyph != null) + this.rendererSvc.renderGlyph( + this.animateGlyph, this.selectedTimestamp, - this.selectedAlgorithm + this.selectedAlgorithm, + this.id, + this.aggregated, + this.buildRenderConfig() ); - - node.x = node.position.x; - node.y = node.position.y; - node.vx = 0; - node.vy = 0; - node.mesh?.position.set(node.position.x, node.position.y, 0); - } - } - - private renderMagicLensGlyphs(glyphs: GlyphObject[]) { - if (this.magicLensComponent.isActive()) return; - - this.lensSimulation?.stop(); - - const highlightedIds = new Set(glyphs.map(g => g.id)); - this.resetUnhighlightedGlyphs(highlightedIds); - - if (glyphs.length > 1) { - // Build nodes at their original positions - const nodes: { x: number; y: number; mesh: THREE.Object3D | undefined }[] = []; - - glyphs.forEach(glyph => { - const cache = glyph.getCacheObject(this.id, this.selectedTimestamp, this.selectedAlgorithm); - nodes.push({ - x: cache.position.x, - y: cache.position.y, - mesh: cache.mesh - }); - }); - - // Simple iterative collision resolution - push overlapping glyphs apart minimally - const enlargedRadius = this.sizeInfo.getRadius(ZoomLevel.high) * 5; - const minDist = enlargedRadius * 2; // Minimum distance between glyph centers - - // Run a few iterations of pairwise collision resolution - for (let iter = 0; iter < 5; iter++) { - for (let i = 0; i < nodes.length; i++) { - for (let j = i + 1; j < nodes.length; j++) { - const dx = nodes[j].x - nodes[i].x; - const dy = nodes[j].y - nodes[i].y; - const dist = Math.sqrt(dx * dx + dy * dy); - - if (dist < minDist && dist > 0) { - // Push apart by half the overlap each - const overlap = (minDist - dist) / 2; - const nx = dx / dist; - const ny = dy / dist; - - nodes[i].x -= nx * overlap; - nodes[i].y -= ny * overlap; - nodes[j].x += nx * overlap; - nodes[j].y += ny * overlap; - } - } - } - } - - // Apply final positions - nodes.forEach(node => { - node.mesh?.position.set(node.x, node.y, 0); - }); - } - - glyphs.forEach(glyph => { - const lensSize = this.sizeInfo.clone(); - lensSize.currentZoomLevel = ZoomLevel.high; - lensSize.radius = lensSize.radius * 5; - - let mesh = glyph.getMesh(this.selectedTimestamp, this.selectedAlgorithm, this.id); - if (mesh != undefined) { - this.glyphGroup.remove(mesh); - } - let newMesh = glyph.render(lensSize, this.selectedTimestamp, this.selectedAlgorithm, this.id, this.aggregated); - if (newMesh) { - this.glyphGroup.add(newMesh); - } - }); - - this.requestRender(RenderTask.SceneRender); - } - - - private renderGlyph(glyph: GlyphObject) { - let mesh = glyph.getMesh(this.selectedTimestamp, this.selectedAlgorithm, this.id); - if (mesh != undefined) this.glyphGroup.remove(mesh); - - let newMesh = glyph.render(this.sizeInfo, this.selectedTimestamp, this.selectedAlgorithm, this.id, this.aggregated); - if (newMesh) this.glyphGroup.add(newMesh); - - this.requestRender(RenderTask.SceneRender); - } - - private applyFilters() { - const filters = this.dataProvider.getFilters(); - if (!filters.includes(this.selectionFilter)) { - this.selectionFilter.filterMode = FilterMode.Or; - filters.push(this.selectionFilter); - } - this.dataProvider.refreshFilters(); - this.config.redraw(); - } - - private highlightSelectedObjects(selectedObjects: THREE.Object3D[], replace = false): void { - if (selectedObjects.length == 0) { - this.dataProvider.clearIdFilters(); - } else { - if (replace) { - this.dataProvider.clearIdFilters(); - } - for (const glyph of this.glyphData) { - const cache = glyph.getCacheObject(this.id, this.selectedTimestamp, this.selectedAlgorithm); - const obj = cache.mesh; - - if (obj && selectedObjects.includes(obj)) { - (this.selectionFilter as IdFilter).add(glyph.id); - } - } - } - this.applyFilters(); + this.rendererSvc.cancelRender(RenderTask.GlyphAnimation); } private clearHoveredGlyph() { @@ -1121,46 +706,6 @@ export class GlyphCanvasComponent implements OnInit, AfterViewInit, OnDestroy { } //#endregion - //#region Selection - private isMouseOverOverlay(event: MouseEvent): boolean { - const el = document.elementFromPoint(event.clientX, event.clientY); - const isOverOverlay = - el?.closest('.settings-panel') !== null - || el?.closest('.tooltip-popup') !== null - || el?.closest('.nav-controls-panel') !== null - return isOverOverlay; - } - - private updateSelectionBox(): void { - const x = Math.min(this.selectionStart.x, this.selectionEnd.x); - const y = Math.min(this.selectionStart.y, this.selectionEnd.y); - const w = Math.abs(this.selectionEnd.x - this.selectionStart.x); - const h = Math.abs(this.selectionEnd.y - this.selectionStart.y); - - this.selectionBox = { left: x, top: y, width: w, height: h }; - } - - private selectObjectsInRectangle(): void { - this.selectionBox = { left: 0, top: 0, width: 0, height: 0 }; - - const x1 = Math.min(this.selectionStart.x, this.selectionEnd.x); - const y1 = Math.min(this.selectionStart.y, this.selectionEnd.y); - const x2 = Math.max(this.selectionStart.x, this.selectionEnd.x); - const y2 = Math.max(this.selectionStart.y, this.selectionEnd.y); - - const contained: THREE.Object3D[] = []; - - this.glyphGroup.children.forEach((obj) => { - const screen = convertToScreenSpace(obj, this.camera, this.renderer.domElement); - if (screen.x >= x1 && screen.x <= x2 && screen.y >= y1 && screen.y <= y2) { - contained.push(obj); - } - }); - - this.highlightSelectedObjects(contained, !this.isShiftDown); - } - //#endregion - //#region HostListeners /** Listen to clicks anywhere in the document */ @@ -1174,7 +719,7 @@ export class GlyphCanvasComponent implements OnInit, AfterViewInit, OnDestroy { this.canvasActivated = true; this.resetMouseIdleTimer(); this.settingsPanel.activatePanel(); - if ((event.target as HTMLElement).localName === "canvas") { + if ((event.target as HTMLElement).localName === 'canvas') { this.settingsPanel.hideMenus(); } } @@ -1182,44 +727,61 @@ export class GlyphCanvasComponent implements OnInit, AfterViewInit, OnDestroy { @HostListener('document:keydown', ['$event']) onKeyDown(event: KeyboardEvent): void { - if (event.key === 'Shift') this.isShiftDown = true; - } + if (event.key === 'Shift') this.selectionSvc.isShiftDown = true; + } + + private keyBindings = new Map void>([ + ['c', () => this.toggleCollisionAvoidance()], + ['f', () => this.fitToView()], + ['a', () => this.toggleAggregation()], + ['d', () => this.toggleSettings()], + [ + 'n', + () => { + if (this.selectionSvc.selectionMode) this.toggleSelectionMode(); + if (this.magicLensComponent.isActive()) this.toggleMagicLens(); + }, + ], + ['s', () => this.toggleSelectionMode()], + [ + 'x', + () => + this.rendererSvc.renderGlyphs( + this.glyphData, + this.id, + this.selectedTimestamp, + this.selectedAlgorithm, + this.aggregated, + this.buildRenderConfig() + ), + ], + [ + 'l', + () => { + this.clearHoveredGlyph(); + this.toggleMagicLens(); + this.magicLensComponent.updateMagicLens( + this.lastMousePosition, + this.cameraSvc.camera, + this.rendererSvc.renderer + ); + this.magicLensComponent.renderMagicLensGlyphs(this.selectedTimestamp, this.selectedAlgorithm); + }, + ], + ]); @HostListener('document:keyup', ['$event']) onKeyUp(event: KeyboardEvent): void { if (checkTextInput(event)) return; - if (!this.mouseInside) return; - if (event.key === 'Shift') this.isShiftDown = false; - if (event.key.toLowerCase() === 'c') { - this.toggleCollisionAvoidance(); - } - if (event.key.toLowerCase() === 'f') { - this.fitToView(); - } - if (event.key.toLowerCase() === 'a') { - this.toggleAggregation(); - } - if (event.key.toLowerCase() === 'd') { - this.toggleSettings(); - } - if (event.key.toLowerCase() === 'n') { - if (this.selectionMode) this.toggleSelectionMode(); - if (this.magicLensComponent.isActive()) this.toggleMagicLens(); - } - if (event.key.toLowerCase() === 's') { - this.toggleSelectionMode(); - } - if (event.key.toLowerCase() === 'x') { - this.renderGlyphs(); - } - if (event.key.toLowerCase() === 'l') { - this.clearHoveredGlyph(); - this.toggleMagicLens(); - this.magicLensComponent.updateMagicLens(this.lastMousePosition, this.camera, this.renderer); - this.magicLensComponent.renderMagicLensGlyphs(this.selectedTimestamp, this.selectedAlgorithm); + if (event.key === 'Shift') { + this.selectionSvc.isShiftDown = false; + return; } + + const action = this.keyBindings.get(event.key.toLowerCase()); + action?.(); } @HostListener('mousedown', ['$event']) @@ -1229,20 +791,20 @@ export class GlyphCanvasComponent implements OnInit, AfterViewInit, OnDestroy { if (this.magicLensComponent.isActive()) return; this.lastMousePosition.set(event.clientX, event.clientY); - this.isPanning = true; + this.cameraSvc.isPanning = true; - if (this.selectionMode) { - this.isSelecting = true; - this.selectionStart.set(event.clientX, event.clientY); - this.selectionEnd.copy(this.selectionStart); + if (this.selectionSvc.selectionMode) { + this.selectionSvc.isSelecting = true; + this.selectionSvc.selectionStart.set(event.clientX, event.clientY); + this.selectionSvc.selectionEnd.copy(this.selectionSvc.selectionStart); } } @HostListener('mouseup', ['$event']) onMouseUp(event: MouseEvent): void { - this.isPanning = false; + this.cameraSvc.isPanning = false; - if (this.isMouseOverOverlay(event)) { + if (this.selectionSvc.isMouseOverOverlay(event)) { // Skip THREE.js interaction return; } @@ -1252,7 +814,7 @@ export class GlyphCanvasComponent implements OnInit, AfterViewInit, OnDestroy { const distance = Math.sqrt(dx * dx + dy * dy); const elapsedTime = Date.now() - this.mouseDownTime; - const isClick = distance < this.clickThreshold && elapsedTime < this.clickTimeThreshold; + const isClick = distance < CLICK_DISTANCE_THRESHOLD && elapsedTime < CLICK_TIME_THRESHOLD_MS; if (isClick && this.magicLensComponent.isActive()) { this.toggleFixMagicLens(); @@ -1264,33 +826,48 @@ export class GlyphCanvasComponent implements OnInit, AfterViewInit, OnDestroy { this.toggleFixMagicLens(); } - if (isClick && !this.selectionMode) { + if (isClick && !this.selectionSvc.selectionMode) { if (this.currentHoveredObject != null) { this.tooltipComponent.toggleFixation(); } return; } - if (this.isSelecting && this.selectionMode) { - this.isSelecting = false; + if (this.selectionSvc.isSelecting && this.selectionSvc.selectionMode) { + this.selectionSvc.isSelecting = false; // Single selection is a simple click - if (this.selectionStart.distanceTo(this.selectionEnd) < 0.1) { - let closestObject: THREE.Object3D | null = this.optimizedHitTest(event); + if (this.selectionSvc.selectionStart.distanceTo(this.selectionSvc.selectionEnd) < 0.1) { + const closestObject: THREE.Object3D | null = this.rendererSvc.optimizedHitTest( + event, + this.glyphData, + this.cameraSvc.camera, + this.selectedTimestamp, + this.selectedAlgorithm, + this.id + ); this.updateMousePositions(event); if (closestObject != null) { const glyph = getGlyphFromObject(closestObject); if (glyph != null) { - (this.selectionFilter as IdFilter).toggle(glyph.id); - this.applyFilters(); + (this.selectionSvc.selectionFilter as IdFilter).toggle(glyph.id); + this.selectionSvc.applyFilters(); } } else { - this.dataProvider.clearIdFilters(); - this.applyFilters(); + this.filterService.clearIdFilters(); + this.selectionSvc.applyFilters(); } } else { - this.selectObjectsInRectangle(); + this.selectionSvc.selectObjectsInRectangle( + this.rendererSvc.glyphGroup, + this.cameraSvc.camera, + this.rendererSvc.renderer.domElement, + this.glyphData, + this.id, + this.selectedTimestamp, + this.selectedAlgorithm + ); } } } @@ -1300,8 +877,8 @@ export class GlyphCanvasComponent implements OnInit, AfterViewInit, OnDestroy { this.mouseInside = true; this.resetMouseIdleTimer(); - if (this.isMouseOverOverlay(event) || this.tooltipComponent.isFixed()) { - this.isSelecting = false; + if (this.selectionSvc.isMouseOverOverlay(event) || this.tooltipComponent.isFixed()) { + this.selectionSvc.isSelecting = false; this.tooltipComponent.cancelHoverPopup(); // Skip THREE.js interaction return; @@ -1310,10 +887,10 @@ export class GlyphCanvasComponent implements OnInit, AfterViewInit, OnDestroy { this.updateMousePositions(event); if (this.magicLensComponent.isActive() && this.magicLensComponent.isFixed()) { - let closestObject: THREE.Object3D | null = this.magicLensComponent.doHitTest(event); + const closestObject: THREE.Object3D | null = this.magicLensComponent.doHitTest(event); if (closestObject != null) { const hoveredGlyph = getGlyphFromObject(closestObject); - if (hoveredGlyph != null && this.currentHoveredObject != hoveredGlyph) { + if (hoveredGlyph != null && this.currentHoveredObject !== hoveredGlyph) { this.currentHoveredObject = hoveredGlyph; this.tooltipComponent.cancelHoverPopup(); this.tooltipComponent.scheduleHoverPopup(event.clientX, event.clientY, closestObject as THREE.Object3D); @@ -1328,37 +905,59 @@ export class GlyphCanvasComponent implements OnInit, AfterViewInit, OnDestroy { if (this.magicLensComponent.isActive()) { this.lastMousePosition.set(event.clientX, event.clientY); this.magicLensComponent.renderLens(this.lastMousePosition); - const change = this.magicLensComponent.updateMagicLens(this.lastMousePosition, this.camera, this.renderer); + const change = this.magicLensComponent.updateMagicLens( + this.lastMousePosition, + this.cameraSvc.camera, + this.rendererSvc.renderer + ); if (change) this.magicLensComponent.renderMagicLensGlyphs(this.selectedTimestamp, this.selectedAlgorithm); return; } - if (this.isSelecting) { - this.selectionEnd.set(event.clientX, event.clientY); - this.updateSelectionBox(); - } else if (this.isPanning && !this.selectionMode) { + if (this.selectionSvc.isSelecting) { + this.selectionSvc.selectionEnd.set(event.clientX, event.clientY); + this.selectionSvc.updateSelectionBox(); + } else if (this.cameraSvc.isPanning && !this.selectionSvc.selectionMode) { this.tooltipComponent.cancelHoverPopup(); - panCamera(this.camera, this.lastMousePosition, event, this.target); - this.requestRender(RenderTask.SceneRender); - } else if (!this.needsRender.has(RenderTask.ForceSimulation) && !this.isSelecting && !this.selectionMode) { + this.cameraSvc.pan(this.lastMousePosition, event); + this.rendererSvc.requestRender(RenderTask.SceneRender); + } else if ( + !this.rendererSvc.needsRender.has(RenderTask.ForceSimulation) && + !this.selectionSvc.isSelecting && + !this.selectionSvc.selectionMode + ) { const now = performance.now(); - if (now - this.lastHitTestTime < this.throttleDelay) return; + if (now - this.lastHitTestTime < HIT_TEST_THROTTLE_MS) return; this.lastHitTestTime = now; - let closestObject: THREE.Object3D | null = this.optimizedHitTest(event); + const closestObject: THREE.Object3D | null = this.rendererSvc.optimizedHitTest( + event, + this.glyphData, + this.cameraSvc.camera, + this.selectedTimestamp, + this.selectedAlgorithm, + this.id + ); if (closestObject != null) { const hoveredGlyph = getGlyphFromObject(closestObject); - if (this.currentHoveredObject != hoveredGlyph) { + if (this.currentHoveredObject !== hoveredGlyph) { this.clearHoveredGlyph(); if (hoveredGlyph != null && !hoveredGlyph.highlighted) { - hoveredGlyph?.setHighlighted(true) + hoveredGlyph?.setHighlighted(true); this.pulseStartTime = performance.now(); - this.renderGlyph(hoveredGlyph); + this.rendererSvc.renderGlyph( + hoveredGlyph, + this.selectedTimestamp, + this.selectedAlgorithm, + this.id, + this.aggregated, + this.buildRenderConfig() + ); this.config.animateGlyph(hoveredGlyph); this.currentHoveredObject = hoveredGlyph; } - this.requestRender(RenderTask.SceneRender); + this.rendererSvc.requestRender(RenderTask.SceneRender); this.tooltipComponent.cancelHoverPopup(); this.tooltipComponent.scheduleHoverPopup(event.clientX, event.clientY, closestObject as THREE.Object3D); @@ -1367,7 +966,7 @@ export class GlyphCanvasComponent implements OnInit, AfterViewInit, OnDestroy { this.clearHoveredGlyph(); this.tooltipComponent.cancelHoverPopup(); this.config.animateGlyph(null); - if (this.currentHoveredObject != null) this.requestRender(RenderTask.SceneRender); + if (this.currentHoveredObject != null) this.rendererSvc.requestRender(RenderTask.SceneRender); this.currentHoveredObject = null; } } @@ -1375,75 +974,47 @@ export class GlyphCanvasComponent implements OnInit, AfterViewInit, OnDestroy { this.lastMousePosition.set(event.clientX, event.clientY); } - private applyZoomAtScreenPoint(screenX: number, screenY: number, newZoom: number, oldZoom: number): void { - const rect = this.renderer.domElement.getBoundingClientRect(); - - const xNDC = ((screenX - rect.left) / rect.width) * 2 - 1; - const yNDC = -((screenY - rect.top) / rect.height) * 2 + 1; - - const worldBefore = new THREE.Vector3(xNDC, yNDC, 0).unproject(this.camera); - - this.camera.zoom = newZoom; - this.camera.updateProjectionMatrix(); - - const worldAfter = new THREE.Vector3(xNDC, yNDC, 0).unproject(this.camera); - const delta = worldBefore.sub(worldAfter); - - this.camera.position.x += delta.x; - this.camera.position.y += delta.y; - - if (this.target) { - this.target.x += delta.x; - this.target.y += delta.y; - } - - this.checkZoomLevelChanged(oldZoom, newZoom); - this.requestRender(RenderTask.SceneRender); - } - - private getTouchDistance(event: TouchEvent): number { - const dx = event.touches[0].clientX - event.touches[1].clientX; - const dy = event.touches[0].clientY - event.touches[1].clientY; - return Math.sqrt(dx * dx + dy * dy); - } - - private touchCenter = { x: 0, y: 0 }; - private updateTouchCenter(event: TouchEvent): void { - const rect = this.renderer.domElement.getBoundingClientRect(); - const cx = (event.touches[0].clientX + event.touches[1].clientX) / 2; - const cy = (event.touches[0].clientY + event.touches[1].clientY) / 2; - - this.touchCenter.x = ((cx - rect.left) / rect.width) * 2 - 1; - this.touchCenter.y = -((cy - rect.top) / rect.height) * 2 + 1; - } - @HostListener('wheel', ['$event']) onWheel(event: WheelEvent): void { // Always prevent default to avoid browser zoom, even when Magic Lens is active event.preventDefault(); - if (!this.camera || !this.renderer || this.magicLensComponent.isActive() || this.tooltipComponent.isFixed()) return; + if ( + !this.cameraSvc.camera || + !this.rendererSvc.renderer || + this.magicLensComponent.isActive() || + this.tooltipComponent.isFixed() + ) + return; this.tooltipComponent.cancelHoverPopup(); - const oldZoom = this.camera.zoom; + const oldZoom = this.cameraSvc.camera.zoom; const direction = event.deltaY < 0 ? 1 : -1; - const scale = Math.pow(this.zoomFactor, direction); - const newZoom = THREE.MathUtils.clamp(this.camera.zoom * scale, 0.5, 50); - - this.applyZoomAtScreenPoint(event.clientX, event.clientY, newZoom, oldZoom); + const scale = Math.pow(this.cameraSvc.zoomFactor, direction); + const newZoom = THREE.MathUtils.clamp(this.cameraSvc.camera.zoom * scale, 0.5, 50); + + this.cameraSvc.applyZoomAtScreenPoint( + event.clientX, + event.clientY, + newZoom, + oldZoom, + this.rendererSvc.renderer.domElement + ); + this.handleZoomLevelChange(oldZoom, newZoom); + this.rendererSvc.requestRender(RenderTask.SceneRender); } @HostListener('touchstart', ['$event']) onTouchStart(event: TouchEvent): void { if (event.touches.length === 1) { - this.lastTouchPosition = { + this.cameraSvc.lastTouchPosition = { x: event.touches[0].clientX, - y: event.touches[0].clientY + y: event.touches[0].clientY, }; } if (event.touches.length === 2) { - this.touchZoomStartDistance = this.getTouchDistance(event); - this.lastZoom = this.camera?.zoom ?? null; + this.cameraSvc.touchZoomStartDistance = this.cameraSvc.getTouchDistance(event); + this.cameraSvc.lastZoom = this.cameraSvc.camera?.zoom ?? null; } } @@ -1451,52 +1022,53 @@ export class GlyphCanvasComponent implements OnInit, AfterViewInit, OnDestroy { @HostListener('touchcancel', ['$event']) onTouchEnd(event: TouchEvent): void { if (event.touches.length < 2) { - this.touchZoomStartDistance = null; - this.lastZoom = null; + this.cameraSvc.touchZoomStartDistance = null; + this.cameraSvc.lastZoom = null; } if (event.touches.length < 1) { - this.lastTouchPosition = null; + this.cameraSvc.lastTouchPosition = null; } } @HostListener('touchmove', ['$event']) onTouchMove(event: TouchEvent): void { - if (!this.camera || !this.renderer) return; + if (!this.cameraSvc.camera || !this.rendererSvc.renderer) return; event.preventDefault(); - if (event.touches.length === 1 && this.lastTouchPosition) { + if (event.touches.length === 1 && this.cameraSvc.lastTouchPosition) { const currentTouch = event.touches[0]; const fakeMouseEvent = { clientX: currentTouch.clientX, - clientY: currentTouch.clientY + clientY: currentTouch.clientY, } as MouseEvent; - const from = new THREE.Vector2(this.lastTouchPosition.x, this.lastTouchPosition.y); + const from = new THREE.Vector2(this.cameraSvc.lastTouchPosition.x, this.cameraSvc.lastTouchPosition.y); this.tooltipComponent.cancelHoverPopup(); - panCamera(this.camera, from, fakeMouseEvent, this.target); - this.requestRender(RenderTask.SceneRender); + this.cameraSvc.pan(from, fakeMouseEvent); + this.rendererSvc.requestRender(RenderTask.SceneRender); - this.lastTouchPosition = { + this.cameraSvc.lastTouchPosition = { x: currentTouch.clientX, - y: currentTouch.clientY + y: currentTouch.clientY, }; } - if (event.touches.length === 2 && this.touchZoomStartDistance !== null) { - - const currentDistance = this.getTouchDistance(event); - const zoomRatio = currentDistance / this.touchZoomStartDistance; + if (event.touches.length === 2 && this.cameraSvc.touchZoomStartDistance !== null) { + const currentDistance = this.cameraSvc.getTouchDistance(event); + const zoomRatio = currentDistance / this.cameraSvc.touchZoomStartDistance; - const oldZoom = this.lastZoom ?? this.camera.zoom; + const oldZoom = this.cameraSvc.lastZoom ?? this.cameraSvc.camera.zoom; const newZoom = THREE.MathUtils.clamp(oldZoom * zoomRatio, 0.5, 50); const centerX = (event.touches[0].clientX + event.touches[1].clientX) / 2; const centerY = (event.touches[0].clientY + event.touches[1].clientY) / 2; - this.updateTouchCenter(event); // similar to `updateMousePositions()` + this.cameraSvc.updateTouchCenter(event, this.rendererSvc.renderer.domElement); - this.applyZoomAtScreenPoint(centerX, centerY, newZoom, oldZoom); + this.cameraSvc.applyZoomAtScreenPoint(centerX, centerY, newZoom, oldZoom, this.rendererSvc.renderer.domElement); + this.handleZoomLevelChange(oldZoom, newZoom); + this.rendererSvc.requestRender(RenderTask.SceneRender); } } //#endregion diff --git a/src/app/canvas/magiclens/magiclens.component.html b/src/app/canvas/magiclens/magiclens.component.html index 6f042ab..2555a18 100644 --- a/src/app/canvas/magiclens/magiclens.component.html +++ b/src/app/canvas/magiclens/magiclens.component.html @@ -1,15 +1,22 @@ - +
\ No newline at end of file +>
diff --git a/src/app/canvas/magiclens/magiclens.component.scss b/src/app/canvas/magiclens/magiclens.component.scss index e3dff6e..2ed5e2f 100644 --- a/src/app/canvas/magiclens/magiclens.component.scss +++ b/src/app/canvas/magiclens/magiclens.component.scss @@ -1,3 +1,5 @@ +@use '../../../styles/variables' as v; + .lens-canvas { position: absolute; z-index: 999; /* lower than overlay-controls, which is z-index: 1001 */ @@ -5,9 +7,9 @@ .lens-indicator { position: absolute; - border: 1px solid rgba(46, 21, 21, 0.7); + border: 1px solid v.$gray-700; border-radius: 50%; - width: 40px; - height: 40px; + width: 60px; + height: 60px; pointer-events: none; -} \ No newline at end of file +} diff --git a/src/app/canvas/magiclens/magiclens.component.spec.ts b/src/app/canvas/magiclens/magiclens.component.spec.ts deleted file mode 100644 index e2f4f50..0000000 --- a/src/app/canvas/magiclens/magiclens.component.spec.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { MagiclensComponent } from './magiclens.component'; - -describe('MagiclensComponent', () => { - let component: MagiclensComponent; - let fixture: ComponentFixture; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - imports: [MagiclensComponent] - }) - .compileComponents(); - - fixture = TestBed.createComponent(MagiclensComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/src/app/canvas/magiclens/magiclens.component.ts b/src/app/canvas/magiclens/magiclens.component.ts index 0260177..2938d6e 100644 --- a/src/app/canvas/magiclens/magiclens.component.ts +++ b/src/app/canvas/magiclens/magiclens.component.ts @@ -1,4 +1,4 @@ -import { Component, ElementRef, Input, ViewChild } from '@angular/core'; +import { Component, ElementRef, Input, ViewChild, AfterViewInit, OnDestroy } from '@angular/core'; import { forceSimulation, forceCollide } from 'd3-force'; import * as THREE from 'three'; import { GlyphObject } from '../../glyph/glyph-object'; @@ -6,15 +6,17 @@ import { ZoomLevel } from '../../shared/enum/zoom-level'; import { getGlyphFromObject } from '../../shared/helpers/glyph-helper'; import { hitTest, screenToWorld } from '../../shared/helpers/three-helper'; import { ConfigService } from '../../services/config.service'; +import { DataProcessorService } from '../../services/data-processor'; import { GlyphSizeInfo } from '../../glyph/glyph-size-info'; +import { buildGlyphRenderConfig } from '../../glyph/glyph-render-config'; @Component({ selector: 'app-magiclens', imports: [], templateUrl: './magiclens.component.html', - styleUrl: './magiclens.component.scss' + styleUrl: './magiclens.component.scss', }) -export class MagiclensComponent { +export class MagiclensComponent implements AfterViewInit, OnDestroy { @Input() container!: HTMLElement; @Input() glyphGroup!: THREE.Group; @Input() parentId!: number; @@ -28,21 +30,41 @@ export class MagiclensComponent { relativePosition = new THREE.Vector2(); magicLensActive = false; isLensFixed = false; - lensRadius = 250; // in pixels - lensZoomFactor = 12; // how much magnification to apply lensGlyphs: GlyphObject[] = []; private sizeInfo = new GlyphSizeInfo(); - // Adaptive performance settings - private maxLensGlyphs = 30; // Starting value, will adapt + // Lens geometry + readonly lensRadius = 250; // Lens canvas diameter in pixels + private readonly LENS_ZOOM_FACTOR = 12; // Magnification multiplier + private readonly DETECTION_RADIUS_PX = 30; // Screen-space radius for glyph detection + private readonly LENS_MOUSE_OFFSET_PX = 10; // Spacing between cursor and lens popup + private readonly CIRCULAR_LAYOUT_PADDING = 1.2; // Radius multiplier for 2-3 glyph layout + + // Force simulation + private readonly MAX_SIMULATION_TICKS = 50; + private readonly BASE_SIMULATION_TICKS = 20; + private readonly TICKS_PER_GLYPH = 2; + private readonly BOUNDARY_CHECK_INTERVAL = 5; + private readonly SIMULATION_VELOCITY_DECAY = 0.3; + + // Adaptive performance + private maxLensGlyphs = 30; private readonly MIN_LENS_GLYPHS = 10; private readonly MAX_LENS_GLYPHS = 30; - private readonly TARGET_FRAME_TIME = 12; // ms (target ~80fps to leave headroom) + private readonly TARGET_FRAME_TIME_MS = 12; // ~83fps to leave headroom + private readonly SLOW_THRESHOLD = 1.5; // Frame time multiplier for slowdown + private readonly FAST_THRESHOLD = 0.5; // Frame time multiplier for speedup + private readonly SCALE_DOWN_FACTOR = 0.8; + private readonly SCALE_UP_FACTOR = 1.2; + private readonly ADAPT_THRESHOLD = 0.8; // Only adapt when near the limit private lastRenderTime = 0; - constructor(private config: ConfigService) { + constructor( + private config: ConfigService, + private dataProcessor: DataProcessorService + ) { this.sizeInfo.currentZoomLevel = ZoomLevel.high; - this.sizeInfo.radius = this.sizeInfo.radius * this.lensZoomFactor; + this.sizeInfo.radius = this.sizeInfo.radius * this.LENS_ZOOM_FACTOR; this.sizeInfo.hitTolerance = this.sizeInfo.radius; } @@ -52,7 +74,7 @@ export class MagiclensComponent { this.lensRenderer = new THREE.WebGLRenderer({ canvas: this.lensCanvasRef.nativeElement, alpha: true, - antialias: true + antialias: true, }); this.lensRenderer.setClearColor(0xffffff, 1); this.lensRenderer.setSize(this.lensRadius, this.lensRadius); @@ -60,8 +82,8 @@ export class MagiclensComponent { // Lens Camera is just a zoomed clone of main this.lensCamera = new THREE.OrthographicCamera( - (-this.lensRadius) / 2, - (this.lensRadius) / 2, + -this.lensRadius / 2, + this.lensRadius / 2, this.lensRadius / 2, -this.lensRadius / 2, 1, @@ -73,11 +95,14 @@ export class MagiclensComponent { this.lensCamera.updateProjectionMatrix(); } } - + ngOnDestroy(): void { this.lensRenderer.forceContextLoss?.(); // Optional for full GPU cleanup + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- intentional cleanup to release DOM reference this.lensRenderer.domElement = null!; + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- intentional cleanup to release scene reference this.lensScene = null!; + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- intentional cleanup to release camera reference this.lensCamera = null!; this.lensGlyphGroup.clear(); this.lensRenderer.dispose(); @@ -106,7 +131,11 @@ export class MagiclensComponent { this.lensGlyphs = []; } - updateMagicLens(lastMousePosition: THREE.Vector2, camera: THREE.OrthographicCamera, renderer: THREE.WebGLRenderer): boolean { + updateMagicLens( + lastMousePosition: THREE.Vector2, + camera: THREE.OrthographicCamera, + renderer: THREE.WebGLRenderer + ): boolean { if (!this.magicLensActive || !this.lensCamera) return false; this.updatePositions(lastMousePosition); @@ -116,13 +145,12 @@ export class MagiclensComponent { const mouseEvent = { clientX: lastMousePosition.x, clientY: lastMousePosition.y } as MouseEvent; const mouseWorld = screenToWorld(mouseEvent, renderer, camera); - // Calculate world-space radius based on screen pixel radius (30px) and camera zoom + // Calculate world-space radius based on screen pixel radius and camera zoom // This avoids converting every glyph to screen space - const screenRadius = 30; // pixels - slightly larger tolerance for better UX - const worldRadius = screenRadius / camera.zoom; + const worldRadius = this.DETECTION_RADIUS_PX / camera.zoom; // Check glyphs within world-space radius (O(n) but with cheaper distance calc) - this.glyphGroup.children.forEach((obj) => { + this.glyphGroup.children.forEach(obj => { const dx = obj.position.x - mouseWorld.x; const dy = obj.position.y - mouseWorld.y; const distSq = dx * dx + dy * dy; @@ -137,8 +165,7 @@ export class MagiclensComponent { // Compare current lens glyphs to new ones const same = - newLensGlyphs.length === this.lensGlyphs.length && - newLensGlyphs.every((g, i) => g === this.lensGlyphs[i]); + newLensGlyphs.length === this.lensGlyphs.length && newLensGlyphs.every((g, i) => g === this.lensGlyphs[i]); if (same) return false; @@ -151,10 +178,7 @@ export class MagiclensComponent { updatePositions(lastMousePosition: THREE.Vector2) { const canvasRect = this.container.getBoundingClientRect(); - this.relativePosition.set( - lastMousePosition.x - canvasRect.left, - lastMousePosition.y - canvasRect.top - ); + this.relativePosition.set(lastMousePosition.x - canvasRect.left, lastMousePosition.y - canvasRect.top); } renderMagicLensGlyphs(timestamp: string, algorithm: string): void { @@ -162,18 +186,18 @@ export class MagiclensComponent { this.lensGlyphGroup.clear(); // Adaptive limit based on previous performance - const glyphsToRender = this.lensGlyphs.length > this.maxLensGlyphs - ? this.lensGlyphs.slice(0, this.maxLensGlyphs) - : this.lensGlyphs; + const glyphsToRender = + this.lensGlyphs.length > this.maxLensGlyphs ? this.lensGlyphs.slice(0, this.maxLensGlyphs) : this.lensGlyphs; // Build nodes array while creating glyphs const nodes: { x: number; y: number; threeObj: THREE.Object3D }[] = []; for (const glyph of glyphsToRender) { - const mesh = glyph.renderGlyph(this.sizeInfo, timestamp, algorithm, this.parentId, false); + const renderConfig = buildGlyphRenderConfig(this.config, this.dataProcessor); + const mesh = glyph.renderGlyph(this.sizeInfo, timestamp, algorithm, this.parentId, false, renderConfig); if (mesh != null) { const wrapper = new THREE.Group(); - wrapper.name = "Wrapper"; + wrapper.name = 'Wrapper'; wrapper.userData = { item: new WeakRef(glyph) }; wrapper.add(mesh); mesh.position.set(0, 0, 0); @@ -182,7 +206,7 @@ export class MagiclensComponent { nodes.push({ x: (Math.random() - 0.5) * 2, y: (Math.random() - 0.5) * 2, - threeObj: wrapper + threeObj: wrapper, }); } } @@ -198,7 +222,7 @@ export class MagiclensComponent { // For 2-3 glyphs, use simple circular positions (no simulation needed) if (count <= 3) { const angleStep = (2 * Math.PI) / count; - const radius = this.sizeInfo.radius * 1.2; + const radius = this.sizeInfo.radius * this.CIRCULAR_LAYOUT_PADDING; nodes.forEach((node, i) => { node.threeObj.position.x = Math.cos(angleStep * i) * radius; node.threeObj.position.y = Math.sin(angleStep * i) * radius; @@ -213,19 +237,19 @@ export class MagiclensComponent { } private runForceSimulation(nodes: { x: number; y: number; threeObj: THREE.Object3D }[], count: number): void { - const maxRadius = (this.lensRadius / 2) - this.sizeInfo.radius; + const maxRadius = this.lensRadius / 2 - this.sizeInfo.radius; const maxRadiusSq = maxRadius * maxRadius; const simulation = forceSimulation(nodes) .force('collide', forceCollide().radius(this.sizeInfo.radius).strength(1)) - .velocityDecay(0.3) + .velocityDecay(this.SIMULATION_VELOCITY_DECAY) .stop(); - const totalTicks = Math.min(50, 20 + count * 2); + const totalTicks = Math.min(this.MAX_SIMULATION_TICKS, this.BASE_SIMULATION_TICKS + count * this.TICKS_PER_GLYPH); for (let i = 0; i < totalTicks; i++) { simulation.tick(1); - if (i % 5 === 0) this.enforceBoundary(nodes, maxRadius, maxRadiusSq); + if (i % this.BOUNDARY_CHECK_INTERVAL === 0) this.enforceBoundary(nodes, maxRadius, maxRadiusSq); } // Final boundary enforcement and apply positions @@ -252,7 +276,7 @@ export class MagiclensComponent { this.lensCamera.lookAt(0, 0, 0); this.lensCamera.updateProjectionMatrix(); - renderedGlyphs.forEach((glyph) => { + renderedGlyphs.forEach(glyph => { glyph.isInLense = true; }); this.config.drawMagicLensGlyphs(renderedGlyphs); @@ -264,20 +288,12 @@ export class MagiclensComponent { private adaptGlyphLimit(renderedCount: number): void { // Only adapt if we rendered near the limit (otherwise we can't measure properly) - if (renderedCount < this.maxLensGlyphs * 0.8) return; + if (renderedCount < this.maxLensGlyphs * this.ADAPT_THRESHOLD) return; - if (this.lastRenderTime > this.TARGET_FRAME_TIME * 1.5) { - // Too slow - decrease limit - this.maxLensGlyphs = Math.max( - this.MIN_LENS_GLYPHS, - Math.floor(this.maxLensGlyphs * 0.8) - ); - } else if (this.lastRenderTime < this.TARGET_FRAME_TIME * 0.5) { - // Fast enough - can increase limit - this.maxLensGlyphs = Math.min( - this.MAX_LENS_GLYPHS, - Math.floor(this.maxLensGlyphs * 1.2) - ); + if (this.lastRenderTime > this.TARGET_FRAME_TIME_MS * this.SLOW_THRESHOLD) { + this.maxLensGlyphs = Math.max(this.MIN_LENS_GLYPHS, Math.floor(this.maxLensGlyphs * this.SCALE_DOWN_FACTOR)); + } else if (this.lastRenderTime < this.TARGET_FRAME_TIME_MS * this.FAST_THRESHOLD) { + this.maxLensGlyphs = Math.min(this.MAX_LENS_GLYPHS, Math.floor(this.maxLensGlyphs * this.SCALE_UP_FACTOR)); } } @@ -287,14 +303,15 @@ export class MagiclensComponent { this.updatePositions(lastMousePosition); this.lensRenderer.render(this.lensScene, this.lensCamera); - const lensElem = this.lensCanvasRef!.nativeElement; + const lensElem = this.lensCanvasRef?.nativeElement; + if (!lensElem) return; const canvasRect = this.container.getBoundingClientRect(); // or your canvas element // Dimensions const lensWidth = lensElem.offsetWidth; const lensHeight = lensElem.offsetHeight; - const padding = 10; // spacing from mouse + const padding = this.LENS_MOUSE_OFFSET_PX; const viewportWidth = canvasRect.width; const viewportHeight = canvasRect.height; diff --git a/src/app/canvas/navigationcontrols/navigationcontrols.component.html b/src/app/canvas/navigationcontrols/navigationcontrols.component.html index 847c080..10229c8 100644 --- a/src/app/canvas/navigationcontrols/navigationcontrols.component.html +++ b/src/app/canvas/navigationcontrols/navigationcontrols.component.html @@ -1,31 +1,26 @@ \ No newline at end of file + + + diff --git a/src/app/canvas/navigationcontrols/navigationcontrols.component.scss b/src/app/canvas/navigationcontrols/navigationcontrols.component.scss index c3e3e48..ce28c8a 100644 --- a/src/app/canvas/navigationcontrols/navigationcontrols.component.scss +++ b/src/app/canvas/navigationcontrols/navigationcontrols.component.scss @@ -55,7 +55,7 @@ } &:hover { - background: #e6f0ff; + background: v.$ui-active-bg; /* subtle blue hover */ } @@ -71,4 +71,4 @@ } @include m.tooltip-right(6px); -} \ No newline at end of file +} diff --git a/src/app/canvas/navigationcontrols/navigationcontrols.component.ts b/src/app/canvas/navigationcontrols/navigationcontrols.component.ts index bbc0afa..7a2ea8e 100644 --- a/src/app/canvas/navigationcontrols/navigationcontrols.component.ts +++ b/src/app/canvas/navigationcontrols/navigationcontrols.component.ts @@ -1,19 +1,17 @@ import { Component, EventEmitter, Input, Output } from '@angular/core'; @Component({ - selector: 'app-navigationcontrols', - standalone: true, - templateUrl: './navigationcontrols.component.html', - styleUrls: ['./navigationcontrols.component.scss'], + selector: 'app-navigationcontrols', + standalone: true, + templateUrl: './navigationcontrols.component.html', + styleUrls: ['./navigationcontrols.component.scss'], }) export class CanvasNavigationControlsComponent { + @Input() visible = false; // controls fade in/out + @Input() selectionMode!: boolean; + @Input() magicLenseStatus!: boolean; - @Input() visible = false; // controls fade in/out - @Input() selectionMode!: boolean; - @Input() magicLenseStatus!: boolean; - - @Output() toggleNavigation = new EventEmitter(); - @Output() toggleSelection = new EventEmitter(); - @Output() toggleLens = new EventEmitter(); - + @Output() toggleNavigation = new EventEmitter(); + @Output() toggleSelection = new EventEmitter(); + @Output() toggleLens = new EventEmitter(); } diff --git a/src/app/canvas/overlaycontrols/overlaycontrols.component.html b/src/app/canvas/overlaycontrols/overlaycontrols.component.html deleted file mode 100644 index c36d0cf..0000000 --- a/src/app/canvas/overlaycontrols/overlaycontrols.component.html +++ /dev/null @@ -1,93 +0,0 @@ - -
- - - - - - - - - -
- - - - - - -
-
Playback Controls
-
- - - -
- {{ animationSpeed }} -
- - - - -
-
-
-
\ No newline at end of file diff --git a/src/app/canvas/overlaycontrols/overlaycontrols.component.scss b/src/app/canvas/overlaycontrols/overlaycontrols.component.scss deleted file mode 100644 index 3ca4319..0000000 --- a/src/app/canvas/overlaycontrols/overlaycontrols.component.scss +++ /dev/null @@ -1,154 +0,0 @@ -@use '../../../styles/variables' as v; -@use '../../../styles/mixins' as m; - -.overlay-controls { - position: absolute; - top: 0px; - left: 0px; - display: flex; - flex-direction: row; - gap: 4px; // minimal spacing - z-index: 1001 !important; - - // 🔽 Add a gentle background - background-color: v.$overlay-bg; // very subtle - padding: 2px 3px; - - button { - all: unset; // removes background, border, etc. - padding: 2px; - cursor: pointer; - color: v.$gray-500; // gray icons - font-size: 16px; - line-height: 1; - position: relative; - - i.material-icons { - font-size: 18px; - vertical-align: middle; - } - - &:hover { - color: v.$gray-400; // lighter gray on hover - } - - &.active { - color: v.$active-color; // cyan highlight for active buttons - } - - @include m.tooltip-below(28px); - } -} - -.settings-dropdown { - position: absolute; - top: 30px; - right: 0; - left: 0; - background-color: v.$overlay-bg; - padding: 6px 8px; - border-radius: 0; - z-index: 1002; - display: flex; - flex-direction: column; - gap: 12px; - - label { - position: relative; - font-size: 11px; - color: v.$gray-700; - - select { - margin-top: 0; - font-size: 12px; - padding: 18px 4px 4px 2px; - background-color: v.$select-bg; - border: none; - border-bottom: 1px solid v.$gray-600; - color: v.$gray-800; - appearance: none; - width: 100%; - cursor: pointer; - outline: none; - - &:hover { - background-color: v.$select-bg-hover; - } - - &:focus { - background-color: v.$select-bg-focus; - border-bottom-color: v.$gray-300; - } - } - - .select-label { - position: absolute; - top: 4px; - left: 0px; - font-size: 9px; - color: v.$gray-600; - text-transform: uppercase; - pointer-events: none; - } - } - - .animation-control-group { - position: relative; - display: flex; - flex-direction: column; - background-color: v.$select-bg; - - .select-label { - padding-top: 4px; - left: 0; - font-size: 9px; - color: v.$gray-600; - text-transform: uppercase; - pointer-events: none; - } - - .animation-controls { - display: flex; - flex-direction: row; - align-items: center; - padding-top: 3px; - padding-bottom: 3px; - gap: 4px; - border-bottom: 1px solid v.$gray-600; - - button { - all: unset; - padding: 2px; - cursor: pointer; - color: v.$gray-600; - font-size: 12px; - line-height: 1; - position: relative; - - i.material-icons { - font-size: 18px; - vertical-align: middle; - } - - &:hover { - color: v.$gray-400; - } - - &.active { - color: v.$active-color; - } - - @include m.tooltip-below(28px); - } - - .speed-display { - font-size: 12px; - width: 15px; - text-align: center; - color: v.$gray-700; - user-select: none; - padding-top: 0px; - } - } - } -} \ No newline at end of file diff --git a/src/app/canvas/overlaycontrols/overlaycontrols.component.spec.ts b/src/app/canvas/overlaycontrols/overlaycontrols.component.spec.ts deleted file mode 100644 index ca66138..0000000 --- a/src/app/canvas/overlaycontrols/overlaycontrols.component.spec.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { OverlayControlsComponent } from './overlaycontrols.component'; - -describe('OverlaycontrolsComponent', () => { - let component: OverlayControlsComponent; - let fixture: ComponentFixture; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - imports: [OverlayControlsComponent] - }) - .compileComponents(); - - fixture = TestBed.createComponent(OverlayControlsComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/src/app/canvas/overlaycontrols/overlaycontrols.component.ts b/src/app/canvas/overlaycontrols/overlaycontrols.component.ts deleted file mode 100644 index 77fec6b..0000000 --- a/src/app/canvas/overlaycontrols/overlaycontrols.component.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { Component, Input, Output, EventEmitter } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { FormsModule } from '@angular/forms'; - -@Component({ - selector: 'app-overlaycontrols', - imports: [CommonModule, FormsModule], - templateUrl: './overlaycontrols.component.html', - styleUrls: ['./overlaycontrols.component.scss'] -}) -export class OverlayControlsComponent { - @Input() collisionAvoidance!: boolean; - @Input() aggregated!: boolean; - @Input() selectionMode!: boolean; - @Input() magicLenseStatus!: boolean; - @Input() showSettings!: boolean; - - @Input() timestamps: string[] = []; - @Input() selectedTimestamp!: string; - - @Input() algorithms: string[] = []; - @Input() selectedAlgorithm!: string; - - @Input() contexts: string[] = []; - @Input() selectedContext!: string; - - @Output() fitToView = new EventEmitter(); - @Output() toggleCollision = new EventEmitter(); - @Output() toggleAggregation = new EventEmitter(); - @Output() toggleSelection = new EventEmitter(); - @Output() toggleLens = new EventEmitter(); - @Output() toggleSettingsPanel = new EventEmitter(); - @Output() changeAnimationSpeed = new EventEmitter(); - @Output() togglePlayback = new EventEmitter(); - - @Output() settingsChanged = new EventEmitter<{ - timestamp: string; - algorithm: string; - context: string; - }>(); - - animationSpeed = 10; - paused = true; - - emitSettingsChange() { - this.settingsChanged.emit({ - timestamp: this.selectedTimestamp, - algorithm: this.selectedAlgorithm, - context: this.selectedContext - }); - this.paused = false; - } - - increaseSpeed() { - if (this.animationSpeed < 10) { - this.animationSpeed++; - this.changeAnimationSpeed.emit(this.animationSpeed / 1000); - } - } - - decreaseSpeed() { - if (this.animationSpeed > 1) { - this.animationSpeed--; - this.changeAnimationSpeed.emit(this.animationSpeed / 1000); - } - } - - togglePaused() { - this.paused = !this.paused; - this.togglePlayback.emit(); - } -} \ No newline at end of file diff --git a/src/app/canvas/services/canvas-camera.service.ts b/src/app/canvas/services/canvas-camera.service.ts new file mode 100644 index 0000000..ecceda1 --- /dev/null +++ b/src/app/canvas/services/canvas-camera.service.ts @@ -0,0 +1,175 @@ +import { Injectable } from '@angular/core'; +import * as THREE from 'three'; +import { ZoomLevel } from '../../shared/enum/zoom-level'; +import { panCamera } from '../../shared/helpers/three-helper'; +import { FIT_ANIMATION_DURATION_MS, FIT_MARGIN_FACTOR } from '../../shared/constants/canvas-constants'; + +@Injectable() +export class CanvasCameraService { + camera!: THREE.OrthographicCamera; + target = new THREE.Vector3(0, 0, 0); + + // Fit animation state + fitAnimationStartTime: number | null = null; + fitStartZoom!: number; + private fitEndZoom!: number; + private fitStartPosition!: THREE.Vector3; + private fitEndPosition!: THREE.Vector3; + private fitStartTarget!: THREE.Vector3; + private fitEndTarget!: THREE.Vector3; + private fitDuration = FIT_ANIMATION_DURATION_MS; + + // Navigation + isPanning = false; + zoomFactor = 1.1; + + // Touch + lastTouchPosition: { x: number; y: number } | null = { x: 0, y: 0 }; + touchZoomStartDistance: number | null = null; + lastZoom: number | null = null; + private touchCenter = { x: 0, y: 0 }; + + // View rect (for clipping) + viewRect = { left: 0, right: 0, top: 0, bottom: 0 }; + lastViewRect = { left: 0, right: 0, top: 0, bottom: 0 }; + + initCamera(width: number, height: number): void { + this.camera = new THREE.OrthographicCamera(-width / 2, width / 2, height / 2, -height / 2, 1, 1000); + this.camera.position.set(0, 0, 10); + this.camera.zoom = 1; + this.camera.updateProjectionMatrix(); + } + + updateCameraBounds(width: number, height: number): void { + this.camera.left = width / -2; + this.camera.right = width / 2; + this.camera.top = height / 2; + this.camera.bottom = height / -2; + this.camera.updateProjectionMatrix(); + } + + updateViewRect(): void { + this.camera.updateMatrixWorld(); + const halfW = ((this.camera.right - this.camera.left) / this.camera.zoom) * 0.5; + const halfH = ((this.camera.top - this.camera.bottom) / this.camera.zoom) * 0.5; + this.viewRect.left = this.camera.position.x - halfW; + this.viewRect.right = this.camera.position.x + halfW; + this.viewRect.bottom = this.camera.position.y - halfH; + this.viewRect.top = this.camera.position.y + halfH; + } + + startFitAnimation(glyphGroup: THREE.Group): void { + const box = new THREE.Box3().setFromObject(glyphGroup); + const size = box.getSize(new THREE.Vector3()); + const center = box.getCenter(new THREE.Vector3()); + + const margin = FIT_MARGIN_FACTOR; + const widthWithMargin = size.x * margin; + const heightWithMargin = size.y * margin; + + const cameraWidth = this.camera.right - this.camera.left; + const cameraHeight = this.camera.top - this.camera.bottom; + + const zoomX = cameraWidth / widthWithMargin; + const zoomY = cameraHeight / heightWithMargin; + const requiredZoom = Math.min(zoomX, zoomY); + + const direction = new THREE.Vector3().subVectors(this.camera.position, this.target); + const newTarget = center.clone(); + const newPosition = center.clone().add(direction); + + this.fitStartPosition = this.camera.position.clone(); + this.fitEndPosition = newPosition; + this.fitStartTarget = this.target.clone(); + this.fitEndTarget = newTarget; + this.fitStartZoom = this.camera.zoom; + this.fitEndZoom = requiredZoom; + this.fitAnimationStartTime = performance.now(); + } + + /** Returns true if animation completed this frame */ + updateFitAnimation(glyphCount: number): boolean { + if (this.fitAnimationStartTime === null) return false; + + if (glyphCount > 5000) { + this.fitAnimationStartTime = null; + this.camera.position.copy(this.fitEndPosition); + this.target.copy(this.fitEndTarget); + this.camera.zoom = this.fitEndZoom; + this.camera.updateProjectionMatrix(); + this.camera.lookAt(this.target); + return true; + } + + const now = performance.now(); + const elapsed = now - this.fitAnimationStartTime; + const t = Math.min(elapsed / this.fitDuration, 1); + + // Easing function: easeInOutQuad + const easedT = t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t; + + const currentPosition = new THREE.Vector3().lerpVectors(this.fitStartPosition, this.fitEndPosition, easedT); + this.camera.position.copy(currentPosition); + + const currentTarget = new THREE.Vector3().lerpVectors(this.fitStartTarget, this.fitEndTarget, easedT); + this.target.copy(currentTarget); + + this.camera.zoom = THREE.MathUtils.lerp(this.fitStartZoom, this.fitEndZoom, easedT); + this.camera.updateProjectionMatrix(); + this.camera.lookAt(this.target); + + if (t === 1) { + this.fitAnimationStartTime = null; + return true; + } + return false; + } + + calculateZoomLevel(zoomLevel: number): ZoomLevel { + if (zoomLevel < 2) return ZoomLevel.low; + if (zoomLevel < 10) return ZoomLevel.medium; + return ZoomLevel.high; + } + + applyZoomAtScreenPoint( + screenX: number, + screenY: number, + newZoom: number, + oldZoom: number, + rendererElement: HTMLElement + ): void { + const rect = rendererElement.getBoundingClientRect(); + const xNDC = ((screenX - rect.left) / rect.width) * 2 - 1; + const yNDC = -((screenY - rect.top) / rect.height) * 2 + 1; + + const worldBefore = new THREE.Vector3(xNDC, yNDC, 0).unproject(this.camera); + this.camera.zoom = newZoom; + this.camera.updateProjectionMatrix(); + + const worldAfter = new THREE.Vector3(xNDC, yNDC, 0).unproject(this.camera); + const delta = worldBefore.sub(worldAfter); + + this.camera.position.x += delta.x; + this.camera.position.y += delta.y; + this.target.x += delta.x; + this.target.y += delta.y; + } + + pan(lastPos: THREE.Vector2, event: MouseEvent): void { + panCamera(this.camera, lastPos, event, this.target); + } + + getTouchDistance(event: TouchEvent): number { + const dx = event.touches[0].clientX - event.touches[1].clientX; + const dy = event.touches[0].clientY - event.touches[1].clientY; + return Math.sqrt(dx * dx + dy * dy); + } + + updateTouchCenter(event: TouchEvent, rendererElement: HTMLElement): void { + const rect = rendererElement.getBoundingClientRect(); + const cx = (event.touches[0].clientX + event.touches[1].clientX) / 2; + const cy = (event.touches[0].clientY + event.touches[1].clientY) / 2; + this.touchCenter.x = ((cx - rect.left) / rect.width) * 2 - 1; + this.touchCenter.y = -((cy - rect.top) / rect.height) * 2 + 1; + } +} diff --git a/src/app/canvas/services/canvas-renderer.service.ts b/src/app/canvas/services/canvas-renderer.service.ts new file mode 100644 index 0000000..421da44 --- /dev/null +++ b/src/app/canvas/services/canvas-renderer.service.ts @@ -0,0 +1,488 @@ +import { Injectable } from '@angular/core'; +import * as THREE from 'three'; +import { GlyphObject } from '../../glyph/glyph-object'; +import { GlyphSizeInfo } from '../../glyph/glyph-size-info'; +import { RenderTask } from '../../shared/enum/render-task'; +import { SpatialGrid } from '../../shared/helpers/spatial-grid'; +import { ZoomLevel } from '../../shared/enum/zoom-level'; +import { + hitTest, + hitTestCandidates, + nearlyEqual, + scalePosition, + screenToWorld, +} from '../../shared/helpers/three-helper'; +import { LENS_ENLARGEMENT_FACTOR } from '../../shared/constants/canvas-constants'; +import { GlyphRenderConfig } from '../../glyph/glyph-render-config'; + +// Reusable scratch vector to avoid per-frame allocations +const _tempVec3 = new THREE.Vector3(); + +@Injectable() +export class CanvasRendererService { + scene!: THREE.Scene; + renderer!: THREE.WebGLRenderer; + glyphGroup = new THREE.Group(); + + sizeInfo = new GlyphSizeInfo(); + positionBounds: { minX: number; maxX: number; minY: number; maxY: number } | undefined; + + // Spatial grid + spatialGrid = new SpatialGrid(100); + spatialGridDirty = true; + + // Render task management + needsRender = new Set(); + private onRenderRequested?: () => void; + + // Background colors + readonly standardBackgroundColor = new THREE.Color(0xffffff); + readonly disabledBackgroundColor = new THREE.Color(0xf0f0f0); + + // Clipping + private clippingFrameCounter = 0; + + // Render throttling to prevent cascading re-renders + private lastRenderTime = 0; + private pendingRender: ReturnType | null = null; + private readonly MIN_RENDER_INTERVAL_MS = 50; + + setRenderRequestCallback(fn: () => void): void { + this.onRenderRequested = fn; + } + + initRenderer(container: HTMLElement, width: number, height: number): void { + this.scene = new THREE.Scene(); + this.scene.background = this.standardBackgroundColor; + + this.renderer = new THREE.WebGLRenderer({ antialias: true }); + this.renderer.setPixelRatio(window.devicePixelRatio || 1); + this.renderer.domElement.style.width = '100%'; + this.renderer.domElement.style.height = '100%'; + this.renderer.domElement.style.display = 'block'; + + this.scene.add(this.glyphGroup); + container.appendChild(this.renderer.domElement); + + this.renderer.setSize(width, height, false); + this.sizeInfo.update(width, height); + } + + updateRendererSize(width: number, height: number): void { + this.renderer.setSize(width, height, false); + this.sizeInfo.update(width, height); + } + + requestRender(task: RenderTask): void { + this.needsRender.add(task); + this.onRenderRequested?.(); + } + + cancelRender(task: RenderTask): void { + requestAnimationFrame(() => { + this.needsRender.delete(task); + }); + } + + renderGlyphs( + glyphData: GlyphObject[], + canvasId: number, + selectedTimestamp: string, + selectedAlgorithm: string, + aggregated: boolean, + renderConfig: GlyphRenderConfig, + force = false + ): void { + if (!this.scene) return; + + const now = performance.now(); + const elapsed = now - this.lastRenderTime; + + // Throttle: if called too rapidly, schedule a single trailing render + if (elapsed < this.MIN_RENDER_INTERVAL_MS && !force) { + if (!this.pendingRender) { + this.pendingRender = setTimeout(() => { + this.pendingRender = null; + this.doRenderGlyphs( + glyphData, + canvasId, + selectedTimestamp, + selectedAlgorithm, + aggregated, + renderConfig, + force + ); + }, this.MIN_RENDER_INTERVAL_MS - elapsed); + } + return; + } + + this.doRenderGlyphs(glyphData, canvasId, selectedTimestamp, selectedAlgorithm, aggregated, renderConfig, force); + } + + private doRenderGlyphs( + glyphData: GlyphObject[], + canvasId: number, + selectedTimestamp: string, + selectedAlgorithm: string, + aggregated: boolean, + renderConfig: GlyphRenderConfig, + force: boolean + ): void { + this.lastRenderTime = performance.now(); + + glyphData.forEach((glyph: GlyphObject) => { + const cacheObject = glyph.getCacheObject(canvasId, selectedTimestamp, selectedAlgorithm); + const oldMesh = cacheObject.mesh; + if (oldMesh) this.glyphGroup.remove(oldMesh); + if (cacheObject.visible || force) { + const mesh = glyph.render( + this.sizeInfo, + selectedTimestamp, + selectedAlgorithm, + canvasId, + aggregated, + renderConfig + ); + if (mesh != null) this.glyphGroup.add(mesh); + } + }); + + this.updatePositionBounds(glyphData, selectedTimestamp, selectedAlgorithm); + this.requestRender(RenderTask.SceneRender); + } + + renderGlyph( + glyph: GlyphObject, + selectedTimestamp: string, + selectedAlgorithm: string, + canvasId: number, + aggregated: boolean, + renderConfig: GlyphRenderConfig + ): void { + const mesh = glyph.getMesh(selectedTimestamp, selectedAlgorithm, canvasId); + if (mesh !== undefined) this.glyphGroup.remove(mesh); + + const newMesh = glyph.render( + this.sizeInfo, + selectedTimestamp, + selectedAlgorithm, + canvasId, + aggregated, + renderConfig + ); + if (newMesh) this.glyphGroup.add(newMesh); + + this.requestRender(RenderTask.SceneRender); + } + + updateClipping( + glyphData: GlyphObject[], + viewRect: { left: number; right: number; top: number; bottom: number }, + lastViewRect: { left: number; right: number; top: number; bottom: number }, + canvasId: number, + selectedTimestamp: string, + selectedAlgorithm: string, + aggregated: boolean, + renderConfig: GlyphRenderConfig + ): void { + // Throttle to 30fps (every 2nd frame) + this.clippingFrameCounter++; + if (this.clippingFrameCounter % 2 !== 0) return; + + const { left, right, bottom, top } = viewRect; + + // Skip if viewport hasn't changed significantly + const threshold = this.sizeInfo.radius * 0.5; + if ( + Math.abs(left - lastViewRect.left) < threshold && + Math.abs(right - lastViewRect.right) < threshold && + Math.abs(top - lastViewRect.top) < threshold && + Math.abs(bottom - lastViewRect.bottom) < threshold + ) + return; + + // Update cached viewport + lastViewRect.left = left; + lastViewRect.right = right; + lastViewRect.top = top; + lastViewRect.bottom = bottom; + + const r = this.sizeInfo.radius; + + // Use spatial grid for efficient viewport culling if available + if (this.spatialGrid.size > 0 && glyphData.length > 500) { + const visibleGlyphs = this.spatialGrid.queryRect(left - r, right + r, bottom - r, top + r); + + for (const glyph of glyphData) { + const cachedObject = glyph.getCacheObject(canvasId, selectedTimestamp, selectedAlgorithm); + if (!visibleGlyphs.has(glyph)) { + cachedObject.visible = false; + } + } + + for (const glyph of visibleGlyphs) { + const cachedObject = glyph.getCacheObject(canvasId, selectedTimestamp, selectedAlgorithm); + if (!cachedObject.visible) { + this.renderGlyph(glyph, selectedTimestamp, selectedAlgorithm, canvasId, aggregated, renderConfig); + } + cachedObject.visible = true; + } + } else { + glyphData.forEach(glyph => { + const cachedObject = glyph.getCacheObject(canvasId, selectedTimestamp, selectedAlgorithm); + const cachedMesh = cachedObject.mesh; + if (cachedMesh) { + const isVisible = + cachedMesh.position.x + r > left && + cachedMesh.position.x - r < right && + cachedMesh.position.y + r > bottom && + cachedMesh.position.y - r < top; + if (!cachedObject.visible && isVisible) { + this.renderGlyph(glyph, selectedTimestamp, selectedAlgorithm, canvasId, aggregated, renderConfig); + } + cachedObject.visible = isVisible; + } + }); + } + } + + scaleGroupToFit( + glyphData: GlyphObject[], + canvasId: number, + selectedTimestamp: string, + selectedAlgorithm: string, + canvasWidth: number, + canvasHeight: number + ): void { + glyphData.forEach(glyph => { + if (this.positionBounds === undefined) return; + + const cacheObject = glyph.getCacheObject(canvasId, selectedTimestamp, selectedAlgorithm); + const originalX = glyph.getPosition(selectedTimestamp, selectedAlgorithm).x ?? 0; + const originalY = glyph.getPosition(selectedTimestamp, selectedAlgorithm).y ?? 0; + + const { x: scaledX, y: scaledY } = scalePosition( + originalX, + originalY, + this.positionBounds!, // eslint-disable-line @typescript-eslint/no-non-null-assertion -- guarded by `if (this.positionBounds == undefined) return` above + canvasWidth, + canvasHeight + ); + + cacheObject.position.x = scaledX; + cacheObject.position.y = scaledY; + cacheObject.x = scaledX; + cacheObject.y = scaledY; + cacheObject.mesh?.position.set(scaledX, scaledY, 0); + }); + } + + /** Returns true when all glyphs have reached their original positions */ + animateBackToOriginal( + glyphData: GlyphObject[], + canvasId: number, + selectedTimestamp: string, + selectedAlgorithm: string, + animationSpeed: number + ): boolean { + let finished = true; + glyphData.forEach(glyph => { + const cachedObject = glyph.getCacheObject(canvasId, selectedTimestamp, selectedAlgorithm); + const target = cachedObject.position; + const mesh = cachedObject.mesh; + + if (mesh) { + const finalPosition = nearlyEqual(mesh.position.x, target.x) && nearlyEqual(mesh.position.y, target.y); + finished = finished && finalPosition; + mesh.position.lerp(_tempVec3.set(target.x, target.y, 0), animationSpeed); + } + }); + return finished; + } + + updatePositionBounds(glyphData: GlyphObject[], selectedTimestamp: string, selectedAlgorithm: string): void { + if (this.positionBounds === undefined && glyphData.length > 0) { + let minX = Infinity, + maxX = -Infinity; + let minY = Infinity, + maxY = -Infinity; + + for (const glyph of glyphData) { + const pos = glyph.getPosition(selectedTimestamp, selectedAlgorithm); + const x = pos.x ?? 0; + const y = pos.y ?? 0; + if (x < minX) minX = x; + if (x > maxX) maxX = x; + if (y < minY) minY = y; + if (y > maxY) maxY = y; + } + + this.positionBounds = { minX, maxX, minY, maxY }; + } + } + + rebuildSpatialGrid( + glyphData: GlyphObject[], + canvasId: number, + selectedTimestamp: string, + selectedAlgorithm: string + ): void { + this.spatialGrid.clear(); + + const count = glyphData.length; + if (count > 0 && this.positionBounds) { + const width = this.positionBounds.maxX - this.positionBounds.minX; + const height = this.positionBounds.maxY - this.positionBounds.minY; + const area = width * height; + const targetCellArea = area / (count / 100); + const cellSize = Math.max(50, Math.sqrt(targetCellArea)); + this.spatialGrid.setCellSize(cellSize); + } + + const radius = this.sizeInfo.radius; + for (const glyph of glyphData) { + const cacheObject = glyph.getCacheObject(canvasId, selectedTimestamp, selectedAlgorithm); + const x = cacheObject.position.x ?? 0; + const y = cacheObject.position.y ?? 0; + this.spatialGrid.insert(glyph, x, y, radius); + } + + this.spatialGridDirty = false; + } + + hideLensGlyphs(glyphs: GlyphObject[], canvasId: number, selectedTimestamp: string, selectedAlgorithm: string): void { + for (const glyph of glyphs) { + const mesh = glyph.getMesh(selectedTimestamp, selectedAlgorithm, canvasId); + if (mesh) mesh.visible = false; + } + this.requestRender(RenderTask.SceneRender); + } + + renderMagicLensGlyphs( + glyphs: GlyphObject[], + glyphData: GlyphObject[], + canvasId: number, + selectedTimestamp: string, + selectedAlgorithm: string, + aggregated: boolean, + renderConfig: GlyphRenderConfig + ): void { + const highlightedIds = new Set(glyphs.map(g => g.id)); + + // Reset unhighlighted glyphs to their original positions + for (const glyph of glyphData) { + if (highlightedIds.has(glyph.id)) continue; + const node = glyph.getCacheObject(canvasId, selectedTimestamp, selectedAlgorithm); + node.x = node.position.x; + node.y = node.position.y; + node.vx = 0; + node.vy = 0; + node.mesh?.position.set(node.position.x, node.position.y, 0); + } + + if (glyphs.length > 1) { + const nodes: { x: number; y: number; mesh: THREE.Object3D | undefined }[] = []; + glyphs.forEach(glyph => { + const cache = glyph.getCacheObject(canvasId, selectedTimestamp, selectedAlgorithm); + nodes.push({ x: cache.position.x, y: cache.position.y, mesh: cache.mesh }); + }); + + // Simple iterative collision resolution + const enlargedRadius = this.sizeInfo.getRadius(ZoomLevel.high) * LENS_ENLARGEMENT_FACTOR; + const minDist = enlargedRadius * 2; + + for (let iter = 0; iter < 5; iter++) { + for (let i = 0; i < nodes.length; i++) { + for (let j = i + 1; j < nodes.length; j++) { + const dx = nodes[j].x - nodes[i].x; + const dy = nodes[j].y - nodes[i].y; + const dist = Math.sqrt(dx * dx + dy * dy); + + if (dist < minDist && dist > 0) { + const overlap = (minDist - dist) / 2; + const nx = dx / dist; + const ny = dy / dist; + nodes[i].x -= nx * overlap; + nodes[i].y -= ny * overlap; + nodes[j].x += nx * overlap; + nodes[j].y += ny * overlap; + } + } + } + } + + nodes.forEach(node => { + node.mesh?.position.set(node.x, node.y, 0); + }); + } + + glyphs.forEach(glyph => { + const lensSize = this.sizeInfo.clone(); + lensSize.currentZoomLevel = ZoomLevel.high; + lensSize.radius = lensSize.radius * LENS_ENLARGEMENT_FACTOR; + + const mesh = glyph.getMesh(selectedTimestamp, selectedAlgorithm, canvasId); + if (mesh !== undefined) this.glyphGroup.remove(mesh); + const newMesh = glyph.render(lensSize, selectedTimestamp, selectedAlgorithm, canvasId, aggregated, renderConfig); + if (newMesh) this.glyphGroup.add(newMesh); + }); + + this.requestRender(RenderTask.SceneRender); + } + + optimizedHitTest( + event: MouseEvent, + glyphData: GlyphObject[], + camera: THREE.OrthographicCamera, + selectedTimestamp: string, + selectedAlgorithm: string, + canvasId: number + ): THREE.Object3D | null { + // For small datasets, use standard hit test (less overhead) + if (glyphData.length <= 500 || this.spatialGrid.size === 0) { + return hitTest(event, this.renderer, this.glyphGroup, camera, this.sizeInfo); + } + + // Convert screen to world coordinates + const worldPos = screenToWorld(event, this.renderer, camera); + const searchRadius = this.sizeInfo.radius * 3; + const nearbyGlyphs = this.spatialGrid.queryPoint(worldPos.x, worldPos.y, searchRadius); + + if (nearbyGlyphs.size === 0) return null; + + const candidates: THREE.Object3D[] = []; + for (const glyph of nearbyGlyphs) { + const mesh = glyph.getMesh(selectedTimestamp, selectedAlgorithm, canvasId); + if (mesh) candidates.push(mesh); + } + + return hitTestCandidates(event, this.renderer, candidates, camera, this.sizeInfo); + } + + dispose(): void { + this.scene?.traverse(obj => { + if ((obj as THREE.Mesh).geometry) { + (obj as THREE.Mesh).geometry.dispose(); + } + if ((obj as THREE.Mesh).material) { + const material = (obj as THREE.Mesh).material; + if (Array.isArray(material)) { + material.forEach(m => m.dispose()); + } else { + material.dispose(); + } + } + }); + + this.renderer?.forceContextLoss?.(); + if (this.renderer) { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- intentional cleanup to release DOM reference + this.renderer.domElement = null!; + this.renderer.dispose(); + } + this.glyphGroup.clear(); + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- intentional cleanup to release scene reference + this.scene = null!; + } +} diff --git a/src/app/canvas/services/canvas-selection.service.ts b/src/app/canvas/services/canvas-selection.service.ts new file mode 100644 index 0000000..a894db4 --- /dev/null +++ b/src/app/canvas/services/canvas-selection.service.ts @@ -0,0 +1,112 @@ +import { Injectable } from '@angular/core'; +import * as THREE from 'three'; +import { GlyphObject } from '../../glyph/glyph-object'; +import { ItemFilter } from '../../shared/filter/item-filter'; +import { IdFilter } from '../../shared/filter/id-filter'; +import { FilterMode } from '../../shared/enum/filter-mode'; +import { FilterService } from '../../services/filter.service'; +import { ConfigService } from '../../services/config.service'; +import { convertToScreenSpace } from '../../shared/helpers/three-helper'; + +@Injectable() +export class CanvasSelectionService { + selectionStart = new THREE.Vector2(); + selectionEnd = new THREE.Vector2(); + selectionFilter: ItemFilter = new IdFilter(); + selectionMode = false; + isShiftDown = false; + isSelecting = false; + selectionBox = { left: 0, top: 0, width: 0, height: 0 }; + + constructor( + private filterService: FilterService, + private config: ConfigService + ) {} + + /** Returns the new selectionMode state */ + toggleSelectionMode(doToggle = true): boolean { + this.selectionMode = !this.selectionMode && doToggle; + return this.selectionMode; + } + + updateSelectionBox(): void { + const x = Math.min(this.selectionStart.x, this.selectionEnd.x); + const y = Math.min(this.selectionStart.y, this.selectionEnd.y); + const w = Math.abs(this.selectionEnd.x - this.selectionStart.x); + const h = Math.abs(this.selectionEnd.y - this.selectionStart.y); + this.selectionBox = { left: x, top: y, width: w, height: h }; + } + + selectObjectsInRectangle( + glyphGroup: THREE.Group, + camera: THREE.OrthographicCamera, + rendererElement: HTMLCanvasElement, + glyphData: GlyphObject[], + canvasId: number, + selectedTimestamp: string, + selectedAlgorithm: string + ): void { + this.selectionBox = { left: 0, top: 0, width: 0, height: 0 }; + + const x1 = Math.min(this.selectionStart.x, this.selectionEnd.x); + const y1 = Math.min(this.selectionStart.y, this.selectionEnd.y); + const x2 = Math.max(this.selectionStart.x, this.selectionEnd.x); + const y2 = Math.max(this.selectionStart.y, this.selectionEnd.y); + + const contained: THREE.Object3D[] = []; + glyphGroup.children.forEach(obj => { + const screen = convertToScreenSpace(obj, camera, rendererElement); + if (screen.x >= x1 && screen.x <= x2 && screen.y >= y1 && screen.y <= y2) { + contained.push(obj); + } + }); + + this.highlightSelectedObjects( + contained, + glyphData, + canvasId, + selectedTimestamp, + selectedAlgorithm, + !this.isShiftDown + ); + } + + highlightSelectedObjects( + selectedObjects: THREE.Object3D[], + glyphData: GlyphObject[], + canvasId: number, + selectedTimestamp: string, + selectedAlgorithm: string, + replace = false + ): void { + if (selectedObjects.length === 0) { + this.filterService.clearIdFilters(); + } else { + if (replace) this.filterService.clearIdFilters(); + for (const glyph of glyphData) { + const cache = glyph.getCacheObject(canvasId, selectedTimestamp, selectedAlgorithm); + const obj = cache.mesh; + if (obj && selectedObjects.includes(obj)) { + (this.selectionFilter as IdFilter).add(glyph.id); + } + } + } + this.applyFilters(); + } + + applyFilters(): void { + this.selectionFilter.filterMode = FilterMode.Or; + this.filterService.ensureFilter(this.selectionFilter); + this.filterService.refreshFilters(); + this.config.redraw(); + } + + isMouseOverOverlay(event: MouseEvent): boolean { + const el = document.elementFromPoint(event.clientX, event.clientY); + return ( + el?.closest('.settings-panel') !== null || + el?.closest('.tooltip-popup') !== null || + el?.closest('.nav-controls-panel') !== null + ); + } +} diff --git a/src/app/canvas/settingscontrols/settingscontrols.component.html b/src/app/canvas/settingscontrols/settingscontrols.component.html index 3aba607..0d15367 100644 --- a/src/app/canvas/settingscontrols/settingscontrols.component.html +++ b/src/app/canvas/settingscontrols/settingscontrols.component.html @@ -1,96 +1,127 @@ -
- -
- - - - - +
+
+ + Pos: + {{ selectedAlgorithm }} + + + @if (colorFeatureLabel) { + + Color: + {{ colorFeatureLabel }} + + + } + + + Glyph: + {{ glyphTypeName }} + + + @if (selectedTimestamp) { + + Time: + {{ selectedTimestamp }} + + }
-
- - -
- -
- - -
+ + @if (activeSetting === 'position') { +
+
- - + @for (t of timestamps; track t) { + + }
- - + @for (algo of algorithms; track algo) { + + }
-
- -
-
-
- {{ proj.method }} - - - sync - check_circle - error - schedule - - -
-
-
-
+ @if (backgroundProjections.length > 0) { +
+ +
+ @for (proj of backgroundProjections; track proj.method) { +
+
+ {{ proj.method }} + + @switch (proj.status) { + @case ('running') { + sync + } + @case ('complete') { + check_circle + } + @case ('error') { + error + } + @case ('pending') { + schedule + } + } + +
+ @if (proj.status === 'running') { +
+
+
+ } +
+ }
-
+ }
- +
-
+
{{ animationSpeed }}
-
- -
- - - - - -
- - -
- - -
- - -
-
- - -
- - - -
-
- -
- -
- - - - -
- {{ group.group }} -
- - -
- - -
- - - -
-
- -
- - -
- -
- -
- -
-
- -
- -
- - - - -
- - -
- - - - -
- -
- -
- -
- -
-
- -
- - -
-
\ No newline at end of file +
+ } +
diff --git a/src/app/canvas/settingscontrols/settingscontrols.component.scss b/src/app/canvas/settingscontrols/settingscontrols.component.scss index 68f9abd..b144c88 100644 --- a/src/app/canvas/settingscontrols/settingscontrols.component.scss +++ b/src/app/canvas/settingscontrols/settingscontrols.component.scss @@ -2,634 +2,348 @@ @use '../../../styles/mixins' as m; .settings-panel { + width: 100%; + display: flex; + align-items: center; + gap: 8px; + padding: 8px 14px; + background-color: v.$gray-100; + border-bottom: 1px solid v.$gray-200; + z-index: 400; + box-sizing: border-box; + flex-shrink: 0; + position: relative; + + &.active { + background-color: v.$ui-active-bg; + border-bottom: 1px solid v.$ui-active-border; + } + + .settings-overlay { position: absolute; - top: 0; - left: 0; - width: 100%; - display: flex; - justify-content: space-between; - /* left and right aligned */ - align-items: center; - padding: 12px 14px; - /* extra horizontal padding to avoid clipping */ - background-color: v.$gray-100; - border-top: none; - border-bottom: 1px solid v.$gray-200; - /* dark blue bottom line */ - z-index: 400; - - box-sizing: border-box; - /* ensures padding is counted inside width */ - - /* Initially hidden */ - opacity: 0; - pointer-events: none; - transition: opacity 0.2s ease; - - &.active { - background-color: #e6f0ff; - border-bottom: 1px solid #b3d2ff; - } + top: 100%; + left: 14px; + margin-top: 4px; + background: v.$white; + border-radius: 10px; + box-shadow: v.$shadow-md; + z-index: 450; - .settings-overlay { - position: absolute; - top: 90%; - left: 14px; - /* align with left edge of white button group */ - margin-top: 4px; - background: white; - border-radius: 10px; - box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); - z-index: 450; - - .overlay-content { - padding: 12px; - min-width: 200px; - } + .overlay-content { + padding: 12px; + min-width: 200px; } + } } -.settings-panel.visible { - opacity: 1; - pointer-events: auto; - /* enable interaction */ +.header-info { + display: flex; + align-items: center; + gap: 16px; + flex: 1; + min-width: 0; + overflow: hidden; } -/* White button group on left */ -.settings-buttons { - display: flex; - gap: 4px; - background: white; - padding: 4px 8px; - border-radius: 10px; -} +.info-item { + display: inline-flex; + align-items: center; + gap: 4px; + white-space: nowrap; + font-size: 13px; -.setting-btn { - border: none; - border-radius: 8px; - background: white; + &.clickable { cursor: pointer; - padding: 6px 10px; - font-size: 14px; - transition: all 0.2s ease; - color: v.$gray-600; - - span { - color: v.$gray-500; - transition: all 0.2s ease; - } + border-radius: 4px; + padding: 2px 4px; + margin: -2px -4px; - &:hover:not(.active) { - background: #f0f4ff; + &:hover { + background: v.$hover-overlay; } &.active { - background: v.$color-blue-highlight; - color: white; - - span { - color: white; - } + background: v.$color-blue-highlight; + .info-label, + .info-value { + color: v.$white; + } } + } } -/* Right-aligned action buttons */ -.settings-actions { - display: flex; - gap: 2px; - - /* make sure buttons stay inside the panel */ - margin-right: 0; - /* remove any negative or large margin */ - flex-shrink: 0; - /* prevent shrinking when panel width is constrained */ - - .action-btn { - background: transparent; - border: none; - cursor: pointer; - color: v.$gray-600; - font-size: 20px; - padding: 4px; - - &:hover { - color: v.$color-blue-highlight; - } - - &:disabled { - opacity: 0.3; - cursor: auto; - pointer-events: none; - } - } +.info-label { + color: v.$gray-500; } -.position-menu { - display: flex; - flex-direction: column; - gap: 24px; - min-width: 260px; +.info-value { + color: v.$gray-800; + font-weight: 500; + overflow: hidden; + text-overflow: ellipsis; } -.form-group { - display: flex; - flex-direction: column; - gap: 8px; - margin-bottom: 12px; - - select { - appearance: none; - padding: 8px 12px; - border-radius: 8px; - border: 1px solid #d0d0d0; - background: white; - font-size: 13px; - cursor: pointer; - color: v.$gray-700; - - &:focus { - outline: none; - border-color: v.$color-blue-highlight; - } - } +.color-swatch { + display: inline-block; + width: 48px; + height: 10px; + border-radius: 2px; + flex-shrink: 0; + vertical-align: middle; } -.menu-label { - font-size: 10px; - font-weight: 500; - color: v.$gray-600; - letter-spacing: 0.06em; - text-transform: uppercase; -} - -/* Toggle buttons */ -.toggle-group.horizontal { - display: flex; - gap: 8px; - margin-top: 12px; - - .toggle-btn { - flex: 1; - /* equal width buttons */ - text-align: center; - /* better balance side-by-side */ - padding: 10px 8px; - } -} +.settings-actions { + display: flex; + gap: 2px; + flex-shrink: 0; -.toggle-btn { - width: 100%; - padding: 10px 12px; - border-radius: 10px; - border: 1px solid #d0d0d0; - background: white; - font-size: 13px; - text-align: left; + .action-btn { + background: transparent; + border: none; cursor: pointer; - transition: background-color 0.15s ease, border-color 0.15s ease; - color: v.$gray-700; + color: v.$gray-500; + font-size: 18px; + padding: 4px; &:hover { - border-color: #6aa9ff; + color: v.$gray-800; } - &.active { - background: v.$color-blue-highlight; - border-color: #6aa9ff; - color: white; + &:disabled { + opacity: 0.3; + cursor: auto; + pointer-events: none; } + } } -.animation-control-group { - display: flex; - flex-direction: column; - gap: 10px; +.form-group { + @include m.form-group; + margin-bottom: 12px; } -.animation-controls { - display: flex; - align-items: center; - gap: 6px; +.menu-label { + @include m.menu-label; } -/* Reusable icon button */ -.icon-btn { - width: 32px; - height: 32px; - border-radius: 8px; - border: 1px solid #d0d0d0; - background: white; - display: flex; - align-items: center; - justify-content: center; - cursor: pointer; - transition: - background-color 0.15s ease, - border-color 0.15s ease; - - i { - font-size: 18px; - color: #444; - } - - &:hover { - border-color: #6aa9ff; - } - - &.active { - background: #dbe9ff; - border-color: #6aa9ff; - - i { - color: v.$color-blue-highlight; - } - } -} +.toggle-group.horizontal { + display: flex; + gap: 8px; + margin-top: 12px; -.play-btn { + .toggle-btn { flex: 1; - /* ← fills remaining horizontal space */ - justify-content: center; - border-radius: 10px; - min-width: 56px; + text-align: center; + padding: 10px 8px; + } } -/* Speed display */ -.speed-display { - min-width: 36px; - height: 32px; - padding: 0 8px; - border-radius: 8px; - background: #f5f7fa; - border: 1px solid #e0e0e0; - display: flex; - align-items: center; - justify-content: center; - font-size: 13px; - font-weight: 500; - color: #444; +.toggle-btn { + width: 100%; + padding: 10px 12px; + border-radius: 10px; + border: 1px solid v.$ui-border-light; + background: v.$white; + font-size: 13px; + text-align: left; + cursor: pointer; + transition: + background-color 0.15s ease, + border-color 0.15s ease; + color: v.$gray-700; + + &:hover { + border-color: v.$ui-accent-blue; + } + + &.active { + background: v.$color-blue-highlight; + border-color: v.$ui-accent-blue; + color: v.$white; + } } -/* Checkbox row */ -.checkbox-row { - display: flex; - align-items: center; - gap: 8px; - font-size: 13px; - color: v.$gray-600; - cursor: pointer; - user-select: none; - margin-bottom: 14px; - - input[type="checkbox"] { - display: none; // hide native checkbox - } - - .custom-checkbox { - width: 14px; - height: 14px; - border-radius: 6px; - border: 1px solid #d0d0d0; - background: white; - display: inline-block; - position: relative; - transition: all 0.2s ease; - - /* center dot */ - &::after { - content: ''; - position: absolute; - top: 50%; - left: 50%; - width: 6px; - height: 6px; - background-color: white; - /* default invisible */ - border-radius: 50%; - transform: translate(-50%, -50%) scale(0); - transition: transform 0.2s ease, background-color 0.2s ease; - } - } - - input[type="checkbox"]:checked+.custom-checkbox { - background-color: v.$color-blue-highlight; - /* $color-blue-highlight */ - border-color: #1e88e5; - - &::after { - background-color: white; - /* the dot is white on blue */ - transform: translate(-50%, -50%) scale(1); - } - } - - .label-text { - user-select: none; - } +.animation-control-group { + display: flex; + flex-direction: column; + gap: 10px; } -/* Color scale selector */ -.color-scale-select { - position: relative; - cursor: pointer; - user-select: none; - - .selected-scale { - display: flex; - align-items: center; - gap: 4px; - padding: 6px 8px; - border-radius: 8px; - border: 1px solid #d0d0d0; - background: white; - - /* Custom arrow */ - &::after { - content: ""; - display: inline-block; - width: 16px; - height: 16px; - margin-left: auto; - background-image: url("data:image/svg+xml;utf8,"); - background-repeat: no-repeat; - background-position: center; - background-size: 16px 16px; - } - } - - .dropdown-icon { - margin-left: auto; - font-size: 20px; - color: #666; - } +.animation-controls { + display: flex; + align-items: center; + gap: 6px; +} - .color-scale-group-label { - font-size: 11px; - font-weight: 500; - color: #888; - padding: 4px 6px 2px; - text-transform: uppercase; - } +.icon-btn { + width: 32px; + height: 32px; + border-radius: 8px; + border: 1px solid v.$ui-border-light; + background: v.$white; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + transition: + background-color 0.15s ease, + border-color 0.15s ease; + + i { + font-size: 18px; + color: v.$gray-700; + } - .color-scale-group-divider { - height: 1px; - background: #e0e0e0; - margin: 6px 0; - } + &:hover { + border-color: v.$ui-accent-blue; + } - .color-scale-options { - position: absolute; - top: 100%; - left: 0; - width: 95%; - background: white; - border: 1px solid #d0d0d0; - border-radius: 8px; - margin-top: 4px; - z-index: 10; - display: flex; - flex-direction: column; - padding: 4px; - } + &.active { + background: v.$ui-active-pressed-bg; + border-color: v.$ui-accent-blue; - .color-scale-option { - display: flex; - gap: 4px; - padding: 4px; - border-radius: 6px; - - &:hover { - background: #f0f5ff; - } - - .color-box { - flex: 1; - /* ← each box fills equal space */ - height: 20px; - /* adjust as needed */ - border-radius: 4px; - } - - .color-gradient { - width: 100%; - height: 20px; - border-radius: 4px; - } + i { + color: v.$color-blue-highlight; } + } +} - .selected-scale .color-box { - flex: 1; - height: 20px; - border-radius: 4px; - } +.play-btn { + flex: 1; + justify-content: center; + border-radius: 10px; + min-width: 56px; +} - .selected-scale .color-gradient { - width: 100%; - height: 20px; - border-radius: 4px; - } +.speed-display { + min-width: 36px; + height: 32px; + padding: 0 8px; + border-radius: 8px; + background: v.$ui-bg-light; + border: 1px solid v.$gray-200; + display: flex; + align-items: center; + justify-content: center; + font-size: 13px; + font-weight: 500; + color: v.$gray-700; } /* Background projection status */ .projection-status-list { - display: flex; - flex-direction: column; - gap: 6px; - max-height: 150px; - overflow-y: scroll; // Always show scrollbar area - overflow-x: hidden; - overscroll-behavior: contain; // Prevent scroll chaining to parent - -webkit-overflow-scrolling: touch; // Smooth scrolling on iOS - touch-action: pan-y; // Allow vertical touch/wheel scrolling - pointer-events: auto; // Ensure this element captures pointer events - - // Scrollbar styling - &::-webkit-scrollbar { - width: 6px; - } - - &::-webkit-scrollbar-track { - background: #f0f0f0; - border-radius: 3px; - } - - &::-webkit-scrollbar-thumb { - background: #ccc; - border-radius: 3px; - - &:hover { - background: #aaa; - } - } + display: flex; + flex-direction: column; + gap: 6px; + max-height: 150px; + overflow-y: scroll; + overflow-x: hidden; + overscroll-behavior: contain; + touch-action: pan-y; + pointer-events: auto; + @include m.styled-scrollbar-thin; } .projection-status-item { - display: flex; - flex-direction: column; - gap: 4px; - padding: 6px 8px; - border-radius: 6px; - background: #f5f7fa; - border: 1px solid #e0e0e0; - opacity: 1; - transition: opacity 0.5s ease-out; - - &.fading { - opacity: 0; - } - - &.status-running { - background: #fff8e6; - border-color: #ffd666; - } - - &.status-complete { - background: #e6f7e6; - border-color: #95de95; - } - - &.status-error { - background: #fee; - border-color: #faa; - } - - &.status-pending { - background: #f5f5f5; - border-color: #ddd; - } + display: flex; + flex-direction: column; + gap: 4px; + padding: 6px 8px; + border-radius: 6px; + background: v.$ui-bg-light; + border: 1px solid v.$gray-200; + opacity: 1; + transition: opacity 0.5s ease-out; + + &.fading { + opacity: 0; + } + + &.status-running { + background: v.$proj-running-bg; + border-color: v.$proj-running-border; + } + + &.status-complete { + background: v.$proj-complete-bg; + border-color: v.$proj-complete-border; + } + + &.status-error { + background: v.$proj-error-bg; + border-color: v.$proj-error-border; + } + + &.status-pending { + background: v.$gray-100; + border-color: v.$gray-200; + } } .status-row { - display: flex; - justify-content: space-between; - align-items: center; + display: flex; + justify-content: space-between; + align-items: center; } .method-name { - font-size: 12px; - font-weight: 500; - color: v.$gray-700; + font-size: 12px; + font-weight: 500; + color: v.$gray-700; } .status-indicator { - display: flex; - align-items: center; - - .material-icons { - font-size: 16px; - } + display: flex; + align-items: center; - &.running .material-icons { - color: #f5a623; - } - - &.complete .material-icons { - color: #52c41a; - } + .material-icons { + font-size: 16px; + } - &.error .material-icons { - color: #ff4d4f; - } + &.running .material-icons { + color: v.$proj-running; + } - &.pending .material-icons { - color: #999; - } -} + &.complete .material-icons { + color: v.$proj-complete; + } -.spinning { - animation: spin 1s linear infinite; -} + &.error .material-icons { + color: v.$proj-error; + } -@keyframes spin { - from { - transform: rotate(0deg); - } - to { - transform: rotate(360deg); - } + &.pending .material-icons { + color: v.$color-gray-border; + } } .progress-bar-mini { - height: 3px; - background: #e0e0e0; - border-radius: 2px; - overflow: hidden; - - // Indeterminate progress animation - &.indeterminate .progress-fill-mini { - width: 30% !important; - animation: indeterminate-progress 1.5s ease-in-out infinite; - } + height: 3px; + background: v.$gray-200; + border-radius: 2px; + overflow: hidden; + + &.indeterminate .progress-fill-mini { + width: 30% !important; + animation: indeterminate-progress 1.5s ease-in-out infinite; + } } @keyframes indeterminate-progress { - 0% { - transform: translateX(-100%); - } - 50% { - transform: translateX(200%); - } - 100% { - transform: translateX(-100%); - } + 0% { + transform: translateX(-100%); + } + 50% { + transform: translateX(200%); + } + 100% { + transform: translateX(-100%); + } } .progress-fill-mini { - height: 100%; - background: #f5a623; - border-radius: 2px; - transition: width 0.3s ease; + height: 100%; + background: v.$proj-running; + border-radius: 2px; + transition: width 0.3s ease; } - -.control-cell { - display: flex; - flex-wrap: wrap; - gap: 8px; - position: relative; - max-width: 260px; - - .dashboard-button { - width: 41px; - height: 41px; - display: inline-flex; - align-items: center; - justify-content: center; - background: transparent; - border: 1px solid #999; - cursor: pointer; - color: v.$gray-600; - font-size: 24px; - position: relative; - - &:focus-visible { - outline: none; - box-shadow: none; - } - - &:hover { - color: #000; - } - - &.active { - border-color: v.$color-blue-highlight; - color: v.$color-blue-highlight; - } - - @include m.tooltip-below(28px); - } - - .config-toggle { - padding: 8px 10px; - font-size: 11px; - background-color: #ccc; - border: none; - cursor: pointer; - border-radius: 0px; - transition: background-color 0.2s; - - &.active { - background-color: v.$color-blue-highlight; - color: white; - } - } -} \ No newline at end of file diff --git a/src/app/canvas/settingscontrols/settingscontrols.component.ts b/src/app/canvas/settingscontrols/settingscontrols.component.ts index 2ef7ac1..b66f16d 100644 --- a/src/app/canvas/settingscontrols/settingscontrols.component.ts +++ b/src/app/canvas/settingscontrols/settingscontrols.component.ts @@ -1,17 +1,14 @@ import { CommonModule } from '@angular/common'; -import { Component, EventEmitter, inject, Input, NgZone, OnDestroy, Output } from '@angular/core'; +import { Component, EventEmitter, inject, Input, NgZone, OnDestroy, Output, OnInit } from '@angular/core'; import { ConfigService } from '../../services/config.service'; import { FormsModule } from '@angular/forms'; -import { FeaturesData } from '../../shared/interfaces/glyph-meta'; -import { GlyphSchema } from '../../shared/interfaces/glyph-schema'; -import { DataProviderService } from '../../services/dataprovider.service'; +import { FilterService } from '../../services/filter.service'; import { ProjectionService } from '../../services/projection.service'; -import { COLOR_SCALES, ColorScale } from '../../shared/interfaces/color-scale'; -import { GlyphConfiguration } from '../../glyph/glyph-configuration'; -import { GlyphType } from '../../shared/enum/glyph-type'; import { Subscription } from 'rxjs'; +import { COLOR_SCALES, getContinuousGradient, getCategoricalColors } from '../../shared/interfaces/color-scale'; +import { getGlyphTypeName } from '../../shared/enum/glyph-type'; -export type SettingMode = 'position' | 'color' | 'glyph' | null; +export type SettingMode = 'position' | null; @Component({ selector: 'app-settingscontrols', @@ -20,44 +17,44 @@ export type SettingMode = 'position' | 'color' | 'glyph' | null; templateUrl: './settingscontrols.component.html', styleUrls: ['./settingscontrols.component.scss'], }) -export class SettingsControlPanelComponent implements OnDestroy { - @Input() visible = false; // controls fade in/out +export class SettingsControlPanelComponent implements OnDestroy, OnInit { + @Input() visible = false; - colorScales: ColorScale[] = COLOR_SCALES; - - groupedColorScales: { - group: string; - scales: any[]; - }[] = []; + private readonly MAX_ANIMATION_SPEED = 10; + private readonly MIN_ANIMATION_SPEED = 1; + private readonly PROJECTION_FADE_DELAY_MS = 4500; + private readonly PROJECTION_REMOVE_DELAY_MS = 5000; panelActive = false; activeSetting: SettingMode = null; - animationSpeed = 10; + animationSpeed = this.MAX_ANIMATION_SPEED; paused = true; - applyColorToAll = true; - features: FeaturesData = {}; - featureIds: string[] = []; - schema?: GlyphSchema; - selectedColorAttribute: string = ''; - colorScaleDropdownOpen = false; - selectedColorScaleId = COLOR_SCALES[0].id; + // Color info + colorFeatureLabel = ''; + colorGradientStyle = ''; - glyphConfig = new GlyphConfiguration(); - GlyphType = GlyphType; - applyGlyphSettingsToAll = true; + // Glyph type + glyphTypeName = ''; // Background projection status - backgroundProjections: Array<{ method: string; status: string; progress: number; message: string; fading?: boolean }> = []; + backgroundProjections: { + method: string; + status: string; + progress: number; + message: string; + fading?: boolean; + }[] = []; private backgroundStatusSubscription?: Subscription; private completedProjectionTimers = new Map>(); - private fadingTimers = new Map>(); // Timers for fade-out animation - private dismissedProjections = new Set(); // Track projections that have been dismissed after completion + private fadingTimers = new Map>(); + private dismissedProjections = new Set(); private ngZone!: NgZone; + private subs = new Subscription(); @Input() parentId!: number; - @Input() totalCells: number = 0; + @Input() totalCells = 0; @Input() collisionAvoidance!: boolean; @Input() aggregated!: boolean; @@ -87,25 +84,41 @@ export class SettingsControlPanelComponent implements OnDestroy { constructor( private config: ConfigService, - private dataProvider: DataProviderService, + private filterService: FilterService, private projectionService: ProjectionService ) { this.ngZone = inject(NgZone); } ngOnInit(): void { - this.groupedColorScales = this.groupColorScales(this.colorScales); + // Color info: update when data loads or config changes + this.subs.add( + this.config.loadedDataSubject$.subscribe(data => { + if (data === '') return; + this.updateColorInfo(); + }) + ); + + this.subs.add( + this.config.glyphConfigSubject$.subscribe(() => { + this.updateColorInfo(); + this.updateGlyphTypeName(); + }) + ); // Subscribe to background projection status updates - // Show running/pending projections, and completed ones for 5 seconds before fading out this.backgroundStatusSubscription = this.projectionService.backgroundStatusObservable.subscribe(statusMap => { this.ngZone.run(() => { - const newProjections: Array<{ method: string; status: string; progress: number; message: string; fading?: boolean }> = []; + const newProjections: { + method: string; + status: string; + progress: number; + message: string; + fading?: boolean; + }[] = []; statusMap.forEach((status, method) => { - // Show running, pending, or complete projections if (status.status === 'running' || status.status === 'pending') { - // Clear any existing timers for this method (it's running again) if (this.completedProjectionTimers.has(method)) { clearTimeout(this.completedProjectionTimers.get(method)); this.completedProjectionTimers.delete(method); @@ -114,99 +127,93 @@ export class SettingsControlPanelComponent implements OnDestroy { clearTimeout(this.fadingTimers.get(method)); this.fadingTimers.delete(method); } - // Clear dismissed status if projection is running again this.dismissedProjections.delete(method); newProjections.push({ method, status: status.status, progress: status.progress, - message: status.message + message: status.message, }); } else if (status.status === 'complete') { - // Check if we already have a timer for this completed projection if (!this.completedProjectionTimers.has(method)) { - // Start fade-out after 4.5 seconds, then remove after 5 seconds const fadeTimer = setTimeout(() => { this.ngZone.run(() => { - // Set fading flag to trigger CSS transition const proj = this.backgroundProjections.find(p => p.method === method); if (proj) { proj.fading = true; } }); - }, 4500); + }, this.PROJECTION_FADE_DELAY_MS); const removeTimer = setTimeout(() => { this.ngZone.run(() => { this.completedProjectionTimers.delete(method); this.fadingTimers.delete(method); - // Mark this method as dismissed so we don't show it again this.dismissedProjections.add(method); - // Trigger a re-render by filtering out this method this.backgroundProjections = this.backgroundProjections.filter(p => p.method !== method); }); - }, 5000); + }, this.PROJECTION_REMOVE_DELAY_MS); this.completedProjectionTimers.set(method, removeTimer); this.fadingTimers.set(method, fadeTimer); } - // Only show completed projection if it hasn't been dismissed if (!this.dismissedProjections.has(method)) { newProjections.push({ method, status: status.status, progress: 100, message: status.message, - fading: false + fading: false, }); } } - // Don't show error projections (they disappear immediately) }); this.backgroundProjections = newProjections; }); }); - - this.config.loadedDataSubject$.subscribe(async data => { - if (data == "") return; - - const metaData = await this.dataProvider.getMetaData(); - this.schema = await this.dataProvider.getSchema(); - if (metaData?.features) { - this.ngZone.run(() => { - this.features = metaData.features; - this.featureIds = Object.keys(this.features); - this.selectedColorAttribute = this.config.colorFeature; - // Sync color scale selection with config - this.selectedColorScaleId = this.config.colorRange; - }); - } - }); - - this.config.glyphConfigSubject$.subscribe(cfg => { - this.glyphConfig = cfg; - // Sync color scale and color feature selection when config changes (e.g., from another canvas) - if (this.selectedColorScaleId !== this.config.colorRange) { - this.selectedColorScaleId = this.config.colorRange; - } - if (this.selectedColorAttribute !== this.config.colorFeature) { - this.selectedColorAttribute = this.config.colorFeature; - } - }); } ngOnDestroy(): void { + this.subs.unsubscribe(); if (this.backgroundStatusSubscription) { this.backgroundStatusSubscription.unsubscribe(); } - // Clear all timers this.completedProjectionTimers.forEach(timer => clearTimeout(timer)); this.completedProjectionTimers.clear(); this.fadingTimers.forEach(timer => clearTimeout(timer)); this.fadingTimers.clear(); } + private updateColorInfo(): void { + const colorFeature = this.config.colorFeature; + const colorRange = this.config.colorRange; + const featureLabels = this.config.featureLabels; + + if (!colorFeature) { + this.colorFeatureLabel = ''; + this.colorGradientStyle = ''; + return; + } + + const colorScale = COLOR_SCALES.find(cs => cs.id === colorRange) || COLOR_SCALES[0]; + + let gradient: string; + if (colorScale.type === 'categorical') { + const colors = getCategoricalColors(colorScale); + gradient = `linear-gradient(to right, ${colors.map((c, i) => `${c} ${(i / colors.length) * 100}%, ${c} ${((i + 1) / colors.length) * 100}%`).join(', ')})`; + } else { + gradient = getContinuousGradient(colorScale); + } + + this.colorFeatureLabel = featureLabels[colorFeature] || colorFeature; + this.colorGradientStyle = gradient; + } + + private updateGlyphTypeName(): void { + this.glyphTypeName = getGlyphTypeName(this.config.getConfiguration().glyphType); + } + hideMenus() { this.activeSetting = null; } @@ -233,7 +240,7 @@ export class SettingsControlPanelComponent implements OnDestroy { } clearSelection() { - this.dataProvider.clearFilters(); + this.filterService.clearFilters(); this.config.clearSelection(); } @@ -241,20 +248,20 @@ export class SettingsControlPanelComponent implements OnDestroy { this.settingsChanged.emit({ timestamp: this.selectedTimestamp, algorithm: this.selectedAlgorithm, - context: this.selectedContext + context: this.selectedContext, }); this.paused = false; } increaseSpeed() { - if (this.animationSpeed < 10) { + if (this.animationSpeed < this.MAX_ANIMATION_SPEED) { this.animationSpeed++; this.changeAnimationSpeed.emit(this.animationSpeed / 1000); } } decreaseSpeed() { - if (this.animationSpeed > 1) { + if (this.animationSpeed > this.MIN_ANIMATION_SPEED) { this.animationSpeed--; this.changeAnimationSpeed.emit(this.animationSpeed / 1000); } @@ -264,105 +271,4 @@ export class SettingsControlPanelComponent implements OnDestroy { this.paused = !this.paused; this.togglePlayback.emit(); } - - getFeatureName(id: string) { - return this.schema?.label[id] || ""; - } - - getGlyphName(glyph: GlyphType): string { - switch (glyph) { - case GlyphType.Star: return "Star"; - case GlyphType.Flower: return "Flower"; - case GlyphType.Whisker: return "Whisker"; - case GlyphType.Dot: return "Dot"; - case GlyphType.Thumb: return "Thumbnail"; - default: return "Unknown"; - } - } - - private groupColorScales(scales: any[]) { - const map = new Map(); - - for (const scale of scales) { - const group = scale.group ?? 'Other'; - if (!map.has(group)) { - map.set(group, []); - } - map.get(group)!.push(scale); - } - - return Array.from(map.entries()).map(([group, scales]) => ({ - group, - scales - })); - } - - getContinuousGradient(scale: any, steps = 10): string { - const domain = scale.scale.domain(); - const min = domain[0]; - const max = domain[domain.length - 1]; - - const colors: string[] = []; - - for (let i = 0; i < steps; i++) { - const t = i / (steps - 1); - const value = min + t * (max - min); - colors.push(scale.scale(value)); - } - - return `linear-gradient(to right, ${colors.join(', ')})`; - } - - getCategoricalColors(scaleDef: any): string[] { - const scale = scaleDef.scale; - - // Ordinal / Quantize / Quantile scales - if (typeof scale.range === 'function') { - return scale.range(); - } - - return []; - } - - selectColorScale(id: number) { - this.selectedColorScaleId = id; - this.colorScaleDropdownOpen = false; - this.config.colorRange = id; - this.config.updateConfiguration(); - } - - toggleColorScaleDropdown() { - this.colorScaleDropdownOpen = !this.colorScaleDropdownOpen; - } - - getSelectedScale(): ColorScale { - return this.colorScales.find(s => s.id === this.selectedColorScaleId)!; - } - - selectColor(): void { - this.config.colorFeature = this.selectedColorAttribute; - - const featureType = this.schema?.types[this.selectedColorAttribute]; - const colorScaleType = this.getSelectedScale().type; - - if ( featureType != colorScaleType ) { - const matchingScale = this.colorScales.find(s => s.type == featureType)?.id; - if (matchingScale != undefined) this.selectColorScale(matchingScale); - } - this.config.updateConfiguration(); - } - - setGlyphType(type: GlyphType) { - this.glyphConfig.glyphType = type; - this.config.updateConfiguration(); - } - - isOptionEnabled(prop: string): boolean { - return (this.glyphConfig as any)[prop] === true; - } - - toggleOption(property: string): void { - (this.glyphConfig as any)[property] = !(this.glyphConfig as any)[property]; - this.config.updateConfiguration(); // emit change - } } diff --git a/src/app/canvas/tooltip/tooltip.component.html b/src/app/canvas/tooltip/tooltip.component.html index 4e8d7dd..9a73217 100644 --- a/src/app/canvas/tooltip/tooltip.component.html +++ b/src/app/canvas/tooltip/tooltip.component.html @@ -1,9 +1,8 @@
-
\ No newline at end of file +>
diff --git a/src/app/canvas/tooltip/tooltip.component.scss b/src/app/canvas/tooltip/tooltip.component.scss index 0be7ad4..0f864b4 100644 --- a/src/app/canvas/tooltip/tooltip.component.scss +++ b/src/app/canvas/tooltip/tooltip.component.scss @@ -1,3 +1,5 @@ +@use '../../../styles/mixins' as m; + .tooltip { position: fixed; background: rgba(0, 0, 0, 0.75); @@ -14,29 +16,9 @@ max-height: 600px; overflow-wrap: break-word; overflow-y: auto; - - // Dark scrollbar styling for all browsers - scrollbar-width: thin; - scrollbar-color: rgba(255, 255, 255, 0.4) transparent; - - &::-webkit-scrollbar { - width: 6px; - } - - &::-webkit-scrollbar-track { - background: transparent; - } - - &::-webkit-scrollbar-thumb { - background: rgba(255, 255, 255, 0.4); - border-radius: 3px; - - &:hover { - background: rgba(255, 255, 255, 0.6); - } - } + @include m.styled-scrollbar-dark; &.fixed { background: rgba(0, 0, 0, 1); } -} \ No newline at end of file +} diff --git a/src/app/canvas/tooltip/tooltip.component.spec.ts b/src/app/canvas/tooltip/tooltip.component.spec.ts deleted file mode 100644 index a5425da..0000000 --- a/src/app/canvas/tooltip/tooltip.component.spec.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { TooltipComponent } from './tooltip.component'; - -describe('TooltipComponent', () => { - let component: TooltipComponent; - let fixture: ComponentFixture; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - imports: [TooltipComponent] - }) - .compileComponents(); - - fixture = TestBed.createComponent(TooltipComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/src/app/canvas/tooltip/tooltip.component.ts b/src/app/canvas/tooltip/tooltip.component.ts index cb22e0c..234e153 100644 --- a/src/app/canvas/tooltip/tooltip.component.ts +++ b/src/app/canvas/tooltip/tooltip.component.ts @@ -9,13 +9,13 @@ import { Subscription } from 'rxjs'; selector: 'app-tooltip', imports: [], templateUrl: './tooltip.component.html', - styleUrl: './tooltip.component.scss' + styleUrl: './tooltip.component.scss', }) export class TooltipComponent implements OnInit, OnDestroy { @Input() container!: HTMLElement; @ViewChild('tooltip') tooltipRef!: ElementRef; - private hoverTimeout: any = null; + private hoverTimeout: ReturnType | undefined; private subscription = new Subscription(); tooltipVisible = false; tooltipFixed = false; @@ -23,7 +23,10 @@ export class TooltipComponent implements OnInit, OnDestroy { tooltipX = 0; tooltipY = 0; - constructor(private config: ConfigService, private sanitizer: DomSanitizer) { } + constructor( + private config: ConfigService, + private sanitizer: DomSanitizer + ) {} ngOnInit(): void { // Subscribe to modal state changes to hide fixed tooltips when modal opens @@ -111,7 +114,7 @@ export class TooltipComponent implements OnInit, OnDestroy { return; } this.hoverTimeout = setTimeout(() => { - const info = this.getObjectInfo(object) + const info = this.getObjectInfo(object); this.showTooltip(x, y, info); }, 750); // Delay in ms } @@ -124,9 +127,9 @@ export class TooltipComponent implements OnInit, OnDestroy { toggleFixation(doToggle = true) { this.tooltipFixed = !this.tooltipFixed && doToggle; if (this.tooltipFixed) { - this.tooltipRef.nativeElement.classList.add("fixed"); + this.tooltipRef.nativeElement.classList.add('fixed'); } else { - this.tooltipRef.nativeElement.classList.remove("fixed"); + this.tooltipRef.nativeElement.classList.remove('fixed'); } } @@ -171,5 +174,4 @@ export class TooltipComponent implements OnInit, OnDestroy { return 'Unnamed object'; } - -} \ No newline at end of file +} diff --git a/src/app/glyph/glyph-cache-object.ts b/src/app/glyph/glyph-cache-object.ts index 2a86d2e..a8ca252 100644 --- a/src/app/glyph/glyph-cache-object.ts +++ b/src/app/glyph/glyph-cache-object.ts @@ -1,36 +1,35 @@ import { SimulationNodeDatum } from 'd3-force'; import { Coordinates } from '../shared/interfaces/coordinates'; -import { ZoomLevel } from '../shared/enum/zoom-level'; import { Object3D } from 'three'; export class GlyphCacheObject implements SimulationNodeDatum { - id: string; - position: Coordinates; - index?: number | undefined; - x?: number | undefined; - y?: number | undefined; - vx?: number | undefined; - vy?: number | undefined; - fx?: number | null | undefined; - fy?: number | null | undefined; - visible = true; - isClustered = false; - isClusterRepresentative = false; + id: string; + position: Coordinates; + index?: number | undefined; + x?: number | undefined; + y?: number | undefined; + vx?: number | undefined; + vy?: number | undefined; + fx?: number | null | undefined; + fy?: number | null | undefined; + visible = true; + isClustered = false; + isClusterRepresentative = false; - private _cachedMesh: Object3D | undefined = undefined; + private _cachedMesh: Object3D | undefined = undefined; - constructor(id: string, position: Coordinates) { - this.id = id; - this.position = position; - this.x = position.x; - this.y = position.y; - } + constructor(id: string, position: Coordinates) { + this.id = id; + this.position = position; + this.x = position.x; + this.y = position.y; + } - get mesh() : Object3D | undefined { - return this._cachedMesh; - } + get mesh(): Object3D | undefined { + return this._cachedMesh; + } - set mesh(mesh: Object3D) { - this._cachedMesh = mesh; - } -} \ No newline at end of file + set mesh(mesh: Object3D) { + this._cachedMesh = mesh; + } +} diff --git a/src/app/glyph/glyph-configuration.ts b/src/app/glyph/glyph-configuration.ts index f87ffb7..7a4c692 100644 --- a/src/app/glyph/glyph-configuration.ts +++ b/src/app/glyph/glyph-configuration.ts @@ -1,4 +1,9 @@ -import { GlyphType } from "../shared/enum/glyph-type"; +import { GlyphType } from '../shared/enum/glyph-type'; + +export interface GlyphOption { + property: string; + label: string; +} export class GlyphConfiguration { private _useCoordinateSystem = true; @@ -7,44 +12,76 @@ export class GlyphConfiguration { private _useLabels = true; private _useContour = true; private _radius = 0; - private _accessors: any[] = []; private _scaleLinear = false; private _glyphType: GlyphType = GlyphType.Star; - private options = [ + private options: GlyphOption[] = [ { property: 'useCoordinateSystem', label: 'Coordinate System' }, { property: 'useBackground', label: 'Circle Background' }, - { property: 'useContour', label: 'Contour' } + { property: 'useContour', label: 'Contour' }, ]; - get useCoordinateSystem(): boolean { return this._useCoordinateSystem; } - set useCoordinateSystem(flag: boolean) { this._useCoordinateSystem = flag; } - - get useBackground(): boolean { return this._useBackground; } - set useBackground(flag: boolean) { this._useBackground = flag; } + get useCoordinateSystem(): boolean { + return this._useCoordinateSystem; + } + set useCoordinateSystem(flag: boolean) { + this._useCoordinateSystem = flag; + } - get useCategories(): boolean { return this._useCategories; } - set useCategories(flag: boolean) { this._useCategories = flag; } + get useBackground(): boolean { + return this._useBackground; + } + set useBackground(flag: boolean) { + this._useBackground = flag; + } - get useContour(): boolean { return this._useContour; } - set useContour(flag: boolean) { this._useContour = flag; } + get useCategories(): boolean { + return this._useCategories; + } + set useCategories(flag: boolean) { + this._useCategories = flag; + } - get useLabels(): boolean { return this._useLabels; } - set useLabels(flag: boolean) { this._useLabels = flag; } + get useContour(): boolean { + return this._useContour; + } + set useContour(flag: boolean) { + this._useContour = flag; + } - get glyphOptions(): any { return this.options; } - set glyphOptions(options: any) { this.options = options; } + get useLabels(): boolean { + return this._useLabels; + } + set useLabels(flag: boolean) { + this._useLabels = flag; + } - get glyphType(): GlyphType { return this._glyphType; } - set glyphType(type: GlyphType) { this._glyphType = type; } + get glyphOptions(): GlyphOption[] { + return this.options; + } + set glyphOptions(options: GlyphOption[]) { + this.options = options; + } - get radius(): number { return this._radius; } - set radius(r: number) { this._radius = r; } + get glyphType(): GlyphType { + return this._glyphType; + } + set glyphType(type: GlyphType) { + this._glyphType = type; + } - get accessors(): any[] { return this._accessors; } - set accessors(acc: any[]) { this._accessors = acc; } + get radius(): number { + return this._radius; + } + set radius(r: number) { + this._radius = r; + } - get scaleLinear(): boolean { return this._scaleLinear; } - set scaleLinear(scaleLinear: boolean) { this._scaleLinear = scaleLinear; } -} \ No newline at end of file + get scaleLinear(): boolean { + return this._scaleLinear; + } + set scaleLinear(scaleLinear: boolean) { + this._scaleLinear = scaleLinear; + } +} diff --git a/src/app/glyph/glyph-object.ts b/src/app/glyph/glyph-object.ts index 4326e37..e6f8bcf 100644 --- a/src/app/glyph/glyph-object.ts +++ b/src/app/glyph/glyph-object.ts @@ -1,549 +1,208 @@ -import { Object3D } from "three"; -import { Coordinates } from "../shared/interfaces/coordinates"; -import { ZoomLevel } from "../shared/enum/zoom-level"; +import { Object3D } from 'three'; +import { Coordinates } from '../shared/interfaces/coordinates'; +import { ZoomLevel } from '../shared/enum/zoom-level'; import * as THREE from 'three'; -import { Line2 } from 'three/examples/jsm/lines/Line2.js'; -import { LineGeometry } from 'three/examples/jsm/lines/LineGeometry.js'; -import { LineMaterial } from 'three/examples/jsm/lines/LineMaterial.js'; -import { Features, StringStringMap } from "../shared/interfaces/glyph-feature"; -import { GlyphCacheObject } from "./glyph-cache-object"; -import { ConfigService } from "../services/config.service"; -import { GlyphType } from "../shared/enum/glyph-type"; -import { GlyphSizeInfo } from "./glyph-size-info"; -import { DataProcessorService } from "../services/data-processor"; -import { createGrayPlaceholderTexture } from "../shared/helpers/three-helper"; - -// Shared geometry cache for performance (reuse common geometries) -const geometryCache = { - circles: new Map(), - rings: new Map(), -}; - -// Get or create a cached circle geometry -function getCachedCircleGeometry(radius: number, segments: number = 32): THREE.CircleGeometry { - const key = `${radius.toFixed(2)}_${segments}`; - let geom = geometryCache.circles.get(key); - if (!geom) { - geom = new THREE.CircleGeometry(radius, segments); - geometryCache.circles.set(key, geom); - } - return geom; -} - -// Get or create a cached ring geometry -function getCachedRingGeometry(innerRadius: number, outerRadius: number, segments: number = 32): THREE.RingGeometry { - const key = `${innerRadius.toFixed(2)}_${outerRadius.toFixed(2)}_${segments}`; - let geom = geometryCache.rings.get(key); - if (!geom) { - geom = new THREE.RingGeometry(innerRadius, outerRadius, segments); - geometryCache.rings.set(key, geom); - } - return geom; -} +import { Features, StringStringMap } from '../shared/interfaces/glyph-feature'; +import { GlyphCacheObject } from './glyph-cache-object'; +import { GlyphType } from '../shared/enum/glyph-type'; +import { GlyphSizeInfo } from './glyph-size-info'; +import { normalizeFeatureValue } from '../shared/helpers/color-helper'; +import { GlyphRenderContext, getGlyphRenderer } from './renderers/glyph-renderer'; +import { ThumbnailRenderer } from './renderers/thumbnail.renderer'; +import { getCachedCircleGeometry, getCachedRingGeometry, getCachedBasicMaterial } from './renderers/shared-rendering'; +import { GlyphRenderConfig } from './glyph-render-config'; + +// Side-effect import: registers all built-in glyph renderers +import './renderers/glyph-renderer-registry'; export class GlyphObject { - id: string; - private config!: ConfigService; - private dataProcessor!: DataProcessorService; - positions: { - [timestamp: string]: { - [algorithm: string]: Coordinates; - }; - } = {}; - defaultcontext = 0; - features!: Features; - values: StringStringMap | undefined; - currentContext = 1; - renderCache = new Map(); - passive = false; - highlighted = false; - isInLense = false; - lensCenter: THREE.Vector3 = new THREE.Vector3(0, 0, 0); - highlightColor: number = 0x9b274d; - passivecolor: number = 0xe0e0e0; - axesColor: number = 0xa0a0a0; - - constructor(id: string, config: ConfigService, dataProcessor: DataProcessorService) { - this.id = id; - this.config = config; - this.dataProcessor = dataProcessor; - } - - public getPosition(timestamp: string, algorithm: string): Coordinates { - return this.positions[timestamp][algorithm]; - } - - public clearCache(owner: number) { - this.renderCache.delete(owner); - } - - public getCacheObject(owner = 0, timestamp: string, algorithm: string): GlyphCacheObject { - let cacheObject = this.renderCache.get(owner); - if (cacheObject == undefined || cacheObject == null) { - cacheObject = new GlyphCacheObject(this.id, { ... this.getPosition(timestamp, algorithm) }); - this.renderCache.set(owner, cacheObject); - } - - return cacheObject; - } - - public getMesh(timestamp: string, algorithm: string, owner = 0): Object3D | undefined { - const cacheObject = this.getCacheObject(owner, timestamp, algorithm); - return cacheObject.mesh; - } - - public setHighlighted(highlight: boolean) { - if (this.highlighted == highlight) return; - - this.highlighted = highlight; - } - - private getCurrentColor(trueColor = false): number { - if (this.highlighted && !trueColor) { - return this.highlightColor; - } - if (this.passive && !trueColor) { - return this.passivecolor; - } - - let currentColor = 0x00cc88; - if (this.features != null) { - let featureValue = this.features["1"][this.config.colorFeature]; - - // Normalize categorical values to [0,1] range for proper color mapping - const featureType = this.config.featureTypes[this.config.colorFeature]; - if (featureType === 'categorical') { - const maxValue = this.config.featureMaxValues[this.config.colorFeature]; - if (maxValue !== undefined && maxValue > 0) { - featureValue = featureValue / maxValue; - } - } - - currentColor = this.config.color(featureValue); - } - - return currentColor; - } - - public render(sizeInfo: GlyphSizeInfo, timestamp: string, algorithm: string, owner = 0, clustered = false): THREE.Object3D | null { - const mesh = this.renderGlyph(sizeInfo, timestamp, algorithm, owner, clustered); - const cacheObject = this.getCacheObject(owner, timestamp, algorithm); - if (mesh) cacheObject.mesh = mesh; - return mesh; - } - - public renderGlyph(sizeInfo: GlyphSizeInfo, timestamp: string, algorithm: string, owner = 0, clustered = false): THREE.Object3D | null { - const cacheObject = this.getCacheObject(owner, timestamp, algorithm); - const cachedMesh = cacheObject.mesh; - - let mesh: THREE.Object3D; - - if (sizeInfo.currentZoomLevel == ZoomLevel.low) { - if (clustered && cacheObject.isClustered && !cacheObject.isClusterRepresentative) { - return null; // Omit this glyph entirely - } - - const currentColor = this.getCurrentColor(); - - if (cacheObject.isClusterRepresentative && clustered) { - // Render as an outlined circle (no fill) - use cached geometry - const ringGeom = getCachedRingGeometry(sizeInfo.radius - 1, sizeInfo.radius, 24); - const ringMat = new THREE.MeshBasicMaterial({ color: currentColor, side: THREE.DoubleSide }); - mesh = new THREE.Mesh(ringGeom, ringMat); - } else { - // Render as filled circle - use cached geometry - const geom = getCachedCircleGeometry(sizeInfo.radius, 24); - const mat = new THREE.MeshBasicMaterial({ color: currentColor }); - mesh = new THREE.Mesh(geom, mat); - } - } else { - if (this.config.getConfiguration().glyphType == GlyphType.Star) { - mesh = this.createRadarChart(sizeInfo, this.config.getConfiguration().scaleLinear, this.currentContext); - } else if (this.config.getConfiguration().glyphType == GlyphType.Whisker) { - mesh = this.createWhiskerGlyph(sizeInfo, this.config.getConfiguration().scaleLinear, this.currentContext); - } else if (this.config.getConfiguration().glyphType == GlyphType.Thumb) { - mesh = this.createThumbnail(sizeInfo); - } else { - mesh = this.createFlowerGlyph(sizeInfo, this.config.getConfiguration().scaleLinear, this.currentContext); - } - } - - const x = cachedMesh ? cachedMesh.position.x : cacheObject.x ?? 0; - const y = cachedMesh ? cachedMesh.position.y : cacheObject.y ?? 0; - mesh.position.set(x, y, 0); - mesh.userData = { item: new WeakRef(this) }; - mesh.renderOrder = this.passive ? 1 : 99; - - return mesh; - } - - private applyThumbnailTexture(image: HTMLImageElement | ImageBitmap, mesh: THREE.Mesh, mat: THREE.MeshBasicMaterial, sizeInfo: GlyphSizeInfo) { - const originalWidth = image.width; - const originalHeight = image.height; - - const maxDim = sizeInfo.radius * 3; - const widthRatio = maxDim / originalWidth; - const heightRatio = maxDim / originalHeight; - const scale = Math.min(widthRatio, heightRatio, 1); - - const finalWidth = originalWidth * scale; - const finalHeight = originalHeight * scale; - - // Replace geometry to match image aspect ratio - const geom = new THREE.PlaneGeometry(finalWidth, finalHeight); - mesh.geometry.dispose(); - mesh.geometry = geom; - - const texture = new THREE.Texture(image); - texture.needsUpdate = true; - texture.minFilter = THREE.NearestFilter; - texture.magFilter = THREE.NearestFilter; - texture.colorSpace = THREE.SRGBColorSpace; - - mat.map = texture; - mat.needsUpdate = true; - - this.config.reRender(); - } - - private createThumbnail(sizeInfo: GlyphSizeInfo) { - const placeholderTexture = createGrayPlaceholderTexture(); - const geom = new THREE.PlaneGeometry(sizeInfo.radius * 2, sizeInfo.radius * 2); - const mat = new THREE.MeshBasicMaterial({ map: placeholderTexture, transparent: true }); - const mesh = new THREE.Mesh(geom, mat); - - const file = `${this.config.loadedData}/${this.id}.jpg`; - - if (this.config.dataSource == "wasm") { - this.dataProcessor.requestThumb(file).subscribe((bitmap) => { - if (bitmap) { - this.applyThumbnailTexture(bitmap, mesh, mat, sizeInfo); - } - }); - } else { - const image = new Image(); - image.src = `assets/thumbnails/${this.config.loadedData}/${this.id}.jpg`; - image.crossOrigin = 'anonymous'; // only needed if assets served from different domain (unlikely in local app) - - image.onload = () => { - this.applyThumbnailTexture(image, mesh, mat, sizeInfo); - }; - - image.onerror = () => { - console.warn(`Failed to load thumbnail from local: ${image.src}`); - }; - } - return mesh; - } - - private createRadarChart(sizeInfo: GlyphSizeInfo, linearScale = false, contextId: number): THREE.Object3D { - const group = new THREE.Group(); - this.addBackgroundCircle(group, sizeInfo); - - const ctx = this.getFeatureContext(contextId); - if (!ctx) return group; - - const { featureMap, keys, values, featureMaxValues, segments } = ctx; - - const color = this.getCurrentColor(sizeInfo.currentZoomLevel == ZoomLevel.high); - - this.addCoordinateAxes(group, segments, sizeInfo); - if (this.addPlaceHolder(group, values, sizeInfo)) return group; - - const points: THREE.Vector2[] = []; - - keys.forEach((key, i) => { - const angle = (i / segments) * Math.PI * 2; - const value = +featureMap[key] || 0; - // Use per-feature global max for proper normalization (especially for categorical data) - const maxVal = featureMaxValues[i] || 1; - const norm = linearScale ? value : value / maxVal; - const x = Math.cos(angle) * sizeInfo.radius * norm; - const y = Math.sin(angle) * sizeInfo.radius * norm; - points.push(new THREE.Vector2(x, y)); - }); - - // === Fill shape === - const shape = new THREE.Shape(points); - const fillMat = new THREE.MeshBasicMaterial({ - color: color, - side: THREE.DoubleSide, - transparent: true, - opacity: 0.6 - }); - group.add(new THREE.Mesh(new THREE.ShapeGeometry(shape), fillMat)); - - if (this.config.getConfiguration().useContour) { - // === Contour stroke using Line2 for thick lines === - // Prepare positions array (x,y,z), close path by repeating first point - const closedPoints = [...points.map(p => new THREE.Vector3(p.x, p.y, 0))]; - closedPoints.push(closedPoints[0].clone()); - - // Convert to flat array for LineGeometry - const positions: number[] = []; - closedPoints.forEach(p => { - positions.push(p.x, p.y, p.z); - }); - - // Create LineGeometry and set positions - const lineGeom = new LineGeometry(); - lineGeom.setPositions(positions); - - // Create LineMaterial with thickness (adjust linewidth as needed) - const lineMat = new LineMaterial({ - color: color, - linewidth: sizeInfo.contourThickness, // world units, tweak for your scene scale - transparent: true, - opacity: 0.9, - }); - - // Create Line2 mesh and add to group - const line = new Line2(lineGeom, lineMat); - line.computeLineDistances(); // required for dashed lines (optional here) - line.scale.set(1, 1, 1); - group.add(line); - } - - return group; - } - - private createFlowerGlyph( - sizeInfo: GlyphSizeInfo, - linearScale = false, - contextId: number - ): THREE.Object3D { - const group = new THREE.Group(); - this.addBackgroundCircle(group, sizeInfo); - - const ctx = this.getFeatureContext(contextId); - if (!ctx) return group; - - const { featureMap, keys, values, featureMaxValues, segments } = ctx; - this.addCoordinateAxes(group, segments, sizeInfo); - if (this.addPlaceHolder(group, values, sizeInfo)) return group; - - const color = this.getCurrentColor(sizeInfo.currentZoomLevel == ZoomLevel.high); - - keys.forEach((key, i) => { - const value = +featureMap[key] || 0; - if (value <= 0) return; - - // Use per-feature global max for proper normalization - const maxVal = featureMaxValues[i] || 1; - const norm = linearScale ? value : value / maxVal; - const petalLength = sizeInfo.radius * norm; - const baseWidth = petalLength * 0.4; - - // Create petal shape - const path = new THREE.Shape(); - path.moveTo(0, 0); - - path.bezierCurveTo( - baseWidth * 0.25, -petalLength * 0.3, - baseWidth * 0.6, -petalLength * 0.75, - 0, -petalLength - ); - path.bezierCurveTo( - -baseWidth * 0.6, -petalLength * 0.75, - -baseWidth * 0.25, -petalLength * 0.3, - 0, 0 - ); - - // Petal fill mesh - const geom = new THREE.ShapeGeometry(path); - const mat = new THREE.MeshBasicMaterial({ - color, - transparent: true, - opacity: 0.6, - side: THREE.DoubleSide - }); - const mesh = new THREE.Mesh(geom, mat); - - // Add the fill mesh - const angle = (i / segments) * Math.PI * 2; - mesh.rotation.z = angle - (3 * Math.PI) / 2; - group.add(mesh); - - if (this.config.getConfiguration().useContour) { - // === Create contour using Line2 === - - // Extract points from shape to create contour geometry - const contourPoints: THREE.Vector3[] = []; - - // Move along the bezier curves with manual points sampling or use getPoints() - // THREE.Shape has getPoints() that returns Vector2 points on the outline - const outlinePoints = path.getPoints(50); // 50 points for smoothness - - // Convert Vector2[] to Vector3[] for LineGeometry - outlinePoints.forEach(p => { - contourPoints.push(new THREE.Vector3(p.x, p.y, 0)); - }); - // Close the contour by adding the first point at the end - contourPoints.push(contourPoints[0].clone()); - - // Prepare flat positions array - const positions: number[] = []; - contourPoints.forEach(p => { - positions.push(p.x, p.y, p.z); - }); - - const lineGeom = new LineGeometry(); - lineGeom.setPositions(positions); - - const lineMat = new LineMaterial({ - color, - linewidth: sizeInfo.contourThickness, // Adjust thickness to your liking - transparent: true, - opacity: 0.9, - }); - - const contourLine = new Line2(lineGeom, lineMat); - contourLine.computeLineDistances(); - contourLine.scale.set(1, 1, 1); - contourLine.rotation.z = angle - (3 * Math.PI) / 2; // same rotation as petal - - group.add(contourLine); - } - }); - - return group; - } - - private createWhiskerGlyph( - sizeInfo: GlyphSizeInfo, - linearScale = false, - contextId: number - ): THREE.Object3D { - const group = new THREE.Group(); - this.addBackgroundCircle(group, sizeInfo); - - const ctx = this.getFeatureContext(contextId); - if (!ctx) return group; - - const { featureMap, keys, values, featureMaxValues, segments } = ctx; - this.addCoordinateAxes(group, segments, sizeInfo); - if (this.addPlaceHolder(group, values, sizeInfo)) return group; - - const color = this.getCurrentColor(sizeInfo.currentZoomLevel == ZoomLevel.high); - - keys.forEach((key, i) => { - const value = +featureMap[key] || 0; - if (value <= 0) return; - - // Use per-feature global max for proper normalization - const maxVal = featureMaxValues[i] || 1; - const norm = linearScale ? value : value / maxVal; - const whiskerLength = sizeInfo.radius * norm; - - const barWidth = 0.8; - const barHeight = whiskerLength; - - const angle = (i / segments) * Math.PI * 2; - const container = new THREE.Object3D(); - container.rotation.z = angle - (3 * Math.PI) / 2; - - const geom = new THREE.PlaneGeometry(barWidth, barHeight); - const mat = new THREE.MeshBasicMaterial({ - color, - transparent: true, - opacity: 0.8, - side: THREE.DoubleSide, - depthWrite: false - }); - const mesh = new THREE.Mesh(geom, mat); - - mesh.position.y = -barHeight / 2; - container.add(mesh); - group.add(container); - }); - - return group; - } - - // === Shared feature extraction and setup === - private getFeatureContext(contextId: number) { - if (!this.features) return null; - - const featureMap = Object.fromEntries( - Object.entries(this.features[contextId] || {}).filter(([k]) => - this.config.activeFeatures.includes(k) - ) + id: string; + positions: Record> = {}; + defaultcontext = 0; + features!: Features; + values: StringStringMap | undefined; + currentContext = 1; + renderCache = new Map(); + passive = false; + highlighted = false; + isInLense = false; + lensCenter: THREE.Vector3 = new THREE.Vector3(0, 0, 0); + highlightColor = 0x9b274d; + passivecolor = 0xe0e0e0; + + constructor(id: string) { + this.id = id; + } + + public getPosition(timestamp: string, algorithm: string): Coordinates { + return this.positions[timestamp][algorithm]; + } + + public clearCache(owner: number) { + this.renderCache.delete(owner); + } + + public getCacheObject(owner = 0, timestamp: string, algorithm: string): GlyphCacheObject { + let cacheObject = this.renderCache.get(owner); + if (cacheObject == null) { + cacheObject = new GlyphCacheObject(this.id, { ...this.getPosition(timestamp, algorithm) }); + this.renderCache.set(owner, cacheObject); + } + + return cacheObject; + } + + public getMesh(timestamp: string, algorithm: string, owner = 0): Object3D | undefined { + const cacheObject = this.getCacheObject(owner, timestamp, algorithm); + return cacheObject.mesh; + } + + public setHighlighted(highlight: boolean) { + if (this.highlighted === highlight) return; + + this.highlighted = highlight; + } + + private getCurrentColor(renderConfig: GlyphRenderConfig, trueColor = false): string | number { + if (this.highlighted && !trueColor) { + return this.highlightColor; + } + if (this.passive && !trueColor) { + return this.passivecolor; + } + + let currentColor: string | number = 0x00cc88; + if (this.features != null) { + const featureValue = normalizeFeatureValue( + this.features['1'][renderConfig.colorFeature], + renderConfig.colorFeature, + renderConfig.featureTypes, + renderConfig.featureMaxValues + ); + + const scale = renderConfig.colorScale; + if (scale) { + currentColor = scale(featureValue); + } + } + + return currentColor; + } + + public render( + sizeInfo: GlyphSizeInfo, + timestamp: string, + algorithm: string, + owner: number, + clustered: boolean, + renderConfig: GlyphRenderConfig + ): THREE.Object3D | null { + const mesh = this.renderGlyph(sizeInfo, timestamp, algorithm, owner, clustered, renderConfig); + const cacheObject = this.getCacheObject(owner, timestamp, algorithm); + if (mesh) cacheObject.mesh = mesh; + return mesh; + } + + public renderGlyph( + sizeInfo: GlyphSizeInfo, + timestamp: string, + algorithm: string, + owner: number, + clustered: boolean, + renderConfig: GlyphRenderConfig + ): THREE.Object3D | null { + const cacheObject = this.getCacheObject(owner, timestamp, algorithm); + const cachedMesh = cacheObject.mesh; + + let mesh: THREE.Object3D; + + if (sizeInfo.currentZoomLevel === ZoomLevel.low) { + if (clustered && cacheObject.isClustered && !cacheObject.isClusterRepresentative) { + return null; // Omit this glyph entirely + } + + const currentColor = this.getCurrentColor(renderConfig); + + if (cacheObject.isClusterRepresentative && clustered) { + const ringGeom = getCachedRingGeometry(sizeInfo.radius - 1, sizeInfo.radius, 24); + const ringMat = getCachedBasicMaterial(currentColor, { side: THREE.DoubleSide }); + mesh = new THREE.Mesh(ringGeom, ringMat); + } else { + const geom = getCachedCircleGeometry(sizeInfo.radius, 24); + const mat = getCachedBasicMaterial(currentColor); + mesh = new THREE.Mesh(geom, mat); + } + } else { + const glyphType = renderConfig.glyphType; + + // Thumbnail is special: needs per-glyph service injection + if (glyphType === GlyphType.Thumb) { + const thumbRenderer = new ThumbnailRenderer(this.id, renderConfig); + mesh = thumbRenderer.render( + this.buildRenderContext(sizeInfo, renderConfig), + sizeInfo, + renderConfig.scaleLinear ); - const keys = Object.keys(featureMap); - const values = keys.map(k => +featureMap[k]); - - // Use global max values from config for consistent scaling across all glyphs - // This is especially important for categorical features which are label-encoded - const globalMaxValues = this.config.featureMaxValues; - const featureMaxValues = keys.map(k => globalMaxValues[k] ?? 1); - - // For backward compatibility, also compute local max (used when global not available) - const localMaxValue = Math.max(...values) || 1; - const segments = keys.length; - - return { featureMap, keys, values, featureMaxValues, localMaxValue, segments }; - } - - private addPlaceHolder(group: THREE.Group, values: number[], sizeInfo: GlyphSizeInfo): boolean { - if (values.every(v => v <= 0.001)) { - const geom = getCachedCircleGeometry(sizeInfo.getRadius(ZoomLevel.low) / 4, 16); - const mat = new THREE.MeshBasicMaterial({ - color: this.getCurrentColor(true), - side: THREE.DoubleSide, - transparent: true, - opacity: 0.6 - }); - group.add(new THREE.Mesh(geom, mat)); - return true; - } - return false; - } - - // === Shared background circle === - private addBackgroundCircle(group: THREE.Group, sizeInfo: GlyphSizeInfo) { - const background = (sizeInfo.currentZoomLevel == ZoomLevel.high) && this.config.getConfiguration().useBackground; - if (!background) return; - - // Use cached geometry with reduced segment count for performance - const geom = getCachedCircleGeometry(sizeInfo.radius, 32); - const mat = new THREE.MeshBasicMaterial({ color: 0xf0f0f0 }); - if (this.highlighted) { - const color = new THREE.Color(this.highlightColor); - color.lerp(new THREE.Color(0xffffff), 0.6); // mix toward white - mat.color.copy(color); - } - group.add(new THREE.Mesh(geom, mat)); - - // Optional contour/stroke - if (this.config.getConfiguration().useContour) { - const ringWidth = sizeInfo.radius * 0.01; - const contourGeom = getCachedRingGeometry(sizeInfo.radius - ringWidth, sizeInfo.radius, 32); - const contourMat = new THREE.MeshBasicMaterial({ - color: 0xcccccc, - side: THREE.DoubleSide, - depthTest: false // always draw on top - }); - - const contour = new THREE.Mesh(contourGeom, contourMat); - contour.renderOrder = 999; // draw last - group.add(contour); - } - } - - // === Shared axes drawing === - private addCoordinateAxes(group: THREE.Group, segments: number, sizeInfo: GlyphSizeInfo) { - const axes = (sizeInfo.currentZoomLevel == ZoomLevel.high) && this.config.getConfiguration().useCoordinateSystem; - if (!axes) return; - - const lineWidth = sizeInfo.contourThickness / 3; // 0.1; - for (let i = 0; i < segments; i++) { - const angle = (i / segments) * Math.PI * 2; - const geom = new THREE.PlaneGeometry(lineWidth, sizeInfo.radius); - geom.translate(0, sizeInfo.radius / 2, 0); - const mat = new THREE.MeshBasicMaterial({ color: this.axesColor, side: THREE.DoubleSide }); - const mesh = new THREE.Mesh(geom, mat); - mesh.rotation.z = angle - Math.PI / 2; - group.add(mesh); + } else { + const renderer = getGlyphRenderer(glyphType); + if (renderer) { + mesh = renderer.render(this.buildRenderContext(sizeInfo, renderConfig), sizeInfo, renderConfig.scaleLinear); + } else { + // Fallback to flower + const fallback = getGlyphRenderer(GlyphType.Flower); + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- Flower renderer is always registered + mesh = fallback!.render(this.buildRenderContext(sizeInfo, renderConfig), sizeInfo, renderConfig.scaleLinear); } - } -} \ No newline at end of file + } + } + + const x = cachedMesh ? cachedMesh.position.x : (cacheObject.x ?? 0); + const y = cachedMesh ? cachedMesh.position.y : (cacheObject.y ?? 0); + mesh.position.set(x, y, 0); + mesh.userData = { item: new WeakRef(this) }; + mesh.renderOrder = this.passive ? 1 : 99; + + return mesh; + } + + /** + * Build the render context that glyph renderers need. + */ + private buildRenderContext(sizeInfo: GlyphSizeInfo, renderConfig: GlyphRenderConfig): GlyphRenderContext { + const featureCtx = this.getFeatureContext(this.currentContext, renderConfig); + const color = this.getCurrentColor(renderConfig, sizeInfo.currentZoomLevel === ZoomLevel.high); + + return { + featureMap: featureCtx?.featureMap ?? {}, + keys: featureCtx?.keys ?? [], + values: featureCtx?.values ?? [], + featureMaxValues: featureCtx?.featureMaxValues ?? [], + segments: featureCtx?.segments ?? 0, + color, + useContour: renderConfig.useContour, + useBackground: renderConfig.useBackground, + useCoordinateSystem: renderConfig.useCoordinateSystem, + highlighted: this.highlighted, + highlightColor: this.highlightColor, + }; + } + + // === Shared feature extraction === + private getFeatureContext(contextId: number, renderConfig: GlyphRenderConfig) { + if (!this.features) return null; + + const featureMap = Object.fromEntries( + Object.entries(this.features[contextId] || {}).filter(([k]) => renderConfig.activeFeatures.includes(k)) + ); + const keys = Object.keys(featureMap); + const values = keys.map(k => +featureMap[k]); + + const globalMaxValues = renderConfig.featureMaxValues; + const featureMaxValues = keys.map(k => globalMaxValues[k] ?? 1); + + const localMaxValue = Math.max(...values) || 1; + const segments = keys.length; + + return { featureMap, keys, values, featureMaxValues, localMaxValue, segments }; + } +} diff --git a/src/app/glyph/glyph-render-config.ts b/src/app/glyph/glyph-render-config.ts new file mode 100644 index 0000000..d74a5f6 --- /dev/null +++ b/src/app/glyph/glyph-render-config.ts @@ -0,0 +1,55 @@ +import { Observable } from 'rxjs'; +import { GlyphType } from '../shared/enum/glyph-type'; +import { ConfigService } from '../services/config.service'; +import { DataProcessorService } from '../services/data-processor'; + +/** + * Abstracts thumbnail loading away from DataProcessorService. + */ +export interface ThumbnailResolver { + requestThumb(path: string): Observable; +} + +/** + * Plain-data configuration snapshot that GlyphObject.render() needs. + * Decouples GlyphObject from Angular services. + */ +export interface GlyphRenderConfig { + colorFeature: string; + featureTypes: Record; + featureMaxValues: Record; + colorScale: ((value: number) => string) | undefined; + glyphType: GlyphType; + scaleLinear: boolean; + useContour: boolean; + useBackground: boolean; + useCoordinateSystem: boolean; + activeFeatures: string[]; + dataSource: string; + loadedData: string; + thumbnailResolver?: ThumbnailResolver; + onReRender?: () => void; +} + +/** + * Build a GlyphRenderConfig snapshot from the current ConfigService state. + */ +export function buildGlyphRenderConfig(config: ConfigService, dataProcessor?: DataProcessorService): GlyphRenderConfig { + const glyphConfig = config.getConfiguration(); + return { + colorFeature: config.colorFeature, + featureTypes: config.featureTypes, + featureMaxValues: config.featureMaxValues, + colorScale: config.color as ((value: number) => string) | undefined, + glyphType: glyphConfig.glyphType, + scaleLinear: glyphConfig.scaleLinear, + useContour: glyphConfig.useContour, + useBackground: glyphConfig.useBackground, + useCoordinateSystem: glyphConfig.useCoordinateSystem, + activeFeatures: config.activeFeatures, + dataSource: config.dataSource, + loadedData: config.loadedData, + thumbnailResolver: dataProcessor ? { requestThumb: (path: string) => dataProcessor.requestThumb(path) } : undefined, + onReRender: () => config.reRender(), + }; +} diff --git a/src/app/glyph/glyph-size-info.ts b/src/app/glyph/glyph-size-info.ts index 115b208..22b4af8 100644 --- a/src/app/glyph/glyph-size-info.ts +++ b/src/app/glyph/glyph-size-info.ts @@ -1,4 +1,4 @@ -import { ZoomLevel } from "../shared/enum/zoom-level"; +import { ZoomLevel } from '../shared/enum/zoom-level'; export class GlyphSizeInfo { private radii = new Map(); @@ -14,14 +14,10 @@ export class GlyphSizeInfo { private baseRadius = 2, private baseContour = 0.3, private baseHitTolerance = 8 - ) { } + ) {} clone(): GlyphSizeInfo { - const cloned = new GlyphSizeInfo( - this.baseRadius, - this.baseContour, - this.baseHitTolerance - ); + const cloned = new GlyphSizeInfo(this.baseRadius, this.baseContour, this.baseHitTolerance); // Clone maps this.radii.forEach((value, key) => cloned.radii.set(key, value)); @@ -45,7 +41,7 @@ export class GlyphSizeInfo { const depthFactor = window.screen.pixelDepth / 24; const scale = 1.25; // pixelRatio * depthFactor; - const base = 1 / (depthFactor / pixelRatio) * (minDim / baseDim); // minDim * this.baseRatio; + const base = (1 / (depthFactor / pixelRatio)) * (minDim / baseDim); // minDim * this.baseRatio; this.radii.set(ZoomLevel.low, base * this.baseRadius); this.radii.set(ZoomLevel.medium, base * this.baseRadius * scale); @@ -56,8 +52,8 @@ export class GlyphSizeInfo { this.contourThicknesses.set(ZoomLevel.high, this.baseContour * scale); this.hitTolerances.set(ZoomLevel.low, this.baseHitTolerance / depthFactor / pixelRatio); - this.hitTolerances.set(ZoomLevel.medium, this.baseHitTolerance * 4 / depthFactor / pixelRatio); - this.hitTolerances.set(ZoomLevel.high, this.baseHitTolerance * 16 / depthFactor / pixelRatio); + this.hitTolerances.set(ZoomLevel.medium, (this.baseHitTolerance * 4) / depthFactor / pixelRatio); + this.hitTolerances.set(ZoomLevel.high, (this.baseHitTolerance * 16) / depthFactor / pixelRatio); this.updateInfo(); } @@ -72,7 +68,7 @@ export class GlyphSizeInfo { // === Zoom level management === set currentZoomLevel(level: ZoomLevel) { this._currentZoomLevel = level; - this.updateInfo(); // Update AFTER setting the new level + this.updateInfo(); // Update AFTER setting the new level } get currentZoomLevel(): ZoomLevel { diff --git a/src/app/glyph/renderers/flower-glyph.renderer.ts b/src/app/glyph/renderers/flower-glyph.renderer.ts new file mode 100644 index 0000000..185a20e --- /dev/null +++ b/src/app/glyph/renderers/flower-glyph.renderer.ts @@ -0,0 +1,77 @@ +import * as THREE from 'three'; +import { Line2 } from 'three/examples/jsm/lines/Line2.js'; +import { LineGeometry } from 'three/examples/jsm/lines/LineGeometry.js'; +import { LineMaterial } from 'three/examples/jsm/lines/LineMaterial.js'; +import { GlyphSizeInfo } from '../glyph-size-info'; +import { GlyphRenderer, GlyphRenderContext } from './glyph-renderer'; +import { addBackgroundCircle, addCoordinateAxes, addPlaceHolder } from './shared-rendering'; + +export class FlowerGlyphRenderer implements GlyphRenderer { + render(ctx: GlyphRenderContext, sizeInfo: GlyphSizeInfo, linearScale: boolean): THREE.Object3D { + const group = new THREE.Group(); + addBackgroundCircle(group, sizeInfo, ctx); + + const { featureMap, keys, values, featureMaxValues, segments, color } = ctx; + if (keys.length === 0) return group; + + addCoordinateAxes(group, segments, sizeInfo, ctx); + if (addPlaceHolder(group, values, sizeInfo, color)) return group; + + keys.forEach((key, i) => { + const value = +featureMap[key] || 0; + if (value <= 0) return; + + const maxVal = featureMaxValues[i] || 1; + const norm = linearScale ? value : value / maxVal; + const petalLength = sizeInfo.radius * norm; + const baseWidth = petalLength * 0.4; + + const path = new THREE.Shape(); + path.moveTo(0, 0); + path.bezierCurveTo(baseWidth * 0.25, -petalLength * 0.3, baseWidth * 0.6, -petalLength * 0.75, 0, -petalLength); + path.bezierCurveTo(-baseWidth * 0.6, -petalLength * 0.75, -baseWidth * 0.25, -petalLength * 0.3, 0, 0); + + const geom = new THREE.ShapeGeometry(path); + const mat = new THREE.MeshBasicMaterial({ + color, + transparent: true, + opacity: 0.6, + side: THREE.DoubleSide, + }); + const mesh = new THREE.Mesh(geom, mat); + + const angle = (i / segments) * Math.PI * 2; + mesh.rotation.z = angle - (3 * Math.PI) / 2; + group.add(mesh); + + if (ctx.useContour) { + const contourPoints: THREE.Vector3[] = []; + const outlinePoints = path.getPoints(50); + outlinePoints.forEach(p => contourPoints.push(new THREE.Vector3(p.x, p.y, 0))); + contourPoints.push(contourPoints[0].clone()); + + const positions: number[] = []; + contourPoints.forEach(p => positions.push(p.x, p.y, p.z)); + + const lineGeom = new LineGeometry(); + lineGeom.setPositions(positions); + + const lineMat = new LineMaterial({ + color, + linewidth: sizeInfo.contourThickness, + transparent: true, + opacity: 0.9, + }); + + const contourLine = new Line2(lineGeom, lineMat); + contourLine.computeLineDistances(); + contourLine.scale.set(1, 1, 1); + contourLine.rotation.z = angle - (3 * Math.PI) / 2; + + group.add(contourLine); + } + }); + + return group; + } +} diff --git a/src/app/glyph/renderers/glyph-renderer-registry.ts b/src/app/glyph/renderers/glyph-renderer-registry.ts new file mode 100644 index 0000000..c1125bd --- /dev/null +++ b/src/app/glyph/renderers/glyph-renderer-registry.ts @@ -0,0 +1,11 @@ +import { GlyphType } from '../../shared/enum/glyph-type'; +import { registerGlyphRenderer } from './glyph-renderer'; +import { RadarChartRenderer } from './radar-chart.renderer'; +import { FlowerGlyphRenderer } from './flower-glyph.renderer'; +import { WhiskerGlyphRenderer } from './whisker-glyph.renderer'; + +// Register all built-in glyph renderers. +// Thumbnail is excluded because it requires per-glyph service injection. +registerGlyphRenderer(GlyphType.Star, new RadarChartRenderer()); +registerGlyphRenderer(GlyphType.Flower, new FlowerGlyphRenderer()); +registerGlyphRenderer(GlyphType.Whisker, new WhiskerGlyphRenderer()); diff --git a/src/app/glyph/renderers/glyph-renderer.ts b/src/app/glyph/renderers/glyph-renderer.ts new file mode 100644 index 0000000..d2f72e6 --- /dev/null +++ b/src/app/glyph/renderers/glyph-renderer.ts @@ -0,0 +1,54 @@ +import * as THREE from 'three'; +import { GlyphSizeInfo } from '../glyph-size-info'; +import { GlyphType } from '../../shared/enum/glyph-type'; + +/** + * Context provided to glyph renderers containing everything they need + * to create the glyph mesh without coupling to GlyphObject internals. + */ +export interface GlyphRenderContext { + /** Feature data: { featureId: value, ... } */ + featureMap: Record; + /** Ordered feature keys */ + keys: string[]; + /** Ordered numeric values */ + values: number[]; + /** Per-feature max values for normalization */ + featureMaxValues: number[]; + /** Number of feature axes */ + segments: number; + /** Resolved color for this glyph (hex number or string) */ + color: string | number; + /** Whether to use contour outlines */ + useContour: boolean; + /** Whether to show background circle */ + useBackground: boolean; + /** Whether to show coordinate axes */ + useCoordinateSystem: boolean; + /** Whether the glyph is highlighted */ + highlighted: boolean; + /** Highlight color */ + highlightColor: number; +} + +/** + * Interface for glyph type renderers. + * Each glyph type (Star, Flower, Whisker, Thumb) implements this. + */ +export interface GlyphRenderer { + render(ctx: GlyphRenderContext, sizeInfo: GlyphSizeInfo, linearScale: boolean): THREE.Object3D; +} + +/** + * Registry of glyph renderers by type. + * Import individual renderers and register them here. + */ +const GLYPH_RENDERERS = new Map(); + +export function registerGlyphRenderer(type: GlyphType, renderer: GlyphRenderer): void { + GLYPH_RENDERERS.set(type, renderer); +} + +export function getGlyphRenderer(type: GlyphType): GlyphRenderer | undefined { + return GLYPH_RENDERERS.get(type); +} diff --git a/src/app/glyph/renderers/radar-chart.renderer.ts b/src/app/glyph/renderers/radar-chart.renderer.ts new file mode 100644 index 0000000..be967ba --- /dev/null +++ b/src/app/glyph/renderers/radar-chart.renderer.ts @@ -0,0 +1,67 @@ +import * as THREE from 'three'; +import { Line2 } from 'three/examples/jsm/lines/Line2.js'; +import { LineGeometry } from 'three/examples/jsm/lines/LineGeometry.js'; +import { LineMaterial } from 'three/examples/jsm/lines/LineMaterial.js'; +import { GlyphSizeInfo } from '../glyph-size-info'; +import { GlyphRenderer, GlyphRenderContext } from './glyph-renderer'; +import { addBackgroundCircle, addCoordinateAxes, addPlaceHolder } from './shared-rendering'; + +export class RadarChartRenderer implements GlyphRenderer { + render(ctx: GlyphRenderContext, sizeInfo: GlyphSizeInfo, linearScale: boolean): THREE.Object3D { + const group = new THREE.Group(); + addBackgroundCircle(group, sizeInfo, ctx); + + const { featureMap, keys, values, featureMaxValues, segments, color } = ctx; + if (keys.length === 0) return group; + + addCoordinateAxes(group, segments, sizeInfo, ctx); + if (addPlaceHolder(group, values, sizeInfo, color)) return group; + + const points: THREE.Vector2[] = []; + + keys.forEach((key, i) => { + const angle = (i / segments) * Math.PI * 2; + const value = +featureMap[key] || 0; + const maxVal = featureMaxValues[i] || 1; + const norm = linearScale ? value : value / maxVal; + const x = Math.cos(angle) * sizeInfo.radius * norm; + const y = Math.sin(angle) * sizeInfo.radius * norm; + points.push(new THREE.Vector2(x, y)); + }); + + // Fill shape + const shape = new THREE.Shape(points); + const fillMat = new THREE.MeshBasicMaterial({ + color: color, + side: THREE.DoubleSide, + transparent: true, + opacity: 0.6, + }); + group.add(new THREE.Mesh(new THREE.ShapeGeometry(shape), fillMat)); + + if (ctx.useContour) { + const closedPoints = [...points.map(p => new THREE.Vector3(p.x, p.y, 0))]; + closedPoints.push(closedPoints[0].clone()); + + const positions: number[] = []; + closedPoints.forEach(p => positions.push(p.x, p.y, p.z)); + + const lineGeom = new LineGeometry(); + lineGeom.setPositions(positions); + + const lineMat = new LineMaterial({ + color: color, + linewidth: sizeInfo.contourThickness, + transparent: true, + opacity: 0.9, + }); + + const line = new Line2(lineGeom, lineMat); + line.computeLineDistances(); + line.scale.set(1, 1, 1); + group.add(line); + } + + return group; + } +} diff --git a/src/app/glyph/renderers/shared-rendering.ts b/src/app/glyph/renderers/shared-rendering.ts new file mode 100644 index 0000000..6614e09 --- /dev/null +++ b/src/app/glyph/renderers/shared-rendering.ts @@ -0,0 +1,115 @@ +import * as THREE from 'three'; +import { GlyphSizeInfo } from '../glyph-size-info'; +import { ZoomLevel } from '../../shared/enum/zoom-level'; +import { GlyphRenderContext } from './glyph-renderer'; + +// Shared geometry cache for performance (reuse common geometries) +const geometryCache = { + circles: new Map(), + rings: new Map(), +}; + +// Shared material cache for performance (reuse materials by color + options) +const materialCache = new Map(); + +export function getCachedBasicMaterial( + color: string | number, + options?: { side?: THREE.Side; transparent?: boolean; opacity?: number; depthTest?: boolean } +): THREE.MeshBasicMaterial { + const key = `${color}_${options?.side ?? THREE.FrontSide}_${options?.transparent ?? false}_${options?.opacity ?? 1}_${options?.depthTest ?? true}`; + let mat = materialCache.get(key); + if (!mat) { + mat = new THREE.MeshBasicMaterial({ color, ...options }); + materialCache.set(key, mat); + } + return mat; +} + +export function getCachedCircleGeometry(radius: number, segments = 32): THREE.CircleGeometry { + const key = `${radius.toFixed(2)}_${segments}`; + let geom = geometryCache.circles.get(key); + if (!geom) { + geom = new THREE.CircleGeometry(radius, segments); + geometryCache.circles.set(key, geom); + } + return geom; +} + +export function getCachedRingGeometry(innerRadius: number, outerRadius: number, segments = 32): THREE.RingGeometry { + const key = `${innerRadius.toFixed(2)}_${outerRadius.toFixed(2)}_${segments}`; + let geom = geometryCache.rings.get(key); + if (!geom) { + geom = new THREE.RingGeometry(innerRadius, outerRadius, segments); + geometryCache.rings.set(key, geom); + } + return geom; +} + +export function addBackgroundCircle(group: THREE.Group, sizeInfo: GlyphSizeInfo, ctx: GlyphRenderContext): void { + const background = sizeInfo.currentZoomLevel === ZoomLevel.high && ctx.useBackground; + if (!background) return; + + const geom = getCachedCircleGeometry(sizeInfo.radius, 32); + const mat = new THREE.MeshBasicMaterial({ color: 0xf0f0f0 }); + if (ctx.highlighted) { + const color = new THREE.Color(ctx.highlightColor); + color.lerp(new THREE.Color(0xffffff), 0.6); + mat.color.copy(color); + } + group.add(new THREE.Mesh(geom, mat)); + + if (ctx.useContour) { + const ringWidth = sizeInfo.radius * 0.01; + const contourGeom = getCachedRingGeometry(sizeInfo.radius - ringWidth, sizeInfo.radius, 32); + const contourMat = new THREE.MeshBasicMaterial({ + color: 0xcccccc, + side: THREE.DoubleSide, + depthTest: false, + }); + const contour = new THREE.Mesh(contourGeom, contourMat); + contour.renderOrder = 999; + group.add(contour); + } +} + +export function addCoordinateAxes( + group: THREE.Group, + segments: number, + sizeInfo: GlyphSizeInfo, + ctx: GlyphRenderContext +): void { + const axes = sizeInfo.currentZoomLevel === ZoomLevel.high && ctx.useCoordinateSystem; + if (!axes) return; + + const axesColor = 0xa0a0a0; + const lineWidth = sizeInfo.contourThickness / 3; + for (let i = 0; i < segments; i++) { + const angle = (i / segments) * Math.PI * 2; + const geom = new THREE.PlaneGeometry(lineWidth, sizeInfo.radius); + geom.translate(0, sizeInfo.radius / 2, 0); + const mat = new THREE.MeshBasicMaterial({ color: axesColor, side: THREE.DoubleSide }); + const mesh = new THREE.Mesh(geom, mat); + mesh.rotation.z = angle - Math.PI / 2; + group.add(mesh); + } +} + +export function addPlaceHolder( + group: THREE.Group, + values: number[], + sizeInfo: GlyphSizeInfo, + trueColor: string | number +): boolean { + if (values.every(v => v <= 0.001)) { + const geom = getCachedCircleGeometry(sizeInfo.getRadius(ZoomLevel.low) / 4, 16); + const mat = new THREE.MeshBasicMaterial({ + color: trueColor, + side: THREE.DoubleSide, + transparent: true, + opacity: 0.6, + }); + group.add(new THREE.Mesh(geom, mat)); + return true; + } + return false; +} diff --git a/src/app/glyph/renderers/thumbnail.renderer.ts b/src/app/glyph/renderers/thumbnail.renderer.ts new file mode 100644 index 0000000..5797d26 --- /dev/null +++ b/src/app/glyph/renderers/thumbnail.renderer.ts @@ -0,0 +1,79 @@ +import * as THREE from 'three'; +import { GlyphSizeInfo } from '../glyph-size-info'; +import { GlyphRenderer, GlyphRenderContext } from './glyph-renderer'; +import { GlyphRenderConfig } from '../glyph-render-config'; +import { createGrayPlaceholderTexture } from '../../shared/helpers/three-helper'; + +/** + * Thumbnail renderer is special: it needs runtime config for loading images. + * Constructed with a GlyphRenderConfig snapshot rather than Angular services. + */ +export class ThumbnailRenderer implements GlyphRenderer { + constructor( + private glyphId: string, + private renderConfig: GlyphRenderConfig + ) {} + + render(_ctx: GlyphRenderContext, sizeInfo: GlyphSizeInfo, _linearScale: boolean): THREE.Object3D { + const placeholderTexture = createGrayPlaceholderTexture(); + const geom = new THREE.PlaneGeometry(sizeInfo.radius * 2, sizeInfo.radius * 2); + const mat = new THREE.MeshBasicMaterial({ map: placeholderTexture, transparent: true }); + const mesh = new THREE.Mesh(geom, mat); + + const file = `${this.renderConfig.loadedData}/${this.glyphId}.jpg`; + + if (this.renderConfig.dataSource === 'wasm' && this.renderConfig.thumbnailResolver) { + this.renderConfig.thumbnailResolver.requestThumb(file).subscribe(bitmap => { + if (bitmap) { + this.applyThumbnailTexture(bitmap, mesh, mat, sizeInfo); + } + }); + } else { + const image = new Image(); + image.src = `assets/thumbnails/${this.renderConfig.loadedData}/${this.glyphId}.jpg`; + image.crossOrigin = 'anonymous'; + + image.onload = () => { + this.applyThumbnailTexture(image, mesh, mat, sizeInfo); + }; + + image.onerror = () => { + console.warn(`Failed to load thumbnail from local: ${image.src}`); + }; + } + return mesh; + } + + private applyThumbnailTexture( + image: HTMLImageElement | ImageBitmap, + mesh: THREE.Mesh, + mat: THREE.MeshBasicMaterial, + sizeInfo: GlyphSizeInfo + ) { + const originalWidth = image.width; + const originalHeight = image.height; + + const maxDim = sizeInfo.radius * 3; + const widthRatio = maxDim / originalWidth; + const heightRatio = maxDim / originalHeight; + const scale = Math.min(widthRatio, heightRatio, 1); + + const finalWidth = originalWidth * scale; + const finalHeight = originalHeight * scale; + + const geom = new THREE.PlaneGeometry(finalWidth, finalHeight); + mesh.geometry.dispose(); + mesh.geometry = geom; + + const texture = new THREE.Texture(image); + texture.needsUpdate = true; + texture.minFilter = THREE.NearestFilter; + texture.magFilter = THREE.NearestFilter; + texture.colorSpace = THREE.SRGBColorSpace; + + mat.map = texture; + mat.needsUpdate = true; + + this.renderConfig.onReRender?.(); + } +} diff --git a/src/app/glyph/renderers/whisker-glyph.renderer.ts b/src/app/glyph/renderers/whisker-glyph.renderer.ts new file mode 100644 index 0000000..d72b2ab --- /dev/null +++ b/src/app/glyph/renderers/whisker-glyph.renderer.ts @@ -0,0 +1,49 @@ +import * as THREE from 'three'; +import { GlyphSizeInfo } from '../glyph-size-info'; +import { GlyphRenderer, GlyphRenderContext } from './glyph-renderer'; +import { addBackgroundCircle, addCoordinateAxes, addPlaceHolder } from './shared-rendering'; + +export class WhiskerGlyphRenderer implements GlyphRenderer { + render(ctx: GlyphRenderContext, sizeInfo: GlyphSizeInfo, linearScale: boolean): THREE.Object3D { + const group = new THREE.Group(); + addBackgroundCircle(group, sizeInfo, ctx); + + const { featureMap, keys, values, featureMaxValues, segments, color } = ctx; + if (keys.length === 0) return group; + + addCoordinateAxes(group, segments, sizeInfo, ctx); + if (addPlaceHolder(group, values, sizeInfo, color)) return group; + + keys.forEach((key, i) => { + const value = +featureMap[key] || 0; + if (value <= 0) return; + + const maxVal = featureMaxValues[i] || 1; + const norm = linearScale ? value : value / maxVal; + const whiskerLength = sizeInfo.radius * norm; + + const barWidth = 0.8; + const barHeight = whiskerLength; + + const angle = (i / segments) * Math.PI * 2; + const container = new THREE.Object3D(); + container.rotation.z = angle - (3 * Math.PI) / 2; + + const geom = new THREE.PlaneGeometry(barWidth, barHeight); + const mat = new THREE.MeshBasicMaterial({ + color, + transparent: true, + opacity: 0.8, + side: THREE.DoubleSide, + depthWrite: false, + }); + const mesh = new THREE.Mesh(geom, mat); + + mesh.position.y = -barHeight / 2; + container.add(mesh); + group.add(container); + }); + + return group; + } +} diff --git a/src/app/menubar/histogram/histogram.component.html b/src/app/menubar/histogram/histogram.component.html deleted file mode 100644 index 3ba702d..0000000 --- a/src/app/menubar/histogram/histogram.component.html +++ /dev/null @@ -1,15 +0,0 @@ -
-
- {{ label }} -
- {{ type }} - -
-
-
-
\ No newline at end of file diff --git a/src/app/menubar/histogram/histogram.component.scss b/src/app/menubar/histogram/histogram.component.scss deleted file mode 100644 index aab72a2..0000000 --- a/src/app/menubar/histogram/histogram.component.scss +++ /dev/null @@ -1,115 +0,0 @@ -@use '../../../styles/variables' as v; - -.histogram-item { - display: flex; - flex-direction: column; - width: 100%; - margin-bottom: 12px; - - .histogram-label { - font-size: 14px; - color: v.$gray-700; - margin-top: 6px; - margin-bottom: 4px; - display: flex; - align-items: center; - - .right-controls { - margin-left: auto; - /* ← pushes tag + button to the right */ - display: inline-flex; - align-items: center; - gap: 6px; - } - - .type-tag { - font-size: 0.55rem; - font-weight: 600; - text-transform: uppercase; - letter-spacing: 0.05em; - - padding: 0.25rem 0.4rem; - background-color: #e0e0e0; - /* light gray */ - color: #555; - - border-radius: 0.4rem; - line-height: 1; - - margin-left: auto; - } - } - - .histogram-container { - position: relative; - width: 100%; - height: 60px; - background: #f5f5f5; - border-radius: 8px; - box-sizing: border-box; - } - - .histogram-container svg rect { - pointer-events: all; - /* ensure rects can receive events */ - } - - .hist-tooltip { - pointer-events: none; - } - - .color-container { - margin-top: 2px; - width: 100%; - pointer-events: none; // purely visual - } - - .color-container svg { - display: block; - } - - .expander { - margin-left: auto; - /* ← push to the right */ - - display: inline-flex; - align-items: center; - gap: 6px; - - padding: 3px 3px; - - border-radius: 6px; - border: 1px solid #cfcfcf; - - background: #ffffff; - color: v.$gray-800; - - font-size: 10px; - font-weight: 500; - - cursor: pointer; - user-select: none; - - transition: - background-color 120ms ease, - border-color 120ms ease, - color 120ms ease, - box-shadow 120ms ease; - } - - .expander:hover { - border-color: #b5b5b5; - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08); - } - - .expander.active { - background: v.$color-blue-highlight; - border-color: #6aa9ff; - color: white; - } - - .expander i.material-icons { - font-size: 10px; - line-height: 1; - } -} \ No newline at end of file diff --git a/src/app/menubar/histogram/histogram.component.ts b/src/app/menubar/histogram/histogram.component.ts deleted file mode 100644 index 83a8c4d..0000000 --- a/src/app/menubar/histogram/histogram.component.ts +++ /dev/null @@ -1,529 +0,0 @@ -import { Component, Input, OnInit, ElementRef, ViewChild, AfterViewInit, OnChanges, SimpleChanges, Output, EventEmitter } from '@angular/core'; -import * as d3 from 'd3'; -import { ItemFilter } from '../../shared/filter/item-filter'; -import { FeatureFilter } from '../../shared/filter/feature-filter'; -import { FilterMode } from '../../shared/enum/filter-mode'; -import { Subscription } from 'rxjs'; -import { COLOR_SCALES, ColorScale } from '../../shared/interfaces/color-scale'; -import { DataProviderService } from '../../services/dataprovider.service'; -import { GlyphMeta } from '../../shared/interfaces/glyph-meta'; -import { CategoryFilter } from '../../shared/filter/category-filter'; -import { InteractionCommand } from '../../shared/enum/interaction-command'; -import { Histogram, StackedBin } from '../../shared/types/histogram.types'; -import { - prepareStackedBinsFromObject, - getEffectiveHistogramType -} from '../../shared/utils/histogram.utils'; - -// Re-export for backward compatibility -export type { Histogram } from '../../shared/types/histogram.types'; - -@Component({ - selector: 'app-histogram', - templateUrl: './histogram.component.html', - styleUrls: ['./histogram.component.scss'] -}) -export class HistogramComponent implements OnInit, AfterViewInit, OnChanges { - @Input() histogramData!: Histogram; - @Input() categories: string[] | undefined; - @Input() label!: string; - @Input() type!: string; - @Input() property!: string; - @Input() featureMin: number = 0; - @Input() featureMax: number = 1; - - @Input() configuration: any; - @Input() dataProvider: any; - - @Output() selectionChanged = new EventEmitter<{ property: string, minBin: number, maxBin: number }>(); - - @ViewChild('histogramContainer', { static: true }) histogramContainer!: ElementRef; - - private configSub = new Subscription(); - - private filter!: ItemFilter; - private categoryFilter!: CategoryFilter; - - active = false; - - private svg: any; - private margin = { top: 6, right: 6, bottom: 6, left: 6 }; - private width = 300; - private height = 60; - private innerHeight = 60; - - private xScale: any; - private yScale: any; - private brush: any; - private brushSelection: [number, number] | null = null; - private selectedBins = new Set(); - private cachedStackedBins: StackedBin[] | null = null; - private binToCategory = new Map(); - - private defaultBarColor = '#333'; // dark gray - private colorScale: ColorScale = COLOR_SCALES[0]; - - constructor() { } - - ngOnInit(): void { - this.filter = new FeatureFilter(this.property); - this.categoryFilter = new CategoryFilter(this.property); - this.categoryFilter.filterMode = FilterMode.And; - this.filter.filterMode = FilterMode.And; - this.createHistogram(); - } - - ngAfterViewInit(): void { - this.configSub.add( - this.configuration.glyphConfigSubject$.subscribe(() => { - this.colorScale = COLOR_SCALES.find(cs => cs.id === this.configuration.colorRange) || COLOR_SCALES[0]; - this.updateChart(); - }) - ); - this.configSub.add( - this.configuration.loadedDataSubject$.subscribe(() => { - this.brushSelection = null; - this.selectedBins.clear(); - }) - ); - this.configSub.add( - this.configuration.commandSubject$.subscribe((command: InteractionCommand) => { - if (command == InteractionCommand.clearselection) { - this.brushSelection = null; - this.selectedBins.clear(); - this.updateChart(); - } - }) - ); - } - - ngOnDestroy(): void { - if (this.svg) { - this.svg.remove(); // removes the appended element - this.svg = null; - } - d3.select(this.histogramContainer!.nativeElement).select('svg').remove(); - this.configSub.unsubscribe(); - } - - ngOnChanges(changes: SimpleChanges): void { - if (changes['histogramData'] && !changes['histogramData'].firstChange) { - this.updateChart(); - } - } - - public changed(): void { - this.active = !this.active; - const index = this.configuration.activeFeatures.indexOf(this.property); - if (this.active && index < 0) { - this.configuration?.activeFeatures.push(this.property); - } else if (index >= 0) { - this.configuration?.activeFeatures.splice(index, 1); - } - - this.configuration?.updateConfiguration(); - } - - private createHistogram(): void { - const container = this.histogramContainer.nativeElement; - this.width = container.clientWidth - this.margin.left - this.margin.right; - this.innerHeight = this.height - this.margin.top - this.margin.bottom; - - this.svg = d3.select(container) - .append('svg') - .attr('width', this.width + this.margin.left + this.margin.right) - .attr('height', this.height) - .append('g') - .attr('transform', `translate(${this.margin.left},${this.margin.top})`); - - this.updateChart(); - } - - private updateChart(): void { - if (!this.svg || !this.histogramData) return; - - // Clear cached bins when data changes - this.cachedStackedBins = null; - this.active = this.configuration.activeFeatures.indexOf(this.property) >= 0; - - this.svg.selectAll('*').remove(); - - // Validate and infer effective type based on data characteristics - const effectiveType = this.getEffectiveType(); - - if (effectiveType === 'numeric') { - this.drawNumericHistogram(); - } else { - this.drawCategoricalStack(); - } - } - - /** - * Determine the effective rendering type based on declared type and data characteristics. - * If categorical type has too many bins, fall back to numeric histogram. - * Uses cached stacked bins to avoid duplicating prepareStackedBins logic. - */ - private getEffectiveType(): string { - // Prepare stacked bins once and cache for reuse - if (!this.cachedStackedBins) { - this.cachedStackedBins = this.prepareStackedBins(); - } - - const nonZeroBinCount = this.cachedStackedBins.length; - const effectiveType = getEffectiveHistogramType(this.type, nonZeroBinCount); - - if (this.type === 'categorical' && effectiveType === 'numeric') { - console.warn( - `Feature "${this.property}" has ${nonZeroBinCount} categories (>40), rendering as numeric histogram` - ); - } - - return effectiveType; - } - - private prepareStackedBins(): StackedBin[] { - return prepareStackedBinsFromObject(this.histogramData, { availableWidth: this.width }); - } - - private updateCategoricalSelection( - bars: d3.Selection, - totalBins: number - ): void { - if (this.selectedBins.size === 0) { - bars.attr('fill', (d: { bin: number }) => - this.getBarColor(d.bin, totalBins) - ); - } else { - bars.attr('fill', (d: { bin: number }) => - this.selectedBins.has(d.bin) - ? this.getBarColor(d.bin, totalBins) - : '#bdbdbd' - ); - } - - this.filteringFromBins(Array.from(this.selectedBins)); - } - - private drawCategoricalStack(): void { - if (!this.histogramData || !this.svg) return; - - // Clear brush selection when switching to categorical mode - this.brushSelection = null; - - // Use cached bins if available, otherwise prepare them - const bins = this.cachedStackedBins || this.prepareStackedBins(); - this.buildBinCategoryMap(); - const tooltip = this.createTooltip(); - - this.svg.selectAll('*').remove(); - - const originalBinCount = Object.keys(this.histogramData).length; - - const bars = this.svg - .selectAll('rect') - .data(bins) - .enter() - .append('rect') - .attr('x', (d: { x0: number; }) => d.x0) - .attr('y', 0) - .attr('width', (d: { x1: number; x0: number; }) => (d.x1 - d.x0)) - .attr('height', this.innerHeight) - .attr('rx', 3) - .attr('ry', 3) - .attr('fill', (d: { bin: number; }) => this.getBarColor(d.bin, originalBinCount)) - .style('cursor', 'pointer') - .on('mousemove', (event: MouseEvent) => { - const rect = event.currentTarget as SVGRectElement; - const d = d3.select(rect).datum(); - - const [x, y] = d3.pointer(event, this.histogramContainer.nativeElement); - - tooltip - .style('opacity', 1) - .text(`${this.getCategoricalValue(d.bin, d.value)}`) - .style('left', `${x + 10}px`) - .style('top', `${y - 8}px`); - }) - .on('mouseleave', () => { - tooltip.style('opacity', 0); - }) - .on('click', (event: MouseEvent, d: { bin: number }) => { - event.stopPropagation(); - - if (this.selectedBins.has(d.bin)) { - // Deselect - this.selectedBins.delete(d.bin); - } else { - // Select - this.selectedBins.add(d.bin); - } - - this.updateCategoricalSelection(bars, originalBinCount); - }); - - this.updateCategoricalSelection(bars, originalBinCount); - } - - private buildBinCategoryMap() { - this.binToCategory.clear(); - if (!this.categories?.length) return; - - const nonZeroBins = Object.entries(this.histogramData) - .filter(([, v]) => v !== 0) - .map(([k]) => +k); - - // Optional safety check - if (nonZeroBins.length !== this.categories.length) { - console.warn( - 'Histogram/category length mismatch', - nonZeroBins.length, - this.categories.length - ); - } - - nonZeroBins.forEach((bin, i) => { - if (this.categories && this.categories[i] !== undefined) { - this.binToCategory.set(bin, this.categories[i]); - } - }); - } - - private getCategoricalValue(bin: number, value: number) { - return this.binToCategory.get(bin) ?? value; - } - - private drawNumericHistogram(): void { - if (!this.histogramData || !this.svg) return; - - // Clear categorical selection when switching to numeric mode - this.selectedBins.clear(); - - const bins = Object.keys(this.histogramData) - .map(k => ({ bin: +k, value: this.histogramData[k] })); - - this.xScale = d3.scaleLinear() - .domain([0, bins.length]) - .range([0, this.width]); - - const maxVal = d3.max(bins, d => d.value) || 1; - - this.yScale = d3.scaleLinear() - .domain([0, maxVal]) - .range([this.innerHeight, 0]); - - const tooltip = this.createTooltip(); - - const bars = this.svg.selectAll('rect') - .data(bins) - .join('rect') - .attr('x', (d: { bin: any; }) => this.xScale(d.bin)) - .attr('y', (d: { value: any; }) => this.yScale(d.value)) - .attr('width', this.xScale(1) - this.xScale(0) - 1) - .attr('height', (d: { value: any; }) => this.innerHeight - this.yScale(d.value)) - .attr('fill', (d: { bin: number }) => this.getBarColor(d.bin, bins.length)) - .attr('rx', 3) // horizontal corner radius - .attr('ry', 3) - - this.brush = d3.brushX() - .extent([[0, 0], [this.width, this.innerHeight]]) - .on('end', ({ selection }: { selection: [number, number] | null }) => { - // save the current selection - this.brushSelection = selection; - - if (!selection) { - bars.attr('fill', (d: { bin: number }) => - this.getBarColor(d.bin, bins.length) - ); - - this.removeFilter(); - return; - } - const [x0, x1] = selection; - const minBin = Math.round(this.xScale.invert(x0)); - const maxBin = Math.round(this.xScale.invert(x1)); - - bars.attr('fill', (d: { bin: number }) => - d.bin >= minBin && d.bin <= maxBin - ? this.getBarColor(d.bin, bins.length) - : '#bdbdbd' - ); - - this.filtering(selection); - }); - - const brushG = this.svg.append('g') - .attr('class', 'brush') - .call(this.brush) - .on('mousemove', (event: MouseEvent) => { - const [x, y] = d3.pointer(event, this.svg.node()); - const bin = Math.floor(this.xScale.invert(x)); - const binData = bins.find(b => b.bin === bin); - if (!binData) return; - - tooltip.style('opacity', 1) - .text(`Bin ${binData.bin}: ${binData.value.toPrecision(4)}`) - .style('left', `${x + this.margin.left + 10}px`) - .style('top', `${y + this.margin.top - 10}px`); - }) - .on('mouseout', (_event: MouseEvent) => { - tooltip.style('opacity', 0); - }); - - // restore previous selection if it exists - if (this.brushSelection) { - brushG.call(this.brush.move, this.brushSelection); - } - } - - private createTooltip(): d3.Selection { - const container = this.histogramContainer.nativeElement; - // Remove any previous tooltip - d3.select(container).selectAll('.hist-tooltip').remove(); - - // Append tooltip div - const tooltip = d3.select(container) - .append('div') - .attr('class', 'hist-tooltip') - .style('position', 'absolute') - .style('pointer-events', 'none') - .style('opacity', 0) - .style('background', 'rgba(0,0,0,0.7)') - .style('color', 'white') - .style('padding', '2px 6px') - .style('border-radius', '4px') - .style('font-size', '12px') - .style('z-index', '950'); // ensure it's above the SVG - - return tooltip - } - - private getBarColor(bin: number, binCount: number): string { - if (!this.colorScale || this.configuration.colorFeature !== this.property) { - return this.defaultBarColor; - } - - const t = binCount > 1 ? bin / (binCount - 1) : 0; - return this.colorScale.scale(t); - } - - private filteringFromBins(selectedBins: number[]): void { - const filters = this.dataProvider.getFilters(); - if (!filters.includes(this.filter)) { - this.dataProvider.getFilters().push(this.filter); - } - if (!filters.includes(this.categoryFilter)) { - this.dataProvider.getFilters().push(this.categoryFilter); - } - - if (!selectedBins || selectedBins.length === 0) { - this.categoryFilter.clear(); - this.filter.clear(); - this.dataProvider.refreshFilters(); - this.configuration.redraw(); - return; - } - - const effectiveType = this.getEffectiveType(); - const totalBins = Object.keys(this.histogramData).length; - - if (effectiveType === 'categorical') { - // For categorical: Filter by actual feature values - // Values can be either normalized [0,1] or raw integers depending on scaling config - this.categoryFilter.clear(); - - // Get the number of actual categories from the non-zero bins - const nonZeroBins = Object.entries(this.histogramData) - .filter(([, v]) => v !== 0) - .map(([k]) => +k) - .sort((a, b) => a - b); - - const numCategories = nonZeroBins.length; - - // Determine if data is raw label-encoded integers (not normalized) - // Raw integers: min=0, max=numCategories-1 (e.g., 0,1,2,3,4 for 5 categories) - // Normalized: any other pattern (data was scaled to [0,1]) - const isRawIntegers = this.featureMin === 0 && - this.featureMax === numCategories - 1 && - numCategories > 1; - - selectedBins.forEach(bin => { - // Find which category index this bin corresponds to - const categoryIndex = nonZeroBins.indexOf(bin); - - if (categoryIndex === -1) { - return; - } - - let filterMin: number; - let filterMax: number; - - if (isRawIntegers) { - // Data is raw integers: category index IS the value - // With tolerance for float comparison - filterMin = categoryIndex - 0.5; - filterMax = categoryIndex + 0.5; - } else { - // Data is normalized [0,1]: use category index to compute normalized value - // category i → i / (N-1) for N categories - const normalizedValue = numCategories === 1 ? 0 : categoryIndex / (numCategories - 1); - const tolerance = 0.01; - filterMin = Math.max(0, normalizedValue - tolerance); - filterMax = Math.min(1, normalizedValue + tolerance); - } - - this.categoryFilter.addRange(filterMin, filterMax); - }); - } else { - // For numeric: Filter by continuous range - // Bins represent ranges of continuous values - this.filter.clear(); - - const steps = 1 / totalBins; - - selectedBins.forEach(bin => { - (this.filter as FeatureFilter).minValue = bin * steps; - (this.filter as FeatureFilter).maxValue = Math.min((bin + 1) * steps, 1.0); - }); - } - - this.dataProvider.refreshFilters(); - this.configuration.redraw(); - } - - private filtering(selection: any): void { - if (selection === null || selection === undefined) { - return; - } - - const filters = this.dataProvider.getFilters(); - if (!filters.includes(this.filter)) { - this.dataProvider.getFilters().push(this.filter); - } - - const absoluteMinValue: number = +d3.min(selection)!; - const absoluteMaxValue: number = +d3.max(selection)!; - - const relativeMinValue: number = absoluteMinValue / this.width; - const relativeMaxValue: number = absoluteMaxValue / this.width; - - // TODO: Workaround because data is not bound to actual bars in chart - - const steps = 1 / Object.keys(this.histogramData).length; - let minValue = Math.floor(relativeMinValue / steps) * steps; - let maxValue = (Math.floor(relativeMaxValue / steps) + 1) * steps; - - (this.filter as FeatureFilter).minValue = minValue; - (this.filter as FeatureFilter).maxValue = Math.min(maxValue, 1.0); - - this.dataProvider.refreshFilters(); - this.configuration.redraw(); - } - - public removeFilter() { - this.filter.clear(); - const pos = this.dataProvider.getFilters().indexOf(this.filter); - if (pos >= 0) this.dataProvider.getFilters().splice(pos, 1); - this.dataProvider.refreshFilters(); - this.configuration.redraw(); - } -} diff --git a/src/app/menubar/legend-dropdown/legend-dropdown.component.html b/src/app/menubar/legend-dropdown/legend-dropdown.component.html deleted file mode 100644 index 9bcff29..0000000 --- a/src/app/menubar/legend-dropdown/legend-dropdown.component.html +++ /dev/null @@ -1,56 +0,0 @@ -
-
- - -
- -
- - -
- Total items  - {{ dataProvider.totalItems }} - - {{ dataProvider.filteredItems - }} - Filtered Items  -
- - - - - -
- -
- - -
-
-
- -
-
\ No newline at end of file diff --git a/src/app/menubar/legend-dropdown/legend-dropdown.component.scss b/src/app/menubar/legend-dropdown/legend-dropdown.component.scss deleted file mode 100644 index e33bc3b..0000000 --- a/src/app/menubar/legend-dropdown/legend-dropdown.component.scss +++ /dev/null @@ -1,185 +0,0 @@ -@use '../../../styles/variables' as v; -@use '../../../styles/mixins' as m; - -.legend-dropdown { - position: absolute; - top: 100%; - left: 0; - box-sizing: border-box; - - background: white; - - border-radius: 0 0 12px 12px; - border: 1px solid #e5e5e5; - border-top: none; - - box-shadow: 0 12px 32px rgba(0, 0, 0, 0.12); - - transform-origin: top left; - transform: scaleY(0); - opacity: 0; - - transition: - transform 0.25s ease, - opacity 0.2s ease; - - z-index: 900; - // overflow: hidden; - - &.open { - transform: scaleY(1); - opacity: 1; - } -} - -.menu-label { - font-size: 12px; - font-weight: 300; - color: v.$gray-600; - letter-spacing: 0.05em; - text-transform: uppercase; - margin-bottom: 8px; -} - -.menu-header { - display: flex; - align-items: center; - justify-content: space-between; - margin-bottom: 0.5rem; -} - -.clear-filters-btn { - background: none; - border: none; - cursor: pointer; - font-size: 0.85rem; - opacity: 0.7; - padding: 0; -} - -.clear-filters-btn:hover { - opacity: 1; -} - -.legend-content { - padding: 16px; - max-height: calc(90vh - 64px); - overflow-x: hidden; - overflow-y: auto; - - .glyph-visualization { - width: 328px; - height: 190px; - border: 1px solid v.$gray-300; - border-radius: 8px; - background-color: v.$gray-100; - margin-bottom: 16px; - } - - .dashboard-infos { - padding-left: 0px; - padding-right: 10px; - font-size: 14px; - margin-bottom: 16px; - - .right { - float: right; - } - } - - .dashboard-search { - position: relative; - padding-bottom: 18px; - - input { - box-sizing: border-box; - width: 100%; - margin-right: 5px; - padding: 8px; - font-size: 14px; - border: 1px solid v.$gray-500; - border-radius: 8px; - background-color: white; - color: v.$gray-800; - outline: none; - - &::placeholder { - color: v.$gray-500; - } - } - - .clear-btn { - all: unset; - position: absolute; - top: 10%; - right: 9px; - width: 24px; - height: 24px; - display: flex; - align-items: center; - justify-content: center; - cursor: pointer; - - i.material-icons { - font-size: 20px; - color: v.$gray-600; - } - - &:hover i { - color: v.$gray-800; - } - - @include m.tooltip-below(4px); - - &:disabled { - pointer-events: none; - opacity: 0.5; - } - } - - .search-term-list { - position: absolute; - // top: 0%; - left: 0; - right: 0; - margin: 0px; - margin-top: -1px; - padding: 4px; - background: white; - border: 1px solid v.$gray-400; - border-radius: 8px; - box-shadow: 0 2px 3px rgba(0, 0, 0, 0.1); - z-index: 100; - - li { - display: flex; - justify-content: space-between; - align-items: center; - padding: 4px 6px; - border-bottom: 1px solid v.$gray-400; - font-size: 13px; - color: v.$gray-800; - - &:last-child { - border-bottom: none; - } - - .remove-btn { - all: unset; - cursor: pointer; - display: flex; - align-items: center; - - i.material-icons { - font-size: 20px; - color: v.$gray-500; - } - - &:hover i { - color: v.$gray-700; - } - } - } - } - } -} \ No newline at end of file diff --git a/src/app/menubar/legend-dropdown/legend-dropdown.component.ts b/src/app/menubar/legend-dropdown/legend-dropdown.component.ts deleted file mode 100644 index 63c768c..0000000 --- a/src/app/menubar/legend-dropdown/legend-dropdown.component.ts +++ /dev/null @@ -1,220 +0,0 @@ -import { Component, ElementRef, inject, Input, NgZone, ViewChild } from '@angular/core'; -import { LoggerService } from '../../services/logger-service'; -import { ConfigService } from '../../services/config.service'; -import { DataProcessorService } from '../../services/data-processor'; -import { DataProviderService } from '../../services/dataprovider.service'; -import { Subscription } from 'rxjs'; -import { drawFlowerGlyph, drawRadarChart, drawWhiskerGlyph, hexToRgb } from '../../shared/helpers/d3-helper'; -import { GlyphObject } from '../../glyph/glyph-object'; -import { GlyphType } from '../../shared/enum/glyph-type'; -import { TextFilter } from '../../shared/filter/text-filter'; -import { FilterMode } from '../../shared/enum/filter-mode'; -import { CommonModule } from '@angular/common'; -import { FormsModule } from '@angular/forms'; -import { FeaturesData } from '../../shared/interfaces/glyph-meta'; -import { GlyphSchema } from '../../shared/interfaces/glyph-schema'; -import { HistogramComponent } from '../histogram/histogram.component'; - -@Component({ - selector: 'app-legend-dropdown', - standalone: true, - imports: [CommonModule, FormsModule, HistogramComponent], - templateUrl: './legend-dropdown.component.html', - styleUrls: ['./legend-dropdown.component.scss'], -}) -export class LegendDropdownComponent { - @ViewChild('glyphCanvas') glyphCanvas?: ElementRef; - - @Input() open = false; - @Input() width = 360; - - dataProvider: DataProviderService - config: ConfigService - - glyphContext!: CanvasRenderingContext2D; - lastGlyph: GlyphObject | null = null; - colorFeature = ""; - - searchTerm = ""; - searchTerms: string[] = []; - inputFocused = false; - private textFilter = new TextFilter(); - - features: FeaturesData = {}; - featureIds: string[] = []; - schema?: GlyphSchema; - - private configSub = new Subscription(); - private ngZone!: NgZone; - - constructor(private logger: LoggerService, private dataProcessor: DataProcessorService) { - this.dataProvider = inject(DataProviderService); - this.config = inject(ConfigService), - this.ngZone = inject(NgZone); - - this.config.loadedDataSubject$.subscribe(async data => { - if (data == "") return; - - const metaData = await this.dataProvider.getMetaData(); - this.schema = await this.dataProvider.getSchema(); - if (metaData?.features) { - this.ngZone.run(() => { - this.features = metaData.features; - this.featureIds = Object.keys(this.features); - }); - } - }); - } - - ngAfterViewInit() { - this.configSub.add( - this.config.glyphConfigSubject$.subscribe(() => { - this.ngZone.run(() => { - const newFeature = this.config.featureLabels[this.config.colorFeature]; - if (newFeature) this.colorFeature = newFeature; - }); - - if (this.lastGlyph == null) return; - this.drawLegendGlyph(this.lastGlyph); - }) - ); - this.configSub.add( - this.config.animateGlyphSubject$.subscribe(glyph => { - if (glyph == null) return; - - this.drawLegendGlyph(glyph); - }) - ); - this.configSub.add( - this.config.loadedDataSubject$.subscribe(async data => { - const schema = await this.dataProvider.getSchema(); - this.ngZone.run(() => { - if (schema) this.colorFeature = schema.label[this.config.colorFeature]; - }); - this.drawLegendGlyph(null); - }) - ); - - this.setupGlyphCanvas(); - } - - ngOnDestroy(): void { - this.configSub.unsubscribe(); - } - - private setupGlyphCanvas() { - const canvas = this.glyphCanvas?.nativeElement; - const context = canvas.getContext('2d'); - - if (!context) return; - - const dpr = window.devicePixelRatio || 1; - - // Define the *logical* size you want the canvas to be (CSS pixels) - const logicalWidth = 600; - const logicalHeight = 400; - - // Set physical pixel size scaled by DPR - canvas.width = logicalWidth * dpr; - canvas.height = logicalHeight * dpr; - - // Set CSS size so it looks correct on screen - canvas.style.width = `${logicalWidth}px`; - canvas.style.height = `${logicalHeight}px`; - - // Scale the drawing context - context.scale(dpr, dpr); - } - - async drawLegendGlyph(glyph: GlyphObject | null) { - if (glyph == null) { - const data = await this.dataProvider.getGlyphData(); - if (data) glyph = data[Math.floor(Math.random() * data.length)]; - } - - if (glyph == null) return; - - const currentColor = this.config.getRgbaColor(glyph.features); - - const element = this.glyphCanvas?.nativeElement; - this.glyphContext = element.getContext('2d'); - - // Get the device pixel ratio - const ratio = window.devicePixelRatio || 1; - this.glyphContext.save(); - this.glyphContext.clearRect(0, 0, 328 * ratio, 180 * ratio); - - if (this.config.getConfiguration().glyphType == GlyphType.Star) { - drawRadarChart(this.glyphContext, 50, currentColor, glyph, this.config.activeFeatures, this.config.featureLabels, this.config.getConfiguration()); - } else if (this.config.getConfiguration().glyphType == GlyphType.Whisker) { - drawWhiskerGlyph(this.glyphContext, 50, currentColor, glyph, this.config.activeFeatures, this.config.featureLabels, this.config.getConfiguration()); - } else { - drawFlowerGlyph(this.glyphContext, 50, currentColor, glyph, this.config.activeFeatures, this.config.featureLabels, this.config.getConfiguration()); - } - - this.glyphContext.restore(); - - this.lastGlyph = glyph; - } - - updateTextFilter() { - const pos = this.dataProvider.getFilters().indexOf(this.textFilter); - if (pos < 0) { - this.textFilter.filterMode = FilterMode.And; - this.dataProvider.getFilters().push(this.textFilter); - } - this.textFilter.clear(); - if (this.searchTerms.length > 0) { - this.textFilter.extendacceptableStrings(this.searchTerms); - } - this.dataProvider.refreshFilters(); - this.config.redraw(); - } - - onSearchEnter(): void { - if (!this.searchTerms.includes(this.searchTerm.trim())) { - this.searchTerms.push(this.searchTerm.trim()); - } - this.searchTerm = ''; - this.inputFocused = true; - this.updateTextFilter(); - } - - clearSearch(input: HTMLInputElement): void { - this.searchTerm = ''; - this.searchTerms.splice(0, this.searchTerms.length); - input.focus(); - this.updateTextFilter(); - } - - removeTerm(index: number): void { - this.searchTerms.splice(index, 1); - this.updateTextFilter(); - } - - onFocus(): void { - this.inputFocused = true; - } - - onBlur(): void { - // Optional delay to allow button clicks before hiding - setTimeout(() => this.inputFocused = false, 150); - } - - trackByFeatureId(index: number, featureId: string): string { - return featureId; - } - - getFeatureName(id: string) { - return this.schema?.label[id] || ""; - } - - getFeatureType(id: string) { - return this.schema?.types ? this.schema?.types[id] || "" : ""; - } - - clearFilters() { - this.dataProvider.clearFilters(); - this.config.clearSelection(); - } -} diff --git a/src/app/menubar/menubar.component.html b/src/app/menubar/menubar.component.html index 57dbdf8..767e775 100644 --- a/src/app/menubar/menubar.component.html +++ b/src/app/menubar/menubar.component.html @@ -1,77 +1,72 @@ @if (showWizard) { -
- -
-} \ No newline at end of file +
+ +
+} diff --git a/src/app/menubar/menubar.component.scss b/src/app/menubar/menubar.component.scss index 5ae0e7c..db6d24b 100644 --- a/src/app/menubar/menubar.component.scss +++ b/src/app/menubar/menubar.component.scss @@ -1,369 +1,333 @@ @use '../../styles/variables' as v; .menu-bar { - display: flex; - flex-direction: row; - align-items: center; - height: 64px; - padding: 0 18px; - background: white; - border-bottom: 1px solid #ddd; + display: flex; + flex-direction: row; + align-items: center; + height: 64px; + padding: 0 18px; + background: white; + border-bottom: 1px solid v.$gray-200; } .menu-top-row { - display: flex; - flex: 1; - align-items: center; + display: flex; + flex: 1; + align-items: center; } /* LEFT stays left */ .menu-left { - flex: 0 0 auto; + flex: 0 0 auto; } /* THIS fills remaining space */ .menu-collapsible { - display: flex; - align-items: center; - flex: 1; - /* ← critical */ - min-width: 0; + display: flex; + align-items: center; + flex: 1; + /* ← critical */ + min-width: 0; } /* CENTER grows normally */ .menu-center { - // display: flex; - // align-items: center; - // gap: 24px; - position: absolute; - left: 50%; - transform: translateX(-70%); + position: absolute; + left: 50%; + transform: translateX(-70%); - display: flex; - align-items: center; - gap: 24px; -} - -/* RIGHT pushed all the way */ -.menu-right { - margin-left: auto; - /* ← critical */ + display: flex; + align-items: center; + gap: 24px; } /* hamburger hidden on desktop */ .hamburger { - display: none; + display: none; } .logo { - display: flex; - align-items: center; - gap: 8px; + display: flex; + align-items: center; + gap: 8px; + + img { + width: 28px; + height: 28px; + } + + .title { + font-size: 18px; + font-weight: 600; + } +} - img { - width: 28px; - height: 28px; - } +.dataset-selector { + display: flex; + align-items: center; + gap: 4px; +} - .title { - font-size: 18px; - font-weight: 600; - } +.delete-btn { + display: flex; + align-items: center; + justify-content: center; + width: 32px; + height: 32px; + border: none; + background: transparent; + border-radius: 8px; + cursor: pointer; + color: v.$color-gray-border; + padding: 0; + + &:hover { + background: v.$delete-hover-bg; + color: v.$delete-hover-text; + } + + .material-icons { + font-size: 18px; + } } .data-control { - display: flex; - align-items: center; - gap: 6px; - - .label { - font-size: 14px; - } + display: flex; + align-items: center; + gap: 6px; - select { - appearance: none; - /* Remove native arrow */ - -webkit-appearance: none; - -moz-appearance: none; - - padding: 6px 12px; - border-radius: 10px; - border: none; - background-color: #f2f2f2; - color: #333; - font-size: 14px; - cursor: pointer; - - display: inline-flex; - align-items: center; - - /* subtle hover effect */ - &:hover { - background-color: #e6e6e6; - } - - /* focus outline for accessibility */ - &:focus { - outline: 2px solid #c7d2fe; - outline-offset: 2px; - } - } - - /* Optional: add a custom arrow */ - select { - height: 32px; - line-height: 1.2; - background-image: url("data:image/svg+xml;utf8,"); - background-repeat: no-repeat; - background-position: right 8px center; - background-size: 16px 16px; - padding-right: 32px; - /* make room for arrow */ - } -} + .label { + font-size: 14px; + } + select { + appearance: none; -.icon-panel { - display: flex; - gap: 6px; - padding: 4px; - background: #f2f2f2; + padding: 6px 12px; border-radius: 10px; + border: none; + background-color: v.$gray-100; + color: v.$gray-800; + font-size: 14px; + cursor: pointer; - button { - display: flex; - align-items: center; - gap: 6px; - - border: none; - background: transparent; - padding: 6px 10px; - border-radius: 8px; - cursor: pointer; - - font-size: 14px; - color: #333; - - &:hover { - background: #e0e0e0; - } - - .material-icons { - font-size: 18px; - } - } -} - -.canvas-control { - display: flex; + display: inline-flex; align-items: center; - gap: 8px; - .label { - font-size: 14px; + /* subtle hover effect */ + &:hover { + background-color: v.$gray-200; } - .add-btn { - display: flex; - align-items: center; - gap: 4px; - - border: none; - padding: 6px 12px; - border-radius: 10px; - background: #f2f2f2; - cursor: pointer; - - &:hover { - background: #e6e6e6; - } + /* focus outline for accessibility */ + &:focus { + outline: 2px solid v.$focus-outline; + outline-offset: 2px; } + } + + /* Optional: add a custom arrow */ + select { + height: 32px; + line-height: 1.2; + background-image: url("data:image/svg+xml;utf8,"); + background-repeat: no-repeat; + background-position: right 8px center; + background-size: 16px 16px; + padding-right: 32px; + /* make room for arrow */ + } } -.legend-anchor { - position: relative; - width: 360px; - /* SAME as dropdown width */ -} - -.legend-toggle { - width: 100%; - /* ← stretch to panel width */ +.icon-panel { + display: flex; + gap: 6px; + padding: 4px; + background: v.$gray-100; + border-radius: 10px; + button { display: flex; align-items: center; - justify-content: space-between; - /* text left, icon right */ + gap: 6px; - padding: 8px 14px; - border-radius: 12px; border: none; - - background: #f2f2f2; + background: transparent; + padding: 6px 10px; + border-radius: 8px; cursor: pointer; - font-size: 14px; - z-index: 2; + font-size: 14px; + color: v.$gray-800; &:hover { - background: #e6e6e6; + background: v.$gray-200; } - &.open { - border-bottom-left-radius: 0; - border-bottom-right-radius: 0; + .material-icons { + font-size: 18px; } + } } -.legend-toggle.open { - background: white; - border: 1px solid #e5e5e5; - border-bottom: none; -} - -.legend-toggle .material-icons { - transition: transform 0.2s ease; -} - -.legend-toggle.open .material-icons { - transform: rotate(180deg); -} - -@media (max-width: 1200px) { +.canvas-control { + display: flex; + align-items: center; + gap: 8px; - /* Show the hamburger button */ - .hamburger { - display: block; - margin-left: auto; - margin-right: 6px; - background-color: white; - border-color: v.$gray-700; - border-radius: 8px; - color: v.$gray-600; - } + .label { + font-size: 14px; + } - /* Reset menu-bar layout for mobile */ - .menu-bar { - display: flex; - flex-direction: column; - height: auto; - align-items: flex-start; - padding: 16px 18px; - position: relative; - } + .add-btn { + display: flex; + align-items: center; + gap: 4px; - .menu-top-row { - display: flex; - flex-direction: row; - align-items: center; - justify-content: space-between; - width: 100%; - } + border: none; + padding: 6px 12px; + border-radius: 10px; + background: v.$gray-100; + cursor: pointer; - /* Collapsible menu overlays below header */ - .menu-collapsible { - display: flex; - position: absolute; - flex-direction: column !important; - align-items: flex-start !important; - min-width: 0; - top: 64px; - left: 0; - right: 0; - z-index: 920; - background: white; - max-height: 0; - overflow: hidden; - transition: max-height 400ms ease; - transition: height 400ms ease; + &:hover { + background: v.$gray-200; } + } +} - /* Open state */ - .menu-collapsible.open { - display: flex !important; - flex-direction: column !important; - align-items: flex-start !important; - justify-content: flex-start !important; - width: 100%; - max-height: none !important; - padding: 16px; - background: white; - border-bottom: none; - position: static !important; - overflow: visible !important; - } +@media (max-width: 1200px) { + /* Show the hamburger button */ + .hamburger { + display: block; + margin-left: auto; + margin-right: 6px; + background-color: white; + border-color: v.$gray-700; + border-radius: 8px; + color: v.$gray-600; + } + + /* Reset menu-bar layout for mobile */ + .menu-bar { + display: flex; + flex-direction: column; + height: auto; + align-items: flex-start; + padding: 16px 18px; + position: relative; + } - /* Reset menu-center and menu-right layout */ - .menu-center, - .menu-right { - position: relative; - left: 0; - transform: none; - display: flex !important; - flex-direction: column !important; - align-items: flex-start !important; - gap: 16px; - width: 100%; - padding: 0; - margin: 0; - } + .menu-top-row { + display: flex; + flex-direction: row; + align-items: center; + justify-content: space-between; + width: 100%; + } - /* Buttons: icon + label left-aligned */ - .menu-center button, - .menu-right button { - justify-content: flex-start; - } + /* Collapsible menu overlays below header */ + .menu-collapsible { + display: flex; + position: absolute; + flex-direction: column !important; + align-items: flex-start !important; + min-width: 0; + top: 64px; + left: 0; + right: 0; + z-index: 920; + background: white; + max-height: 0; + overflow: hidden; + transition: max-height 400ms ease; + transition: height 400ms ease; + } + + /* Open state */ + .menu-collapsible.open { + display: flex !important; + flex-direction: column !important; + align-items: flex-start !important; + justify-content: flex-start !important; + width: 100%; + max-height: none !important; + padding: 16px; + background: white; + border-bottom: none; + position: static !important; + overflow: visible !important; + } - /* Optional: add spacing between sections */ - .menu-center { - margin-bottom: 24px; - } + /* Reset menu-center layout */ + .menu-center { + position: relative; + left: 0; + transform: none; + display: flex !important; + flex-direction: column !important; + align-items: flex-start !important; + gap: 16px; + width: 100%; + padding: 0; + margin: 0; + } + + /* Buttons: icon + label left-aligned */ + .menu-center button { + justify-content: flex-start; + } + + /* Optional: add spacing between sections */ + .menu-center { + margin-bottom: 24px; + } } .wizard-overlay { - position: fixed; - top: 0; - left: 0; - right: 0; - bottom: 0; - background: rgba(0, 0, 0, 0.5); - z-index: 9999; - display: flex; - align-items: center; - justify-content: center; - animation: fadeIn 0.3s ease; - padding: 32px; - - app-preprocessing-wizard { - width: 90%; - max-width: 1400px; - height: 90%; - max-height: 900px; - display: block; - background: white; - border-radius: 12px; - box-shadow: 0 10px 40px rgba(0, 0, 0, 0.3); - animation: slideUp 0.3s ease; - overflow: hidden; - } + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(0, 0, 0, 0.5); + z-index: 9999; + display: flex; + align-items: center; + justify-content: center; + animation: fadeIn 0.3s ease; + padding: 32px; + + app-preprocessing-wizard { + width: 90%; + max-width: 1400px; + height: 90%; + max-height: 900px; + display: block; + background: white; + border-radius: 12px; + box-shadow: 0 10px 40px rgba(0, 0, 0, 0.3); + animation: slideUp 0.3s ease; + overflow: hidden; + } } @keyframes fadeIn { - from { - opacity: 0; - } - to { - opacity: 1; - } + from { + opacity: 0; + } + to { + opacity: 1; + } } @keyframes slideUp { - from { - transform: translateY(20px); - opacity: 0; - } - to { - transform: translateY(0); - opacity: 1; - } -} \ No newline at end of file + from { + transform: translateY(20px); + opacity: 0; + } + to { + transform: translateY(0); + opacity: 1; + } +} diff --git a/src/app/menubar/menubar.component.ts b/src/app/menubar/menubar.component.ts index 77b9703..2df0a08 100644 --- a/src/app/menubar/menubar.component.ts +++ b/src/app/menubar/menubar.component.ts @@ -1,81 +1,100 @@ import { Component, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core'; -import { CommonModule } from '@angular/common'; import { FormsModule } from '@angular/forms'; import { Subscription } from 'rxjs'; -import { LegendDropdownComponent } from './legend-dropdown/legend-dropdown.component'; import { PreprocessingWizardComponent } from '../preprocessing-wizard/preprocessing-wizard.component'; -import { DataProviderService } from '../services/dataprovider.service'; +import { DataLoaderService } from '../services/data-loader.service'; +import { FilterService } from '../services/filter.service'; +import { DataExportService } from '../services/data-export.service'; import { ConfigService } from '../services/config.service'; @Component({ - selector: 'app-menubar', - standalone: true, - imports: [LegendDropdownComponent, PreprocessingWizardComponent, CommonModule, FormsModule], - templateUrl: './menubar.component.html', - styleUrls: ['./menubar.component.scss'], + selector: 'app-menubar', + standalone: true, + imports: [PreprocessingWizardComponent, FormsModule], + templateUrl: './menubar.component.html', + styleUrls: ['./menubar.component.scss'], }) export class MenuBarComponent implements OnInit, OnDestroy { - @Output() addCanvas = new EventEmitter(); - @Input() totalCells: number = 0; + @Output() addCanvas = new EventEmitter(); + @Input() totalCells = 0; - menuOpen = false; - legendOpen = false; - showWizard = false; - hasData = false; - datasetNames: string[] = []; - selectedDataset: string | null = null; + menuOpen = false; + showWizard = false; + hasData = false; + datasetNames: string[] = []; + datasetEntries: { name: string; source: string }[] = []; + selectedDataset: string | null = null; - private dataSub = new Subscription(); + private dataSub = new Subscription(); - constructor( - private dataProvider: DataProviderService, - private configService: ConfigService - ) { } + constructor( + private dataLoader: DataLoaderService, + private filterService: FilterService, + private dataExport: DataExportService, + private configService: ConfigService + ) {} - ngOnInit(): void { - this.dataSub.add( - this.dataProvider.dataSetCollectionSubject$.subscribe(collection => { - this.hasData = !!collection && collection.length > 0 && collection.at(0)?.dataset != ""; - this.datasetNames = collection.map(entry => entry.dataset); - })); - this.dataSub.add( - this.configService.loadedDataSubject$.subscribe(loaded => { - if (loaded != "") this.selectedDataset = loaded; - })); - } + ngOnInit(): void { + this.dataSub.add( + this.dataLoader.dataSetCollectionSubject$.subscribe(collection => { + this.hasData = !!collection && collection.length > 0 && collection.at(0)?.dataset !== ''; + this.datasetNames = collection.map(entry => entry.dataset); + this.datasetEntries = collection.map(entry => ({ + name: entry.dataset, + source: entry.source, + })); + }) + ); + this.dataSub.add( + this.configService.loadedDataSubject$.subscribe(loaded => { + if (loaded !== '') this.selectedDataset = loaded; + }) + ); + } - ngOnDestroy(): void { - this.dataSub?.unsubscribe(); - } + ngOnDestroy(): void { + this.dataSub?.unsubscribe(); + } - onDatasetSelect(name: string) { - this.dataProvider.clearFilters(); - this.configService.loadData(name); - } + onDatasetSelect(name: string) { + this.filterService.clearFilters(); + this.configService.loadData(name); + } - onContextSelect(context: string) { - // Do something with selected context - } + upload() { + this.showWizard = true; + this.configService.modalOpen = true; + } - toggleLegend() { - this.legendOpen = !this.legendOpen; - } + closePreprocessingWizard() { + this.showWizard = false; + this.configService.modalOpen = false; + } - upload() { - this.showWizard = true; - this.configService.modalOpen = true; + download() { + if (this.selectedDataset) { + const glyphMap = this.dataLoader.getGlyphMap(this.selectedDataset); + const schemaMap = this.dataLoader.getSchemaMap(this.selectedDataset); + if (glyphMap && schemaMap) { + this.dataExport.exportFilteredGlyphsAsCSV(glyphMap, schemaMap, this.selectedDataset); + } } + } - closePreprocessingWizard() { - this.showWizard = false; - this.configService.modalOpen = false; - } + fitAll() { + this.configService.toggleFitToScreen(); + } - download() { - if (this.selectedDataset) this.dataProvider.exportFilteredGlyphsAsCSV(this.selectedDataset); - } + isUserDataset(name: string | null): boolean { + if (!name) return false; + const entry = this.datasetEntries.find(e => e.name === name); + return !!entry && entry.source !== 'local'; + } - fitAll() { - this.configService.toggleFitToScreen(); + async onDeleteDataset(name: string | null): Promise { + if (!name || !this.isUserDataset(name)) return; + if (confirm(`Delete dataset "${name}"? This cannot be undone.`)) { + await this.dataLoader.deleteDataset(name); } + } } diff --git a/src/app/preprocessing-wizard/models/column-config.ts b/src/app/preprocessing-wizard/models/column-config.ts index 0bf609f..bc3cb33 100644 --- a/src/app/preprocessing-wizard/models/column-config.ts +++ b/src/app/preprocessing-wizard/models/column-config.ts @@ -4,7 +4,7 @@ import { ScalingMethod, MissingValueStrategy, OutlierStrategy, - OutlierMethod + OutlierMethod, } from './data-type.enum'; export interface ColumnConfig { @@ -39,25 +39,25 @@ export interface CleaningConfig { export interface ProjectionConfig { // FastMap is always enabled as primary projection (runs immediately) // These are optional background projections: - enablePCA: boolean; // PCA - fast linear projection - enableIsoMap: boolean; // IsoMap - non-linear manifold, preserves geodesic distances - enableMDS: boolean; // MDS - classical multidimensional scaling - enableLLE: boolean; // LLE - locally linear embedding - enableLTSA: boolean; // LTSA - local tangent space alignment - enableTSNE: boolean; // t-SNE - preserves local structure (slow) - enableUMAP: boolean; // UMAP - balances local/global structure (slow) - enableTriMap: boolean; // TriMap - good for large datasets - enableTopoMap: boolean; // TopoMap - topology preserving - enableSammon: boolean; // Sammon mapping + enablePCA: boolean; // PCA - fast linear projection + enableIsoMap: boolean; // IsoMap - non-linear manifold, preserves geodesic distances + enableMDS: boolean; // MDS - classical multidimensional scaling + enableLLE: boolean; // LLE - locally linear embedding + enableLTSA: boolean; // LTSA - local tangent space alignment + enableTSNE: boolean; // t-SNE - preserves local structure (slow) + enableUMAP: boolean; // UMAP - balances local/global structure (slow) + enableTriMap: boolean; // TriMap - good for large datasets + enableTopoMap: boolean; // TopoMap - topology preserving + enableSammon: boolean; // Sammon mapping // IsoMap parameters - isomapNeighbors: number; // Number of neighbors (default: auto based on dataset size) + isomapNeighbors: number; // Number of neighbors (default: auto based on dataset size) // LLE parameters - lleNeighbors: number; // Number of neighbors for local reconstruction + lleNeighbors: number; // Number of neighbors for local reconstruction // LTSA parameters - ltsaNeighbors: number; // Number of neighbors for tangent space + ltsaNeighbors: number; // Number of neighbors for tangent space // t-SNE parameters (DruidJS) tsnePerplexity: number; @@ -68,7 +68,7 @@ export interface ProjectionConfig { umapMinDist: number; // TriMap parameters - trimapWeightAdj: number; // Weight adjustment factor (default: 500) + trimapWeightAdj: number; // Weight adjustment factor (default: 500) } export interface CleaningResult { diff --git a/src/app/preprocessing-wizard/models/column-statistics.ts b/src/app/preprocessing-wizard/models/column-statistics.ts index 4ec3215..094714c 100644 --- a/src/app/preprocessing-wizard/models/column-statistics.ts +++ b/src/app/preprocessing-wizard/models/column-statistics.ts @@ -19,7 +19,7 @@ export interface ColumnStatistics { variance?: number; // Categorical statistics - topValues?: Array<{ value: string; count: number }>; + topValues?: { value: string; count: number }[]; // Histogram data histogram?: HistogramData; @@ -43,5 +43,5 @@ export interface DataProfile { columns: ColumnStatistics[]; qualityScore: number; duplicateCount: number; - previewRows: any[]; + previewRows: Record[]; } diff --git a/src/app/preprocessing-wizard/models/data-type.enum.ts b/src/app/preprocessing-wizard/models/data-type.enum.ts index bccae24..129fed1 100644 --- a/src/app/preprocessing-wizard/models/data-type.enum.ts +++ b/src/app/preprocessing-wizard/models/data-type.enum.ts @@ -6,7 +6,7 @@ export enum DataType { Boolean = 'boolean', ID = 'id', Coordinate = 'coordinate', - Unknown = 'unknown' + Unknown = 'unknown', } export enum EncodingMethod { @@ -14,14 +14,14 @@ export enum EncodingMethod { OneHot = 'onehot', Label = 'label', Normalize = 'normalize', - Standardize = 'standardize' + Standardize = 'standardize', } export enum ScalingMethod { None = 'none', MinMax = 'minmax', Standard = 'standard', - Robust = 'robust' + Robust = 'robust', } export enum MissingValueStrategy { @@ -30,13 +30,13 @@ export enum MissingValueStrategy { FillMean = 'fill_mean', FillMedian = 'fill_median', FillMode = 'fill_mode', - FillValue = 'fill_value' + FillValue = 'fill_value', } export enum OutlierStrategy { Keep = 'keep', Remove = 'remove', - Cap = 'cap' + Cap = 'cap', } export enum OutlierMethod { @@ -45,5 +45,175 @@ export enum OutlierMethod { IQR_3_0 = 'iqr_3.0', ZScore_2 = 'zscore_2', ZScore_3 = 'zscore_3', - ZScore_4 = 'zscore_4' + ZScore_4 = 'zscore_4', +} + +/** + * Per-data-type configuration for Step 3. + * Defines which encoding/scaling/outlier/missing-value options are available. + */ +export interface DataTypeCapabilities { + encodingMethods: EncodingMethod[]; + hasScaling: boolean; + hasOutliers: boolean; + missingValueFlags: { numericLike: boolean; categorical: boolean }; + defaultEncoding: EncodingMethod; + defaultScaling: ScalingMethod; + defaultIncludeInProjection: boolean; +} + +export const DATA_TYPE_CONFIG: Record = { + [DataType.Numeric]: { + encodingMethods: [EncodingMethod.None, EncodingMethod.Normalize, EncodingMethod.Standardize], + hasScaling: true, + hasOutliers: true, + missingValueFlags: { numericLike: true, categorical: false }, + defaultEncoding: EncodingMethod.Normalize, + defaultScaling: ScalingMethod.MinMax, + defaultIncludeInProjection: true, + }, + [DataType.Categorical]: { + encodingMethods: [EncodingMethod.Label, EncodingMethod.OneHot], + hasScaling: false, + hasOutliers: false, + missingValueFlags: { numericLike: false, categorical: true }, + defaultEncoding: EncodingMethod.Label, + defaultScaling: ScalingMethod.None, + defaultIncludeInProjection: true, + }, + [DataType.Text]: { + encodingMethods: [EncodingMethod.None, EncodingMethod.Label, EncodingMethod.OneHot], + hasScaling: false, + hasOutliers: false, + missingValueFlags: { numericLike: false, categorical: false }, + defaultEncoding: EncodingMethod.None, + defaultScaling: ScalingMethod.None, + defaultIncludeInProjection: false, + }, + [DataType.Date]: { + encodingMethods: [], + hasScaling: true, + hasOutliers: false, + missingValueFlags: { numericLike: false, categorical: false }, + defaultEncoding: EncodingMethod.None, + defaultScaling: ScalingMethod.MinMax, + defaultIncludeInProjection: true, + }, + [DataType.Boolean]: { + encodingMethods: [EncodingMethod.None, EncodingMethod.Label], + hasScaling: false, + hasOutliers: false, + missingValueFlags: { numericLike: false, categorical: false }, + defaultEncoding: EncodingMethod.None, + defaultScaling: ScalingMethod.None, + defaultIncludeInProjection: true, + }, + [DataType.ID]: { + encodingMethods: [], + hasScaling: false, + hasOutliers: false, + missingValueFlags: { numericLike: false, categorical: false }, + defaultEncoding: EncodingMethod.None, + defaultScaling: ScalingMethod.None, + defaultIncludeInProjection: false, + }, + [DataType.Coordinate]: { + encodingMethods: [], + hasScaling: true, + hasOutliers: true, + missingValueFlags: { numericLike: true, categorical: false }, + defaultEncoding: EncodingMethod.None, + defaultScaling: ScalingMethod.None, + defaultIncludeInProjection: true, + }, + [DataType.Unknown]: { + encodingMethods: [EncodingMethod.None, EncodingMethod.Label], + hasScaling: false, + hasOutliers: false, + missingValueFlags: { numericLike: false, categorical: false }, + defaultEncoding: EncodingMethod.None, + defaultScaling: ScalingMethod.None, + defaultIncludeInProjection: true, + }, +}; + +export function getDataTypeBadgeClass(dataType: DataType | undefined): string { + return `badge-${dataType}`; +} + +export function getDataTypeLabel(dataType: DataType): string { + const labels: Record = { + [DataType.Numeric]: 'Numeric', + [DataType.Categorical]: 'Categorical', + [DataType.Text]: 'Text', + [DataType.Date]: 'Date', + [DataType.Boolean]: 'Boolean', + [DataType.ID]: 'ID', + [DataType.Coordinate]: 'Coordinate', + [DataType.Unknown]: 'Unknown', + }; + return labels[dataType] || 'Unknown'; +} + +export function getEncodingLabel(method: EncodingMethod): string { + const labels: Record = { + [EncodingMethod.None]: 'None', + [EncodingMethod.OneHot]: 'One-Hot', + [EncodingMethod.Label]: 'Label', + [EncodingMethod.Normalize]: 'Normalize', + [EncodingMethod.Standardize]: 'Standardize', + }; + return labels[method] || 'Unknown'; +} + +export function getScalingLabel(method: ScalingMethod): string { + const labels: Record = { + [ScalingMethod.None]: 'None', + [ScalingMethod.Standard]: 'Standard', + [ScalingMethod.MinMax]: 'Min-Max', + [ScalingMethod.Robust]: 'Robust', + }; + return labels[method] || 'Unknown'; +} + +export function getDataTypeColor(dataType: DataType): string { + switch (dataType) { + case DataType.Numeric: + return '#16A34A'; + case DataType.Categorical: + return '#7C3AED'; + case DataType.Text: + return '#8BC34A'; + case DataType.Date: + return '#EA580C'; + case DataType.Boolean: + return '#00bcd4'; + case DataType.ID: + return '#888888'; + case DataType.Coordinate: + return '#0369a1'; + default: + return '#888888'; + } +} + +export function getDataTypeBgColor(dataType: DataType): string { + switch (dataType) { + case DataType.Numeric: + return '#86efac'; + case DataType.Categorical: + return '#c4b5fd'; + case DataType.Text: + return '#c5e1a5'; + case DataType.Date: + return '#fdba74'; + case DataType.Boolean: + return '#80deea'; + case DataType.ID: + return '#bdbdbd'; + case DataType.Coordinate: + return '#e0f2fe'; + default: + return '#bdbdbd'; + } } diff --git a/src/app/preprocessing-wizard/models/preprocessing-state.ts b/src/app/preprocessing-wizard/models/preprocessing-state.ts index f6ac050..e608361 100644 --- a/src/app/preprocessing-wizard/models/preprocessing-state.ts +++ b/src/app/preprocessing-wizard/models/preprocessing-state.ts @@ -24,9 +24,10 @@ export interface PreprocessingState { timestamp: string; // Glyph property mapping - glyphFeatures: string[]; // Array of 5 feature names for glyph rays (ordered) - tooltipFeatures: string[]; // Array of feature names for tooltips - colorScaleMode: 'continuous' | 'categorical'; // Auto-detected based on color feature data type + glyphFeatures: string[]; // Array of 5 feature names for glyph rays (ordered) + tooltipFeatures: string[]; // Array of feature names for tooltips + colorScaleMode: 'continuous' | 'categorical'; // Auto-detected based on color feature data type + colorScaleId: number; // ID of selected color scale from COLOR_SCALES // UI state isProcessing: boolean; @@ -42,22 +43,22 @@ export interface ProcessingProgress { } export const DEFAULT_CLEANING_CONFIG: CleaningConfig = { - removeDuplicates: false + removeDuplicates: false, }; export const DEFAULT_PROJECTION_CONFIG: ProjectionConfig = { // FastMap is always enabled as primary (runs immediately, O(n) complexity) // These are optional background projections: - enablePCA: true, // PCA runs in background - very fast - enableIsoMap: true, // IsoMap runs in background - fast, preserves geodesic distances - enableMDS: false, // MDS runs in background - fast - enableLLE: false, // LLE runs in background - medium - enableLTSA: false, // LTSA runs in background - medium - enableTSNE: false, // t-SNE runs in background (slow) - enableUMAP: false, // UMAP runs in background (slow) - enableTriMap: false, // TriMap runs in background - medium - enableTopoMap: false, // TopoMap runs in background - medium - enableSammon: false, // Sammon runs in background - medium + enablePCA: true, // PCA runs in background - very fast + enableIsoMap: true, // IsoMap runs in background - fast, preserves geodesic distances + enableMDS: false, // MDS runs in background - fast + enableLLE: false, // LLE runs in background - medium + enableLTSA: false, // LTSA runs in background - medium + enableTSNE: false, // t-SNE runs in background (slow) + enableUMAP: false, // UMAP runs in background (slow) + enableTriMap: false, // TriMap runs in background - medium + enableTopoMap: false, // TopoMap runs in background - medium + enableSammon: false, // Sammon runs in background - medium // IsoMap parameters (0 = auto based on dataset size) isomapNeighbors: 0, @@ -77,5 +78,5 @@ export const DEFAULT_PROJECTION_CONFIG: ProjectionConfig = { umapMinDist: 0.1, // TriMap parameters - trimapWeightAdj: 500 + trimapWeightAdj: 500, }; diff --git a/src/app/preprocessing-wizard/preprocessing-wizard.component.html b/src/app/preprocessing-wizard/preprocessing-wizard.component.html index 239702d..eef2e22 100644 --- a/src/app/preprocessing-wizard/preprocessing-wizard.component.html +++ b/src/app/preprocessing-wizard/preprocessing-wizard.component.html @@ -12,10 +12,7 @@

Data Preprocessing Wizard

- +
@@ -42,10 +39,12 @@

Data Preprocessing Wizard

} @case (3) { - + + } + @case (4) { + } }
- diff --git a/src/app/preprocessing-wizard/preprocessing-wizard.component.scss b/src/app/preprocessing-wizard/preprocessing-wizard.component.scss index 709891e..078b3ea 100644 --- a/src/app/preprocessing-wizard/preprocessing-wizard.component.scss +++ b/src/app/preprocessing-wizard/preprocessing-wizard.component.scss @@ -1,4 +1,5 @@ @use '../../styles/variables' as v; +@use './shared/wizard-shared' as w; .preprocessing-wizard { display: flex; @@ -18,6 +19,7 @@ justify-content: space-between; align-items: center; padding: 12px 16px; + background: v.$gray-100; border-bottom: 1px solid v.$gray-300; h1 { @@ -57,7 +59,7 @@ .wizard-content { flex: 1; - overflow-y: auto; // Allow scrolling for steps that need it (Step 1) + overflow-y: auto; // Allow scrolling for steps that need it (Step 1) display: flex; flex-direction: column; min-height: 0; @@ -69,9 +71,9 @@ align-items: center; gap: 12px; padding: 12px 16px; - background: rgba(244, 67, 54, 0.1); - border-left: 3px solid #F44336; - color: #C62828; + background: rgba(v.$status-error, 0.1); + border-left: 3px solid v.$status-error; + color: v.$status-error-dark; margin: 0 16px 16px; border-radius: 2px; @@ -88,7 +90,7 @@ .material-icons { font-size: 18px; - color: #C62828; + color: v.$status-error-dark; } } } @@ -98,6 +100,13 @@ display: flex; flex-direction: column; min-height: 0; + + > * { + flex: 1; + display: flex; + flex-direction: column; + min-height: 0; + } } .step-placeholder { @@ -135,59 +144,13 @@ } .btn-secondary { - display: flex; - align-items: center; - gap: 6px; + @include w.btn-secondary; padding: 8px 16px; - background: rgba(200, 200, 200, 0.5); - color: v.$gray-700; - border: none; - border-radius: 4px; - font-size: 13px; - cursor: pointer; - transition: background-color 0.2s ease; - - .material-icons { - font-size: 18px; - } - - &:hover:not(:disabled) { - background: rgba(180, 180, 180, 0.7); - } - - &:disabled { - opacity: 0.5; - cursor: not-allowed; - } } .btn-primary { - display: flex; - align-items: center; - gap: 6px; + @include w.btn-primary; padding: 8px 16px; - background: v.$active-color; - color: white; - border: none; - border-radius: 4px; - font-size: 13px; - font-weight: 600; - cursor: pointer; - transition: opacity 0.2s ease; - - .material-icons { - font-size: 18px; - } - - &:hover:not(:disabled) { - opacity: 0.9; - } - - &:disabled { - background: v.$gray-400; - cursor: not-allowed; - opacity: 0.5; - } } @media (max-width: 768px) { diff --git a/src/app/preprocessing-wizard/preprocessing-wizard.component.ts b/src/app/preprocessing-wizard/preprocessing-wizard.component.ts index 96c00b0..604cc1f 100644 --- a/src/app/preprocessing-wizard/preprocessing-wizard.component.ts +++ b/src/app/preprocessing-wizard/preprocessing-wizard.component.ts @@ -1,5 +1,4 @@ import { Component, OnInit, OnDestroy, Output, EventEmitter, ViewChild, ElementRef } from '@angular/core'; -import { CommonModule } from '@angular/common'; import { Subscription, distinctUntilChanged, map } from 'rxjs'; import { PreprocessingService } from './services/preprocessing.service'; import { ProgressStepperComponent, Step } from './shared/progress-stepper/progress-stepper.component'; @@ -7,30 +6,32 @@ import { Step1UploadComponent } from './steps/step1-upload/step1-upload.componen import { Step2ColumnSelectionComponent } from './steps/step2-column-selection/step2-column-selection.component'; import { Step3ConfigureDataFeaturesComponent } from './steps/step3-configure-data-features/step3-configure-data-features.component'; import { Step4VisualizationSettingsComponent } from './steps/step4-visualization-settings/step4-visualization-settings.component'; +import { Step5ReviewProcessingComponent } from './steps/step5-review-processing/step5-review-processing.component'; import { DataProfile } from './models/column-statistics'; +import { PreprocessingState } from './models/preprocessing-state'; @Component({ selector: 'app-preprocessing-wizard', standalone: true, imports: [ - CommonModule, ProgressStepperComponent, Step1UploadComponent, Step2ColumnSelectionComponent, Step3ConfigureDataFeaturesComponent, - Step4VisualizationSettingsComponent + Step4VisualizationSettingsComponent, + Step5ReviewProcessingComponent, ], templateUrl: './preprocessing-wizard.component.html', - styleUrl: './preprocessing-wizard.component.scss' + styleUrl: './preprocessing-wizard.component.scss', }) export class PreprocessingWizardComponent implements OnInit, OnDestroy { - @Output() close = new EventEmitter(); + @Output() wizardClose = new EventEmitter(); @ViewChild('wizardContent') wizardContent!: ElementRef; private subscription = new Subscription(); currentStep = 0; - highestStepVisited = 0; // Track highest step to enable forward navigation + highestStepVisited = 0; // Track highest step to enable forward navigation isProcessing = false; error: string | null = null; @@ -38,10 +39,11 @@ export class PreprocessingWizardComponent implements OnInit, OnDestroy { { label: 'Upload Data', completed: false }, { label: 'Select Columns', completed: false }, { label: 'Configure Data & Features', completed: false }, - { label: 'Visualization Settings', completed: false } + { label: 'Visualization Settings', completed: false }, + { label: 'Review & Process', completed: false }, ]; - constructor(private preprocessingService: PreprocessingService) { } + constructor(private preprocessingService: PreprocessingService) {} ngOnInit(): void { // Subscribe to state changes @@ -63,12 +65,14 @@ export class PreprocessingWizardComponent implements OnInit, OnDestroy { // Scroll to top when step changes this.subscription.add( - this.preprocessingService.state$.pipe( - map(state => state.currentStep), - distinctUntilChanged() - ).subscribe(() => { - this.scrollToTop(); - }) + this.preprocessingService.state$ + .pipe( + map(state => state.currentStep), + distinctUntilChanged() + ) + .subscribe(() => { + this.scrollToTop(); + }) ); } @@ -88,22 +92,22 @@ export class PreprocessingWizardComponent implements OnInit, OnDestroy { this.subscription.unsubscribe(); } - private updateStepCompletion(state: any): void { + private updateStepCompletion(state: PreprocessingState): void { // Mark steps as completed based on: // 1. Whether the step's required data exists // 2. Whether the user has visited beyond this step (highestStepVisited) this.steps[0].completed = state.dataProfile !== null; this.steps[1].completed = state.columnConfigs.size > 0 && this.highestStepVisited > 1; this.steps[2].completed = this.highestStepVisited > 2; - // Step 3 (index 3) is completed either after processing OR if user has visited it - this.steps[3].completed = state.processedDataset !== null || this.highestStepVisited >= 3; + this.steps[3].completed = this.highestStepVisited > 3; + this.steps[4].completed = state.processedDataset !== null; } onStepClick(step: number): void { this.preprocessingService.goToStep(step); } - onDataLoaded(profile: DataProfile): void { + onDataLoaded(_profile: DataProfile): void { // User clicked "Continue to Column Selection" button - proceed to next step this.preprocessingService.nextStep(); } @@ -127,6 +131,8 @@ export class PreprocessingWizardComponent implements OnInit, OnDestroy { case 2: // Configure Data & Features return true; case 3: // Visualization Settings + return true; + case 4: // Review & Process return false; // Final step - processing happens here default: return false; @@ -135,16 +141,16 @@ export class PreprocessingWizardComponent implements OnInit, OnDestroy { reset(): void { if (confirm('Are you sure you want to start over? All progress will be lost.')) { - this.highestStepVisited = 0; // Reset navigation tracking + this.highestStepVisited = 0; // Reset navigation tracking this.preprocessingService.resetState(); } } closeWizard(): void { - this.close.emit(); + this.wizardClose.emit(); } onWizardComplete(): void { - this.close.emit(); + this.wizardClose.emit(); } } diff --git a/src/app/preprocessing-wizard/services/preprocessing.service.ts b/src/app/preprocessing-wizard/services/preprocessing.service.ts index 67445a9..5e0992e 100644 --- a/src/app/preprocessing-wizard/services/preprocessing.service.ts +++ b/src/app/preprocessing-wizard/services/preprocessing.service.ts @@ -1,14 +1,26 @@ import { Injectable } from '@angular/core'; import { BehaviorSubject, Observable, Subject } from 'rxjs'; -import { PreprocessingState, ProcessingProgress, DEFAULT_CLEANING_CONFIG, DEFAULT_PROJECTION_CONFIG } from '../models/preprocessing-state'; +import { + PreprocessingState, + ProcessingProgress, + DEFAULT_CLEANING_CONFIG, + DEFAULT_PROJECTION_CONFIG, +} from '../models/preprocessing-state'; import { DataProfile, ColumnStatistics } from '../models/column-statistics'; import { ColumnConfig, CleaningConfig, ProjectionConfig } from '../models/column-config'; -import { DataType, EncodingMethod, ScalingMethod, MissingValueStrategy, OutlierStrategy, OutlierMethod } from '../models/data-type.enum'; +import { + DataType, + EncodingMethod, + MissingValueStrategy, + OutlierStrategy, + OutlierMethod, + DATA_TYPE_CONFIG, +} from '../models/data-type.enum'; import { DataProcessorService } from '../../services/data-processor'; -import { DataProviderService } from '../../services/dataprovider.service'; +import { DataLoaderService } from '../../services/data-loader.service'; @Injectable({ - providedIn: 'root' + providedIn: 'root', }) export class PreprocessingService { private stateSubject = new BehaviorSubject(this.getInitialState()); @@ -19,7 +31,7 @@ export class PreprocessingService { constructor( private dataProcessor: DataProcessorService, - private dataProvider: DataProviderService + private dataLoader: DataLoaderService ) { // Load saved state from localStorage if available this.loadStateFromStorage(); @@ -29,7 +41,7 @@ export class PreprocessingService { * Generate a unique dataset name by appending (1), (2), etc. if name already exists */ private getUniqueDatasetName(baseName: string): string { - const existingNames = this.dataProvider.getDataSetNames(); + const existingNames = this.dataLoader.getDataSetNames(); if (!existingNames.includes(baseName)) { return baseName; } @@ -47,7 +59,7 @@ export class PreprocessingService { /** * Get processing progress updates from worker */ - get processingProgress(): Observable<{step: string; progress: number; message: string}> { + get processingProgress(): Observable<{ step: string; progress: number; message: string }> { return this.dataProcessor.processingProgress; } @@ -66,10 +78,11 @@ export class PreprocessingService { glyphFeatures: [], tooltipFeatures: [], colorScaleMode: 'continuous', + colorScaleId: 0, isProcessing: false, processingProgress: 0, processingStep: '', - error: null + error: null, }; } @@ -77,16 +90,16 @@ export class PreprocessingService { return this.stateSubject.getValue(); } - // Step navigation (4 steps: 0-3) + // Step navigation (5 steps: 0-4) public goToStep(step: number): void { - if (step >= 0 && step <= 3) { + if (step >= 0 && step <= 4) { this.updateState({ currentStep: step }); } } public nextStep(): void { const current = this.currentState.currentStep; - if (current < 3) { + if (current < 4) { this.goToStep(current + 1); } } @@ -127,60 +140,36 @@ export class PreprocessingService { columnConfigs, datasetName, timestamp, - isProcessing: false + isProcessing: false, }); this.saveStateToStorage(); return profile; - - } catch (error: any) { + } catch (error: unknown) { this.updateState({ isProcessing: false, - error: error.message || 'Failed to load data file' + error: error instanceof Error ? error.message : 'Failed to load data file', }); throw error; } } private createDefaultColumnConfig(col: ColumnStatistics): ColumnConfig { - let encodingMethod = EncodingMethod.None; - let scalingMethod = ScalingMethod.None; - let includeInProjection = true; - - // Smart defaults based on data type - switch (col.dataType) { - case DataType.Numeric: - encodingMethod = EncodingMethod.Normalize; - scalingMethod = ScalingMethod.MinMax; - break; - case DataType.Categorical: - // Default to Label encoding (simpler, no feature explosion) - encodingMethod = EncodingMethod.Label; - break; - case DataType.Text: - includeInProjection = false; - break; - case DataType.ID: - includeInProjection = false; - break; - case DataType.Date: - encodingMethod = EncodingMethod.Normalize; - break; - } + const capabilities = DATA_TYPE_CONFIG[col.dataType] ?? DATA_TYPE_CONFIG[DataType.Unknown]; return { name: col.name, originalType: col.dataType, targetType: col.dataType, - encodingMethod, - scalingMethod, - includeInProjection, + encodingMethod: capabilities.defaultEncoding, + scalingMethod: capabilities.defaultScaling, + includeInProjection: capabilities.defaultIncludeInProjection, isColorFeature: false, missingValueStrategy: MissingValueStrategy.Keep, outlierMethod: OutlierMethod.IQR_1_5, outlierStrategy: OutlierStrategy.Keep, enabled: true, - hasIssues: col.missingPercentage > 50 || col.uniqueCount === 1 + hasIssues: col.missingPercentage > 50 || col.uniqueCount === 1, }; } @@ -210,26 +199,43 @@ export class PreprocessingService { if (colorConfig) { // Categorical or Text data types should use categorical color scale - if (colorConfig.originalType === DataType.Categorical || - colorConfig.originalType === DataType.Text || - colorConfig.targetType === DataType.Categorical || - colorConfig.targetType === DataType.Text) { + if ( + colorConfig.originalType === DataType.Categorical || + colorConfig.originalType === DataType.Text || + colorConfig.targetType === DataType.Categorical || + colorConfig.targetType === DataType.Text + ) { colorScaleMode = 'categorical'; } // Numeric data types use continuous color scale - else if (colorConfig.originalType === DataType.Numeric || - colorConfig.targetType === DataType.Numeric) { + else if (colorConfig.originalType === DataType.Numeric || colorConfig.targetType === DataType.Numeric) { colorScaleMode = 'continuous'; } } + // Auto-select matching default scale if current scale type doesn't match + const currentScaleId = this.currentState.colorScaleId; + let colorScaleId = currentScaleId; + const isCategorical = colorScaleMode === 'categorical'; + // Default numeric scales: 0-3, categorical scales: 4-5 + const currentIsCategorical = currentScaleId >= 4; + if (isCategorical !== currentIsCategorical) { + colorScaleId = isCategorical ? 4 : 0; + } + this.updateState({ columnConfigs: new Map(configs), - colorScaleMode: colorScaleMode + colorScaleMode: colorScaleMode, + colorScaleId: colorScaleId, }); this.saveStateToStorage(); } + public setColorScaleId(id: number): void { + this.updateState({ colorScaleId: id }); + this.saveStateToStorage(); + } + // Glyph feature mapping public setGlyphFeatures(features: string[]): void { // Validate 3-12 features @@ -240,11 +246,6 @@ export class PreprocessingService { this.saveStateToStorage(); } - public setTooltipFeatures(features: string[]): void { - this.updateState({ tooltipFeatures: features }); - this.saveStateToStorage(); - } - public getPreviewFeatureNames(): string[] { // Returns predicted feature names after encoding return this.predictEncodedFeatureNames(); @@ -254,8 +255,9 @@ export class PreprocessingService { const state = this.currentState; const featureNames: string[] = []; - const enabledCols = Array.from(state.columnConfigs.values()) - .filter(config => config.enabled && config.originalType !== DataType.ID); + const enabledCols = Array.from(state.columnConfigs.values()).filter( + config => config.enabled && config.originalType !== DataType.ID + ); for (const col of enabledCols) { if (col.encodingMethod === EncodingMethod.OneHot) { @@ -263,7 +265,7 @@ export class PreprocessingService { const colStats = state.dataProfile?.columns.find(c => c.name === col.name); if (colStats && colStats.topValues) { // Generate predicted column names: columnName_value - colStats.topValues.forEach((item) => { + colStats.topValues.forEach(item => { featureNames.push(`${col.name}_${item.value}`); }); } @@ -285,7 +287,7 @@ export class PreprocessingService { public selectAllColumns(): void { const configs = this.currentState.columnConfigs; - configs.forEach(config => config.enabled = true); + configs.forEach(config => (config.enabled = true)); this.updateState({ columnConfigs: new Map(configs) }); this.saveStateToStorage(); } @@ -304,7 +306,7 @@ export class PreprocessingService { // Cleaning configuration public updateCleaningConfig(updates: Partial): void { this.updateState({ - cleaningConfig: { ...this.currentState.cleaningConfig, ...updates } + cleaningConfig: { ...this.currentState.cleaningConfig, ...updates }, }); this.saveStateToStorage(); } @@ -312,60 +314,46 @@ export class PreprocessingService { // Projection configuration public updateProjectionConfig(updates: Partial): void { this.updateState({ - projectionConfig: { ...this.currentState.projectionConfig, ...updates } + projectionConfig: { ...this.currentState.projectionConfig, ...updates }, }); this.saveStateToStorage(); } - // Get column statistics - public getColumnStatistics(columnName: string): ColumnStatistics | undefined { - return this.currentState.dataProfile?.columns.find(col => col.name === columnName); - } - - public getEnabledColumns(): ColumnConfig[] { - return Array.from(this.currentState.columnConfigs.values()) - .filter(config => config.enabled); - } - - public getColumnsForProjection(): ColumnConfig[] { - return this.getEnabledColumns() - .filter(config => config.includeInProjection); - } - // Outlier detection - public async detectOutliers(columnName: string, method: OutlierMethod): Promise<{ outlierCount: number; outlierIndices: number[] }> { + public async detectOutliers( + columnName: string, + method: OutlierMethod + ): Promise<{ outlierCount: number; outlierIndices: number[] }> { if (!this.currentState.rawFileName) { throw new Error('No data file loaded'); } - const result = await this.dataProcessor.detectOutliers( - this.currentState.rawFileName, - columnName, - method - ); + const result = await this.dataProcessor.detectOutliers(this.currentState.rawFileName, columnName, method); return { outlierCount: result.outlier_count, - outlierIndices: result.outlier_indices + outlierIndices: result.outlier_indices, }; } // Duplicate detection - public async detectDuplicates(subsetColumns?: string[]): Promise<{ duplicateCount: number; duplicateIndices: number[]; percentage: number; sampleDuplicates: any[] }> { + public async detectDuplicates(subsetColumns?: string[]): Promise<{ + duplicateCount: number; + duplicateIndices: number[]; + percentage: number; + sampleDuplicates: Record[]; + }> { if (!this.currentState.rawFileName) { throw new Error('No data file loaded'); } - const result = await this.dataProcessor.detectDuplicates( - this.currentState.rawFileName, - subsetColumns - ); + const result = await this.dataProcessor.detectDuplicates(this.currentState.rawFileName, subsetColumns); return { duplicateCount: result.duplicateCount, duplicateIndices: result.duplicateIndices, percentage: result.percentage, - sampleDuplicates: result.sampleDuplicates + sampleDuplicates: result.sampleDuplicates, }; } @@ -379,7 +367,7 @@ export class PreprocessingService { this.updateState({ isProcessing: true, processingProgress: 0, - error: null + error: null, }); try { @@ -388,23 +376,19 @@ export class PreprocessingService { // File is already in Pyodide FS from loadCSV() - no need to re-upload // Send to worker for processing (use rawFileName which is the actual CSV file in Pyodide FS) - const result = await this.dataProcessor.processWithConfig( - this.currentState.rawFileName, - config - ); + const result = await this.dataProcessor.processWithConfig(this.currentState.rawFileName, config); this.updateState({ processedDataset: result, isProcessing: false, - processingProgress: 100 + processingProgress: 100, }); this.saveStateToStorage(); - - } catch (error: any) { + } catch (error: unknown) { this.updateState({ isProcessing: false, - error: error.message || 'Processing failed' + error: error instanceof Error ? error.message : 'Processing failed', }); throw error; } @@ -423,21 +407,20 @@ export class PreprocessingService { */ public async addProjectionPositions( method: string, - positions: Array<{id: string | number; x: number; y: number}> + positions: { id: string | number; x: number; y: number }[] ): Promise { const state = this.currentState; // If wizard was reset while background projection was running, silently skip // (user has already moved on to dashboard) if (!state.processedDataset) { - console.log(`[Preprocessing] Skipping ${method} projection - wizard was reset`); return; } // The dataset structure from worker + // eslint-disable-next-line @typescript-eslint/no-explicit-any const collection = state.processedDataset as any; - const datasetKey = collection.selectedDataset || - (collection.datasets ? Object.keys(collection.datasets)[0] : null); + const datasetKey = collection.selectedDataset || (collection.datasets ? Object.keys(collection.datasets)[0] : null); if (!datasetKey || !collection.datasets) { throw new Error('Invalid dataset structure'); @@ -459,13 +442,14 @@ export class PreprocessingService { // Always normalize IDs to string for consistency dataset.positions[method] = positions.map(p => ({ id: String(p.id), - position: { x: p.x, y: p.y } + position: { x: p.x, y: p.y }, })); // Update state to trigger any observers this.updateState({ processedDataset: collection }); } + // eslint-disable-next-line @typescript-eslint/no-explicit-any private buildProcessingConfig(): any { const state = this.currentState; @@ -483,14 +467,15 @@ export class PreprocessingService { missingValueStrategy: col.missingValueStrategy, missingValueFillValue: col.missingValueFillValue, outlierMethod: col.outlierMethod, - outlierStrategy: col.outlierStrategy + outlierStrategy: col.outlierStrategy, })), cleaning: state.cleaningConfig, projections: state.projectionConfig, // Glyph and tooltip feature mappings glyphFeatures: state.glyphFeatures, tooltipFeatures: state.tooltipFeatures.length > 0 ? state.tooltipFeatures : null, - colorScaleMode: state.colorScaleMode + colorScaleMode: state.colorScaleMode, + colorScaleId: state.colorScaleId, }; } @@ -518,7 +503,7 @@ export class PreprocessingService { datasetName: state.datasetName, timestamp: state.timestamp, glyphFeatures: state.glyphFeatures, - tooltipFeatures: state.tooltipFeatures + tooltipFeatures: state.tooltipFeatures, }; localStorage.setItem('glyphspace_preprocessing_state', JSON.stringify(serializable)); @@ -542,7 +527,7 @@ export class PreprocessingService { datasetName: parsed.datasetName, timestamp: parsed.timestamp, glyphFeatures: parsed.glyphFeatures || [], - tooltipFeatures: parsed.tooltipFeatures || [] + tooltipFeatures: parsed.tooltipFeatures || [], }); } } catch (error) { diff --git a/src/app/preprocessing-wizard/shared/_wizard-shared.scss b/src/app/preprocessing-wizard/shared/_wizard-shared.scss index 71148aa..8900370 100644 --- a/src/app/preprocessing-wizard/shared/_wizard-shared.scss +++ b/src/app/preprocessing-wizard/shared/_wizard-shared.scss @@ -2,16 +2,6 @@ // Shared wizard styles following GlyphSpace design system -// Step containers -@mixin step-container { - display: flex; - flex-direction: column; - height: 100%; - padding: 16px 32px; - max-width: 1150px; - margin: 0 auto; -} - @mixin step-header { text-align: center; margin-bottom: 16px; @@ -33,27 +23,10 @@ @mixin card { background: white; border: 1px solid v.$gray-300; - border-radius: 4px; + border-radius: 8px; overflow: hidden; } -@mixin card-header { - padding: 12px; - border-bottom: 1px solid v.$gray-300; - background: v.$gray-100; - - h3, h4 { - margin: 0; - font-size: 13px; - color: v.$gray-800; - font-weight: 600; - } -} - -@mixin card-body { - padding: 12px; -} - // Buttons @mixin btn-base { display: flex; @@ -61,7 +34,7 @@ gap: 6px; padding: 6px 12px; font-size: 13px; - border-radius: 4px; + border-radius: 8px; cursor: pointer; transition: all 0.2s ease; border: none; @@ -118,69 +91,92 @@ // Badges @mixin badge { padding: 2px 8px; - border-radius: 3px; + border-radius: 4px; font-size: 11px; font-weight: 600; text-transform: uppercase; } -@mixin badge-info { - @include badge; - background: rgba(0, 188, 212, 0.1); - color: v.$active-color; -} +// Status badge — used in review/processing steps +@mixin status-badge { + display: inline-flex; + align-items: center; + gap: 4px; + padding: 4px 8px; + border-radius: 4px; + font-size: 11px; + font-weight: 600; -@mixin badge-warning { - @include badge; - background: rgba(255, 152, 0, 0.1); - color: #E65100; -} + .material-icons { + font-size: 14px; + } -@mixin badge-success { - @include badge; - background: rgba(76, 175, 80, 0.1); - color: #388E3C; -} + &.status-yes, + &.status-complete { + background: rgba(v.$status-success, 0.1); + color: v.$status-success-dark; + } -@mixin badge-gray { - @include badge; - background: v.$gray-200; - color: v.$gray-700; + &.status-no { + background: rgba(158, 158, 158, 0.1); + color: v.$gray-600; + } + + &.status-running { + background: rgba(v.$active-color, 0.1); + color: v.$active-color; + } + + &.status-error { + background: rgba(v.$status-error, 0.1); + color: v.$status-error-dark; + } } -// Data type badges - using centralized colors +// Data type badges - using centralized colors (supports both class and attribute selectors) @mixin data-type-badge { @include badge; + flex-shrink: 0; - &[data-type="numeric"] { + &.badge-numeric { background: v.$data-type-numeric-bg; color: v.$data-type-numeric; } - &[data-type="categorical"] { + &.badge-categorical { background: v.$data-type-categorical-bg; color: v.$data-type-categorical; } - &[data-type="text"] { + &.badge-text { background: v.$data-type-text-bg; color: v.$data-type-text; } - &[data-type="date"] { + &.badge-date { background: v.$data-type-date-bg; color: v.$data-type-date; } - &[data-type="boolean"] { + &.badge-boolean { background: v.$data-type-boolean-bg; color: v.$data-type-boolean; } - &[data-type="id"] { + &.badge-id { background: v.$data-type-id-bg; color: v.$data-type-id; } + + &.badge-coordinate { + background: v.$data-type-coordinate-bg; + color: v.$data-type-coordinate; + } + + &.badge-unknown { + background: v.$data-type-unknown-bg; + color: v.$data-type-unknown; + } } // Messages @@ -189,7 +185,7 @@ align-items: center; gap: 8px; padding: 10px 12px; - border-radius: 2px; + border-radius: 8px; font-size: 13px; .material-icons { @@ -199,37 +195,30 @@ @mixin message-info { @include message-base; - background: rgba(0, 188, 212, 0.1); + background: rgba(v.$active-color, 0.1); border-left: 3px solid v.$active-color; - color: #00838f; + color: v.$status-info; } @mixin message-warning { @include message-base; - background: rgba(255, 152, 0, 0.1); - border-left: 3px solid #FF9800; - color: #E65100; -} - -@mixin message-success { - @include message-base; - background: rgba(76, 175, 80, 0.1); - border-left: 3px solid #4CAF50; - color: #2E7D32; + background: rgba(v.$status-warning, 0.1); + border-left: 3px solid v.$status-warning; + color: v.$status-warning-dark; } @mixin message-error { @include message-base; - background: rgba(244, 67, 54, 0.1); - border-left: 3px solid #F44336; - color: #C62828; + background: rgba(v.$status-error, 0.1); + border-left: 3px solid v.$status-error; + color: v.$status-error-dark; } // Form elements @mixin input-base { padding: 8px 10px; border: 1px solid v.$gray-300; - border-radius: 2px; + border-radius: 8px; font-size: 13px; background: white; transition: border-color 0.2s ease; @@ -261,7 +250,62 @@ accent-color: v.$active-color; } +// Search box — shared between column selection, data features, and legend +@mixin search-box($padding: 5px 8px, $icon-size: 18px, $border-color: v.$gray-300) { + display: flex; + align-items: center; + background: white; + border: 1px solid $border-color; + border-radius: 8px; + padding: $padding; + + .material-icons { + color: v.$gray-500; + font-size: $icon-size; + margin-right: 6px; + } + + .search-input { + flex: 1; + border: none; + outline: none; + font-size: 13px; + color: v.$gray-800; + background: transparent; + + &::placeholder { + color: v.$gray-500; + } + } + + .clear-search { + background: none; + border: none; + padding: 2px; + cursor: pointer; + display: flex; + align-items: center; + color: v.$gray-500; + + &:hover { + color: v.$gray-800; + } + + .material-icons { + font-size: 16px; + margin: 0; + } + } +} + // Tables +@mixin table-container { + background: white; + border: 1px solid v.$gray-300; + border-radius: 8px; + overflow-x: auto; +} + @mixin table { width: 100%; border-collapse: collapse; @@ -270,30 +314,50 @@ thead { background: v.$wizard-table-header-bg; - border-bottom: 2px solid v.$gray-300; - } + position: sticky; + top: 0; + z-index: 10; - th { - padding: 8px 10px; - text-align: left; - font-weight: 600; - color: v.$gray-700; - white-space: nowrap; - } + tr { + border-bottom: 2px solid v.$gray-300; + } - td { - padding: 8px 10px; - border-top: 1px solid v.$gray-200; - color: v.$gray-800; + th { + padding: 10px 12px; + text-align: left; + font-weight: 600; + color: v.$gray-700; + font-size: 12px; + text-transform: uppercase; + letter-spacing: 0.5px; + white-space: nowrap; + background: v.$wizard-table-header-bg; + } } - tbody tr { - &:hover { - background: v.$gray-100; + tbody { + tr { + border-bottom: 1px solid v.$gray-200; + + &:hover { + background: v.$gray-100; + } + } + + td { + padding: 10px 12px; + vertical-align: middle; + color: v.$gray-800; } } } +// Table cell helpers +@mixin column-name-text { + font-weight: 500; + color: v.$gray-800; +} + // Progress bars @mixin progress-bar { width: 100%; @@ -310,16 +374,17 @@ } // No content states -@mixin no-content { +@mixin no-content($padding: 40px 20px, $icon-size: 48px, $text-size: 13px) { display: flex; flex-direction: column; align-items: center; justify-content: center; - padding: 40px 20px; + padding: $padding; text-align: center; + color: v.$gray-600; .material-icons { - font-size: 48px; + font-size: $icon-size; color: v.$gray-400; margin-bottom: 12px; } @@ -331,19 +396,29 @@ } p { - font-size: 13px; + font-size: $text-size; color: v.$gray-600; margin: 4px 0; } } +// Step content wrapper - constrains content width while allowing footer to be full-width +@mixin step-content { + flex: 1; + padding: 16px 32px; + max-width: 1150px; + width: 100%; + margin: 0 auto; + box-sizing: border-box; +} + // Action buttons footer - fixed at bottom with Back on left, Next on right @mixin action-buttons-footer { display: flex; justify-content: space-between; align-items: center; gap: 12px; - padding: 16px; + padding: 16px 32px; border-top: 1px solid v.$gray-300; margin-top: auto; background: v.$wizard-header-bg; @@ -374,15 +449,6 @@ } } -@mixin success-box { - @include message-success; - margin-bottom: 16px; - - .material-icons { - flex-shrink: 0; - } -} - // Step purpose statement @mixin step-purpose { text-align: center; @@ -414,18 +480,6 @@ } } -// Badge with data loss warning -@mixin badge-data-loss { - @include badge-warning; - display: inline-flex; - align-items: center; - gap: 4px; - - .material-icons { - font-size: 14px; - } -} - // Helper classes that can be used directly in templates .info-box { @include info-box; @@ -435,10 +489,6 @@ @include warning-box; } -.success-box { - @include success-box; -} - .step-purpose { @include step-purpose; } @@ -446,47 +496,3 @@ .feature-progress { @include feature-progress; } - -.badge-data-loss { - @include badge-data-loss; -} - -.badge-numeric { - @include badge; - background: v.$data-type-numeric-bg; - color: v.$data-type-numeric; -} - -.badge-categorical { - @include badge; - background: v.$data-type-categorical-bg; - color: v.$data-type-categorical; -} - -.badge-text { - @include badge; - background: v.$data-type-text-bg; - color: v.$data-type-text; -} - -.badge-date { - @include badge; - background: v.$data-type-date-bg; - color: v.$data-type-date; -} - -.badge-boolean { - @include badge; - background: v.$data-type-boolean-bg; - color: v.$data-type-boolean; -} - -.badge-id { - @include badge; - background: v.$data-type-id-bg; - color: v.$data-type-id; -} - -.badge-warning { - @include badge-warning; -} diff --git a/src/app/preprocessing-wizard/shared/box-plot/box-plot.component.html b/src/app/preprocessing-wizard/shared/box-plot/box-plot.component.html deleted file mode 100644 index fbac5fd..0000000 --- a/src/app/preprocessing-wizard/shared/box-plot/box-plot.component.html +++ /dev/null @@ -1,109 +0,0 @@ - - - - - Min: {{ formatValue(min) }} - - - - - Max: {{ formatValue(max) }} - - - - - Q1: {{ formatValue(q1) }} | Q3: {{ formatValue(q3) }} - - - - - Median: {{ formatValue(median) }} - - - - @if (meanPos !== undefined) { - - Mean: {{ formatValue(mean) }} - - } - - - - - - - - - - {{ formatShortValue(min) }} - - - - - {{ formatShortValue(max) }} - - diff --git a/src/app/preprocessing-wizard/shared/box-plot/box-plot.component.scss b/src/app/preprocessing-wizard/shared/box-plot/box-plot.component.scss deleted file mode 100644 index 0bd94bd..0000000 --- a/src/app/preprocessing-wizard/shared/box-plot/box-plot.component.scss +++ /dev/null @@ -1,36 +0,0 @@ -.box-plot { - display: block; - - .whisker, - .whisker-cap, - .median { - transition: stroke-width 0.2s ease; - } - - .box { - transition: fill-opacity 0.2s ease; - } - - .mean { - transition: r 0.2s ease; - } - - &:hover { - .whisker, - .whisker-cap { - stroke-width: 2; - } - - .median { - stroke-width: 2.5; - } - - .box { - fill-opacity: 0.3; - } - - .mean { - r: 4; - } - } -} diff --git a/src/app/preprocessing-wizard/shared/box-plot/box-plot.component.ts b/src/app/preprocessing-wizard/shared/box-plot/box-plot.component.ts deleted file mode 100644 index b80d8cd..0000000 --- a/src/app/preprocessing-wizard/shared/box-plot/box-plot.component.ts +++ /dev/null @@ -1,86 +0,0 @@ -import { Component, Input, OnChanges } from '@angular/core'; -import { CommonModule } from '@angular/common'; - -@Component({ - selector: 'app-box-plot', - standalone: true, - imports: [CommonModule], - templateUrl: './box-plot.component.html', - styleUrl: './box-plot.component.scss' -}) -export class BoxPlotComponent implements OnChanges { - @Input() min: number = 0; - @Input() q1: number = 0; - @Input() median: number = 0; - @Input() q3: number = 0; - @Input() max: number = 0; - @Input() mean?: number; - @Input() width: number = 150; - @Input() height: number = 40; - @Input() color: string = '#00bcd4'; - - // Calculated positions - boxLeft: number = 0; - boxWidth: number = 0; - medianPos: number = 0; - meanPos?: number; - whiskerLeftPos: number = 0; - whiskerRightPos: number = 0; - - padding = 10; - plotWidth = 0; - boxHeight = 16; - boxY = 0; - - ngOnChanges(): void { - this.plotWidth = this.width - (this.padding * 2); - this.boxY = (this.height - this.boxHeight) / 2 - 4; // Leave room for labels - - const range = this.max - this.min; - if (range === 0) return; - - const scale = (value: number) => { - return this.padding + ((value - this.min) / range) * this.plotWidth; - }; - - this.whiskerLeftPos = scale(this.min); - this.whiskerRightPos = scale(this.max); - this.boxLeft = scale(this.q1); - this.boxWidth = scale(this.q3) - this.boxLeft; - this.medianPos = scale(this.median); - - if (this.mean !== undefined && this.mean !== null) { - this.meanPos = scale(this.mean); - } - } - - /** - * Format value for tooltips with full precision - */ - formatValue(value: number | undefined): string { - if (value === undefined || value === null) return '—'; - if (Math.abs(value) >= 1000) { - return value.toLocaleString('en-US', { maximumFractionDigits: 1 }); - } - return value.toLocaleString('en-US', { maximumFractionDigits: 2 }); - } - - /** - * Format value for axis labels (short) - */ - formatShortValue(value: number): string { - if (Math.abs(value) >= 1000000) { - return (value / 1000000).toFixed(1) + 'M'; - } - if (Math.abs(value) >= 1000) { - return (value / 1000).toFixed(1) + 'K'; - } - if (Math.abs(value) >= 100) { - return value.toFixed(0); - } - if (Math.abs(value) >= 1) { - return value.toFixed(1); - } - return value.toFixed(2); - } -} diff --git a/src/app/preprocessing-wizard/shared/column-statistics/column-statistics.component.html b/src/app/preprocessing-wizard/shared/column-statistics/column-statistics.component.html deleted file mode 100644 index c69bd45..0000000 --- a/src/app/preprocessing-wizard/shared/column-statistics/column-statistics.component.html +++ /dev/null @@ -1,106 +0,0 @@ -
-
-
{{ statistics.name }}
- - {{ dataTypeLabel }} - -
- - @if (hasIssues) { -
- warning - {{ issueDescription }} -
- } - -
- -
-
Completeness
-
-
-
-
-
- {{ statistics.count }} / {{ statistics.count + statistics.missingCount }} - ({{ completenessPercentage.toFixed(1) }}%) -
-
- - - @if (statistics.missingCount > 0) { -
-
Missing
-
- {{ statistics.missingCount }} - ({{ statistics.missingPercentage.toFixed(1) }}%) -
-
- } - - -
-
Unique values
-
{{ statistics.uniqueCount }}
-
- - @if (!compact) { - - @if (statistics.dataType === 'numeric' && statistics.min !== undefined) { -
-
Numeric Statistics
-
-
Min
-
{{ statistics.min !== undefined ? statistics.min.toFixed(3) : 'N/A' }}
-
-
-
Max
-
{{ statistics.max !== undefined ? statistics.max.toFixed(3) : 'N/A' }}
-
-
-
Mean
-
{{ statistics.mean !== undefined ? statistics.mean.toFixed(3) : 'N/A' }}
-
-
-
Median
-
{{ statistics.median !== undefined ? statistics.median.toFixed(3) : 'N/A' }}
-
-
-
Std Dev
-
{{ statistics.stdDev !== undefined ? statistics.stdDev.toFixed(3) : 'N/A' }}
-
-
- } - - - @if (statistics.topValues && statistics.topValues.length > 0) { -
-
Top Values
- @for (item of statistics.topValues; track item.value) { -
-
{{ item.value }}
-
{{ item.count }}
-
- } -
- } - - - @if (statistics.sampleValues && statistics.sampleValues.length > 0) { -
-
Sample Values
-
- @for (value of statistics.sampleValues; track value) { - {{ value }} - } -
-
- } - } -
-
diff --git a/src/app/preprocessing-wizard/shared/column-statistics/column-statistics.component.scss b/src/app/preprocessing-wizard/shared/column-statistics/column-statistics.component.scss deleted file mode 100644 index 037a466..0000000 --- a/src/app/preprocessing-wizard/shared/column-statistics/column-statistics.component.scss +++ /dev/null @@ -1,175 +0,0 @@ -@use '../../../../styles/variables' as v; - -.column-statistics { - background: white; - border: 1px solid v.$gray-200; - border-radius: 4px; - padding: 16px; - transition: box-shadow 0.2s ease; - - &:hover { - box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); - } - - &.compact { - padding: 12px; - } -} - -.stats-header { - display: flex; - align-items: center; - justify-content: space-between; - margin-bottom: 12px; - gap: 12px; -} - -.column-name { - font-size: 14px; - font-weight: 600; - color: v.$gray-800; - word-break: break-word; -} - -.data-type-badge { - padding: 4px 12px; - border-radius: 12px; - font-size: 11px; - font-weight: 600; - white-space: nowrap; - - &.badge-numeric { - background: rgba(0, 188, 212, 0.1); - color: v.$active-color; - } - - &.badge-categorical { - background: rgba(156, 39, 176, 0.1); - color: #7B1FA2; - } - - &.badge-text { - background: rgba(255, 152, 0, 0.1); - color: #E65100; - } - - &.badge-date { - background: rgba(76, 175, 80, 0.1); - color: #388E3C; - } - - &.badge-boolean { - background: rgba(233, 30, 99, 0.1); - color: #C2185B; - } - - &.badge-id { - background: v.$gray-200; - color: v.$gray-700; - } - - &.badge-unknown { - background: v.$gray-100; - color: v.$gray-600; - } -} - -.issue-warning { - display: flex; - align-items: center; - gap: 8px; - padding: 8px; - background: rgba(255, 152, 0, 0.1); - border-left: 3px solid #FF9800; - border-radius: 4px; - margin-bottom: 12px; - font-size: 13px; - color: #E65100; - - .material-icons { - font-size: 18px; - } -} - -.stats-content { - display: flex; - flex-direction: column; - gap: 10px; -} - -.stat-row { - display: flex; - justify-content: space-between; - align-items: center; - gap: 12px; - font-size: 13px; -} - -.stat-label { - color: v.$gray-600; - font-weight: 500; -} - -.stat-value { - color: v.$gray-800; - font-weight: 600; - text-align: right; - - &.text-warning { - color: #FF9800; - } -} - -.completeness-bar { - flex: 1; - height: 8px; - background: v.$gray-100; - border-radius: 4px; - overflow: hidden; -} - -.completeness-fill { - height: 100%; - transition: width 0.3s ease; - - &.good { - background: #4CAF50; - } - - &.warning { - background: #FF9800; - } - - &.poor { - background: #F44336; - } -} - -.stats-section { - margin-top: 12px; - padding-top: 12px; - border-top: 1px solid v.$gray-100; -} - -.section-title { - font-size: 13px; - font-weight: 600; - color: v.$gray-600; - margin-bottom: 10px; - text-transform: uppercase; - letter-spacing: 0.5px; -} - -.sample-values { - display: flex; - flex-wrap: wrap; - gap: 8px; -} - -.sample-chip { - padding: 4px 12px; - background: v.$gray-100; - border-radius: 12px; - font-size: 11px; - color: v.$gray-600; -} diff --git a/src/app/preprocessing-wizard/shared/column-statistics/column-statistics.component.ts b/src/app/preprocessing-wizard/shared/column-statistics/column-statistics.component.ts deleted file mode 100644 index cefbf44..0000000 --- a/src/app/preprocessing-wizard/shared/column-statistics/column-statistics.component.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { Component, Input } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { ColumnStatistics } from '../../models/column-statistics'; -import { DataType } from '../../models/data-type.enum'; - -@Component({ - selector: 'app-column-statistics', - standalone: true, - imports: [CommonModule], - templateUrl: './column-statistics.component.html', - styleUrl: './column-statistics.component.scss' -}) -export class ColumnStatisticsComponent { - @Input() statistics!: ColumnStatistics; - @Input() compact: boolean = false; - - get dataTypeBadgeClass(): string { - switch (this.statistics.dataType) { - case DataType.Numeric: return 'badge-numeric'; - case DataType.Categorical: return 'badge-categorical'; - case DataType.Text: return 'badge-text'; - case DataType.Date: return 'badge-date'; - case DataType.Boolean: return 'badge-boolean'; - case DataType.ID: return 'badge-id'; - default: return 'badge-unknown'; - } - } - - get dataTypeLabel(): string { - return this.statistics.dataType.charAt(0).toUpperCase() + - this.statistics.dataType.slice(1); - } - - get completenessPercentage(): number { - const total = this.statistics.count + this.statistics.missingCount; - if (total === 0) return 0; - return (this.statistics.count / total) * 100; - } - - get hasIssues(): boolean { - return this.statistics.missingPercentage > 50 || - this.statistics.uniqueCount === 1; - } - - get issueDescription(): string { - if (this.statistics.missingPercentage > 50) { - return `High missing values (${this.statistics.missingPercentage.toFixed(1)}%)`; - } - if (this.statistics.uniqueCount === 1) { - return 'All values are identical'; - } - return ''; - } -} diff --git a/src/app/preprocessing-wizard/shared/constants/help-text.ts b/src/app/preprocessing-wizard/shared/constants/help-text.ts index 8f9586f..469212e 100644 --- a/src/app/preprocessing-wizard/shared/constants/help-text.ts +++ b/src/app/preprocessing-wizard/shared/constants/help-text.ts @@ -12,7 +12,8 @@ export const HELP_TEXT = { date: 'Date or datetime values. Examples: 2024-01-15, timestamps', boolean: 'True/False or Yes/No values', id: 'Unique identifiers for each row. Examples: customer ID, transaction number', - coordinate: 'Geographic coordinates (latitude/longitude)' + coordinate: 'Geographic coordinates (latitude/longitude)', + unknown: 'Data type could not be determined automatically', }, // Encoding Methods @@ -20,48 +21,49 @@ export const HELP_TEXT = { none: { short: 'Keep original values without transformation', when: 'Use for: Data that is already numeric', - example: '' + example: '', }, oneHot: { short: 'Create separate binary columns for each category', when: 'Use for: Categorical data with few distinct values (<10)', - example: 'Example: \'Color: Red, Blue\' becomes two columns: Red=1/0, Blue=1/0' + example: + "Example: 'Color: Red, Blue' becomes two columns: Red=1/0, Blue=1/0", }, label: { short: 'Convert categories to integer codes', when: 'Use for: Categorical data with many distinct values', - example: 'Example: \'Red\'=0, \'Blue\'=1, \'Green\'=2' + example: "Example: 'Red'=0, 'Blue'=1, 'Green'=2", }, normalize: { short: 'Scale values to 0-1 range', when: 'Use for: Numeric data when you want all values between 0 and 1', - example: 'Example: Values 10-100 become 0.0-1.0' + example: 'Example: Values 10-100 become 0.0-1.0', }, standardize: { short: 'Transform to zero mean and unit variance (Z-score)', when: 'Use for: Numeric data following a normal distribution', - example: 'Example: Values are centered around 0 with standard deviation of 1' - } + example: 'Example: Values are centered around 0 with standard deviation of 1', + }, }, // Scaling Methods scaling: { none: { short: 'No scaling applied', - when: 'Use when: Data is already in desired range or scaling not needed' + when: 'Use when: Data is already in desired range or scaling not needed', }, standard: { short: 'Centers data around 0 with standard deviation of 1 (Z-score)', - when: 'Best for: Normally distributed data without major outliers' + when: 'Best for: Normally distributed data without major outliers', }, minMax: { short: 'Scales to exact 0-1 range', - when: 'Best for: When you need values in specific range. Warning: Sensitive to outliers' + when: 'Best for: When you need values in specific range. Warning: Sensitive to outliers', }, robust: { short: 'Uses median and IQR instead of mean and standard deviation', - when: 'Best for: Data with outliers - more resilient than standard scaling' - } + when: 'Best for: Data with outliers - more resilient than standard scaling', + }, }, // Missing Value Strategies @@ -71,24 +73,30 @@ export const HELP_TEXT = { fillMean: 'Replace missing values with the average (mean). Only works for numeric columns.', fillMedian: 'Replace missing values with the middle value (median). More robust to outliers than mean.', fillMode: 'Replace missing values with the most common value. Works for both numeric and categorical data.', - fillValue: 'Specify a custom value to use for all missing entries.' + fillValue: 'Specify a custom value to use for all missing entries.', }, // Outlier Detection Methods outlierMethods: { - iqr_1_5: 'IQR (1.5x) - Standard method
Flags values beyond 1.5× the box plot whiskers (Q1-1.5×IQR or Q3+1.5×IQR).
Most commonly used, balanced approach', - iqr_2_0: 'IQR (2.0x) - More relaxed
Catches only extreme outliers beyond 2× the IQR.
Use when you want to keep more data', - iqr_3_0: 'IQR (3.0x) - Very lenient
Minimal outlier detection - only catches very extreme values.
Use when outliers might be legitimate', - zscore_2: 'Z-Score (2σ) - Strict
Flags values more than 2 standard deviations from the mean.
Catches ~5% of data in normal distribution', - zscore_3: 'Z-Score (3σ) - Standard
Flags values more than 3 standard deviations from the mean.
Balanced statistical method, catches ~0.3% in normal distribution', - zscore_4: 'Z-Score (4σ) - Lenient
Only catches values very far from the mean (4+ standard deviations).
Very conservative approach' + iqr_1_5: + 'IQR (1.5x) - Standard method
Flags values beyond 1.5× the box plot whiskers (Q1-1.5×IQR or Q3+1.5×IQR).
Most commonly used, balanced approach', + iqr_2_0: + 'IQR (2.0x) - More relaxed
Catches only extreme outliers beyond 2× the IQR.
Use when you want to keep more data', + iqr_3_0: + 'IQR (3.0x) - Very lenient
Minimal outlier detection - only catches very extreme values.
Use when outliers might be legitimate', + zscore_2: + 'Z-Score (2σ) - Strict
Flags values more than 2 standard deviations from the mean.
Catches ~5% of data in normal distribution', + zscore_3: + 'Z-Score (3σ) - Standard
Flags values more than 3 standard deviations from the mean.
Balanced statistical method, catches ~0.3% in normal distribution', + zscore_4: + 'Z-Score (4σ) - Lenient
Only catches values very far from the mean (4+ standard deviations).
Very conservative approach', }, // Outlier Strategies outlierStrategies: { keep: 'Keep all outliers in your data. They may skew visualizations but preserve original information.', remove: 'Delete rows containing outlier values. ⚠ Warning: Data Loss', - cap: 'Limit outliers to boundary values (cap at threshold). Preserves row count while reducing extreme values.' + cap: 'Limit outliers to boundary values (cap at threshold). Preserves row count while reducing extreme values.', }, // Projection Methods @@ -96,16 +104,17 @@ export const HELP_TEXT = { pca: { name: 'PCA (Principal Component Analysis)', when: 'Shows immediately', - description: 'Fast linear dimensionality reduction that captures the directions of maximum variance in your data.', + description: + 'Fast linear dimensionality reduction that captures the directions of maximum variance in your data.', bestFor: [ 'Quick initial exploration', 'Understanding overall data structure', 'Identifying main patterns and outliers', - 'Linear relationships between features' + 'Linear relationships between features', ], characteristics: 'Creates smooth, broad patterns. Points far apart in PCA are genuinely different.', speed: 'Very fast (<1 second for most datasets)', - technical: 'Computes eigenvalues of covariance matrix. Always runs first to provide immediate visualization.' + technical: 'Computes eigenvalues of covariance matrix. Always runs first to provide immediate visualization.', }, fastmap: { @@ -116,11 +125,12 @@ export const HELP_TEXT = { 'Large datasets (40K+ items)', 'Quick initial exploration', 'Preserving pairwise distances', - 'When speed is critical' + 'When speed is critical', ], characteristics: 'Very fast projection that preserves distances. Great for initial exploration of large data.', speed: 'Very fast (sub-second even for 40K+ items)', - technical: 'Projects data to lower dimensions by selecting pivot points and computing distances. O(n) complexity.' + technical: + 'Projects data to lower dimensions by selecting pivot points and computing distances. O(n) complexity.', }, isomap: { @@ -131,11 +141,11 @@ export const HELP_TEXT = { 'Non-linear data structures', 'Preserving geodesic distances', 'Revealing manifold structure', - 'General-purpose visualization' + 'General-purpose visualization', ], characteristics: 'Captures non-linear relationships. Better than PCA for curved manifolds.', speed: 'Fast (few seconds for most datasets)', - technical: 'Builds neighborhood graph and computes shortest paths to preserve geodesic distances.' + technical: 'Builds neighborhood graph and computes shortest paths to preserve geodesic distances.', }, tsne: { @@ -146,20 +156,21 @@ export const HELP_TEXT = { 'Discovering clusters and groups', 'Revealing local structure', 'Visualizing high-dimensional data', - 'Pattern recognition' + 'Pattern recognition', ], - characteristics: 'Emphasizes local relationships. Clusters are meaningful, but distances between clusters are not.', + characteristics: + 'Emphasizes local relationships. Clusters are meaningful, but distances between clusters are not.', speed: 'Slow (seconds to minutes depending on dataset size)', parameters: { perplexity: 'Balances local vs. global structure (5-50). Higher = more global context.', - iterations: 'More iterations = better quality, but slower (500-5000)' + iterations: 'More iterations = better quality, but slower (500-5000)', }, technical: 'Uses gradient descent to minimize KL divergence. Computationally intensive.', warnings: [ 'Global structure (distances between clusters) may be misleading', 'Different runs may produce different results', - 'Can be very slow on large datasets (>10k rows)' - ] + 'Can be very slow on large datasets (>10k rows)', + ], }, umap: { @@ -170,19 +181,19 @@ export const HELP_TEXT = { 'Balancing local and global structure', 'Preserving more global relationships than t-SNE', 'Faster results on large datasets', - 'General-purpose visualization' + 'General-purpose visualization', ], characteristics: 'Maintains both cluster structure AND meaningful distances between clusters.', speed: 'Slow (but faster than t-SNE)', parameters: { neighbors: 'Size of local neighborhood (2-200). Higher = more global structure.', - minDist: 'Minimum distance between points (0.0-0.99). Lower = tighter clusters.' + minDist: 'Minimum distance between points (0.0-0.99). Lower = tighter clusters.', }, technical: 'Based on Riemannian geometry and topological data analysis.', warnings: [ 'Can be memory-intensive for very large datasets', - 'JavaScript version may differ slightly from Python implementation' - ] + 'JavaScript version may differ slightly from Python implementation', + ], }, mds: { @@ -193,11 +204,11 @@ export const HELP_TEXT = { 'Preserving overall distance structure', 'Creating interpretable layouts', 'When global relationships matter more than clusters', - 'Comparing similarity between items' + 'Comparing similarity between items', ], characteristics: 'Focuses on preserving distances. Similar items stay close together.', speed: 'Fast (few seconds)', - technical: 'Minimizes stress function to preserve pairwise distances in lower dimensions.' + technical: 'Minimizes stress function to preserve pairwise distances in lower dimensions.', }, lle: { @@ -208,15 +219,12 @@ export const HELP_TEXT = { 'Data lying on curved manifolds', 'Preserving local neighborhood structure', 'When data has intrinsic low-dimensional structure', - 'Discovering underlying geometry' + 'Discovering underlying geometry', ], characteristics: 'Assumes data lies on a smooth manifold. Good at unfolding curved structures.', speed: 'Medium (few seconds to a minute)', technical: 'Reconstructs each point from its neighbors, then finds low-dimensional embedding.', - warnings: [ - 'Sensitive to neighborhood size selection', - 'May struggle with holes or disconnected regions' - ] + warnings: ['Sensitive to neighborhood size selection', 'May struggle with holes or disconnected regions'], }, ltsa: { @@ -227,11 +235,11 @@ export const HELP_TEXT = { 'Curved manifolds with smooth transitions', 'When local geometry is complex', 'Understanding intrinsic data structure', - 'Datasets with well-defined neighborhoods' + 'Datasets with well-defined neighborhoods', ], characteristics: 'Better at handling curved manifolds than LLE. Uses local tangent approximations.', speed: 'Medium (few seconds to a minute)', - technical: 'Computes local tangent spaces and aligns them to find global coordinates.' + technical: 'Computes local tangent spaces and aligns them to find global coordinates.', }, trimap: { @@ -242,11 +250,11 @@ export const HELP_TEXT = { 'Large datasets where t-SNE is too slow', 'Preserving both local and global structure', 'When cluster separation matters', - 'General-purpose visualization' + 'General-purpose visualization', ], characteristics: 'Good balance of speed and quality. Better global structure than t-SNE.', speed: 'Medium (faster than t-SNE)', - technical: 'Uses triplet constraints to preserve relative distances.' + technical: 'Uses triplet constraints to preserve relative distances.', }, topomap: { @@ -257,11 +265,11 @@ export const HELP_TEXT = { 'Preserving topological features', 'When connectivity patterns matter', 'Network-like data structures', - 'Understanding data shape' + 'Understanding data shape', ], characteristics: 'Focuses on preserving the topological structure of the data.', speed: 'Medium', - technical: 'Preserves topological features like connected components and holes.' + technical: 'Preserves topological features like connected components and holes.', }, sammon: { @@ -272,11 +280,11 @@ export const HELP_TEXT = { 'When small distances are more important than large ones', 'Preserving local similarity', 'Compact visualizations', - 'Data with meaningful local structure' + 'Data with meaningful local structure', ], characteristics: 'Puts more weight on preserving small distances. Good for local structure.', speed: 'Medium', - technical: 'Minimizes Sammon stress with inverse weighting on original distances.' + technical: 'Minimizes Sammon stress with inverse weighting on original distances.', }, backgroundProcessing: { @@ -293,8 +301,8 @@ export const HELP_TEXT = { Progress Tracking: Check the projection status indicator in the top-right corner of Glyphspace to see which projections are ready, computing, or pending. - ` - } + `, + }, }, // Projection Parameters @@ -355,21 +363,29 @@ export const HELP_TEXT = { • Low (100-300): More flexible embedding
Default (500): Balanced
High (700-2000): Stricter triplet preservation

- Higher values produce tighter clusters but may over-constrain the layout` + Higher values produce tighter clusters but may over-constrain the layout`, }, // Table Column Headers tableHeaders: { type: 'Data type detected automatically based on column values.

Numeric: Numbers
Categorical: Limited distinct values
Text: Free-form text', - missing: 'Percentage of rows with no value in this column.

>50% missing may indicate poor data quality and could cause issues.', - unique: 'Number of distinct (different) values in this column.

High uniqueness in categorical columns can cause performance issues with one-hot encoding.', - distribution: 'Visual representation of value distribution.

Sparkline: Shows frequency of top categorical values
Box plot: Shows numeric quartiles and outliers', - statistics: 'Summary statistics for numeric columns.

Includes min, max, mean, median, and standard deviation.', + missing: + 'Percentage of rows with no value in this column.

>50% missing may indicate poor data quality and could cause issues.', + unique: + 'Number of distinct (different) values in this column.

High uniqueness in categorical columns can cause performance issues with one-hot encoding.', + distribution: + 'Visual representation of value distribution.

Shows a histogram of value frequencies for both numeric and categorical columns.', + statistics: + 'Summary statistics for numeric columns.

Includes min, max, mean, median, and standard deviation.', // Configure Data & Features column headers - encoding: 'Defines how data values are transformed.

Numeric data: Can be left as-is (None), scaled to a 0–1 range (Normalize), or centered and scaled to unit variance (Standardize).

Categorical data: Can be converted to numeric IDs (Label) or to separate binary columns for each category (One-hot).', - scaling: 'Adjusts numeric values to make them comparable.

None: No scaling
Standard: Standardization to mean 0 and unit variance
Min-Max: Scaling to a fixed range like 0–1
Robust: Scaling based on percentiles to reduce outlier effects', - missingValues: 'Controls how missing data is handled.

Keep: Keep them as-is
Remove rows: Remove rows containing them
Fill mode: Fill with the most common value
Fill value: Fill with a custom value', - outliers: 'Controls how extreme values are handled.

Outliers can be detected using the interquartile range (IQR) or z-Score (measuring how far a value is from the mean in standard deviations).

Keep: Keep outliers
Remove: Remove rows with outliers
Cap: Limit values to the threshold' + encoding: + 'Defines how data values are transformed.

Numeric data: Can be left as-is (None), scaled to a 0–1 range (Normalize), or centered and scaled to unit variance (Standardize).

Categorical data: Can be converted to numeric IDs (Label) or to separate binary columns for each category (One-hot).', + scaling: + 'Adjusts numeric values to make them comparable.

None: No scaling
Standard: Standardization to mean 0 and unit variance
Min-Max: Scaling to a fixed range like 0–1
Robust: Scaling based on percentiles to reduce outlier effects', + missingValues: + 'Controls how missing data is handled.

Keep: Keep them as-is
Remove rows: Remove rows containing them
Fill mode: Fill with the most common value
Fill value: Fill with a custom value', + outliers: + 'Controls how extreme values are handled.

Outliers can be detected using the interquartile range (IQR) or z-Score (measuring how far a value is from the mean in standard deviations).

Keep: Keep outliers
Remove: Remove rows with outliers
Cap: Limit values to the threshold', }, // General concepts @@ -412,6 +428,6 @@ export const HELP_TEXT = { • Categorical (few values): One-Hot encoding
Categorical (many values): Label encoding
Text/ID columns: Excluded from projection

- You can change any of these if needed` - } + You can change any of these if needed`, + }, }; diff --git a/src/app/preprocessing-wizard/shared/constants/step-info.ts b/src/app/preprocessing-wizard/shared/constants/step-info.ts index 903ce05..71bbda0 100644 --- a/src/app/preprocessing-wizard/shared/constants/step-info.ts +++ b/src/app/preprocessing-wizard/shared/constants/step-info.ts @@ -11,18 +11,23 @@ export interface StepInfo { export const STEP_INFO: Record = { 0: { title: 'Upload Data', - purpose: 'Upload your CSV or Parquet file to begin analyzing and preparing your data for visualization' + purpose: 'Upload your CSV or Parquet file to begin analyzing and preparing your data for visualization', }, 1: { title: 'Select Columns', - purpose: 'Choose which columns to include in your visualization. Deselect ID fields and irrelevant columns.' + purpose: 'Choose which columns to include in your visualization. Deselect ID fields and irrelevant columns.', }, 2: { title: 'Configure Data & Features', - purpose: 'Configure data cleaning, encoding, scaling, and projection settings for each column in a unified table view.' + purpose: + 'Configure encoding, scaling, and data cleaning settings for each column. Select a column to view and edit its options.', }, 3: { title: 'Visualization Settings', - purpose: 'Select color and glyph features, choose projection methods, review your configuration, and process your data.' - } + purpose: 'Configure glyph features with live preview, set color mapping, and select projection methods.', + }, + 4: { + title: 'Review & Process', + purpose: 'Review your configuration summary and process the data for visualization.', + }, }; diff --git a/src/app/preprocessing-wizard/shared/data-preview-table/data-preview-table.component.html b/src/app/preprocessing-wizard/shared/data-preview-table/data-preview-table.component.html index 795a071..a418820 100644 --- a/src/app/preprocessing-wizard/shared/data-preview-table/data-preview-table.component.html +++ b/src/app/preprocessing-wizard/shared/data-preview-table/data-preview-table.component.html @@ -28,9 +28,7 @@ @if (data.length > maxRows) { - + } } diff --git a/src/app/preprocessing-wizard/shared/data-preview-table/data-preview-table.component.scss b/src/app/preprocessing-wizard/shared/data-preview-table/data-preview-table.component.scss index cf7179b..31faca5 100644 --- a/src/app/preprocessing-wizard/shared/data-preview-table/data-preview-table.component.scss +++ b/src/app/preprocessing-wizard/shared/data-preview-table/data-preview-table.component.scss @@ -1,9 +1,8 @@ @use '../../../../styles/variables' as v; +@use '../../shared/wizard-shared' as wizard; .data-preview-table { - background: white; - border-radius: 4px; - border: 1px solid v.$gray-200; + @include wizard.table-container; overflow: hidden; } @@ -15,55 +14,29 @@ .table-container { overflow-x: auto; - max-height: 400px; - overflow-y: auto; } table { - width: 100%; - border-collapse: collapse; - font-size: 13px; -} - -thead { - position: sticky; - top: 0; - background: v.$gray-100; - z-index: 10; + @include wizard.table; - th { - padding: 10px 12px; - text-align: left; - font-weight: 600; - color: v.$gray-800; - border-bottom: 2px solid v.$gray-200; + thead th, + tbody td { + max-width: 180px; white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + thead th { &.highlighted { - background: rgba(0, 188, 212, 0.1); + background: rgba(v.$active-color, 0.1); color: v.$active-color; } } -} - -tbody { - tr { - &:nth-child(even) { - background: v.$gray-100; - } - - &:hover { - background: v.$gray-200; - } - } - - td { - padding: 10px 12px; - border-bottom: 1px solid v.$gray-100; - color: v.$gray-600; + tbody td { &.highlighted { - background: rgba(76, 175, 80, 0.1); + background: rgba(v.$status-success, 0.1); } } } diff --git a/src/app/preprocessing-wizard/shared/data-preview-table/data-preview-table.component.ts b/src/app/preprocessing-wizard/shared/data-preview-table/data-preview-table.component.ts index 782adf5..9b8042d 100644 --- a/src/app/preprocessing-wizard/shared/data-preview-table/data-preview-table.component.ts +++ b/src/app/preprocessing-wizard/shared/data-preview-table/data-preview-table.component.ts @@ -1,20 +1,18 @@ import { Component, Input } from '@angular/core'; -import { CommonModule } from '@angular/common'; - @Component({ selector: 'app-data-preview-table', standalone: true, - imports: [CommonModule], + imports: [], templateUrl: './data-preview-table.component.html', - styleUrl: './data-preview-table.component.scss' + styleUrl: './data-preview-table.component.scss', }) export class DataPreviewTableComponent { - @Input() data: any[] = []; + @Input() data: Record[] = []; @Input() columns: string[] = []; - @Input() highlightColumns: Set = new Set(); - @Input() maxRows: number = 10; + @Input() highlightColumns = new Set(); + @Input() maxRows = 10; - get displayData(): any[] { + get displayData(): Record[] { return this.data.slice(0, this.maxRows); } @@ -32,7 +30,7 @@ export class DataPreviewTableComponent { return this.highlightColumns.has(column); } - getCellValue(row: any, column: string): string { + getCellValue(row: Record, column: string): string { const value = row[column]; if (value === null || value === undefined) { return '-'; diff --git a/src/app/preprocessing-wizard/shared/data-type-badge/data-type-badge.component.scss b/src/app/preprocessing-wizard/shared/data-type-badge/data-type-badge.component.scss new file mode 100644 index 0000000..9a0bb6c --- /dev/null +++ b/src/app/preprocessing-wizard/shared/data-type-badge/data-type-badge.component.scss @@ -0,0 +1,6 @@ +@use '../../../../styles/variables' as v; +@use '../wizard-shared' as wizard; + +.data-type-badge { + @include wizard.data-type-badge; +} diff --git a/src/app/preprocessing-wizard/shared/data-type-badge/data-type-badge.component.ts b/src/app/preprocessing-wizard/shared/data-type-badge/data-type-badge.component.ts new file mode 100644 index 0000000..27a79ba --- /dev/null +++ b/src/app/preprocessing-wizard/shared/data-type-badge/data-type-badge.component.ts @@ -0,0 +1,19 @@ +import { Component, Input } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { DataType, getDataTypeBadgeClass, getDataTypeLabel } from '../../models/data-type.enum'; + +@Component({ + selector: 'app-data-type-badge', + standalone: true, + imports: [CommonModule], + template: `{{ + getDataTypeLabel(dataType) + }}`, + styleUrl: './data-type-badge.component.scss', +}) +export class DataTypeBadgeComponent { + @Input() dataType!: DataType; + + getDataTypeBadgeClass = getDataTypeBadgeClass; + getDataTypeLabel = getDataTypeLabel; +} diff --git a/src/app/preprocessing-wizard/shared/help-tooltip/help-tooltip.component.html b/src/app/preprocessing-wizard/shared/help-tooltip/help-tooltip.component.html index 6685d6a..c49f1bd 100644 --- a/src/app/preprocessing-wizard/shared/help-tooltip/help-tooltip.component.html +++ b/src/app/preprocessing-wizard/shared/help-tooltip/help-tooltip.component.html @@ -9,7 +9,8 @@ [attr.aria-label]="'Help: ' + helpText" [attr.aria-expanded]="isVisible" type="button" - tabindex="0"> + tabindex="0" + > help_outline @@ -19,7 +20,8 @@ [class.visible]="isVisible" [ngStyle]="tooltipStyle" role="tooltip" - [attr.aria-hidden]="!isVisible"> + [attr.aria-hidden]="!isVisible" + >
diff --git a/src/app/preprocessing-wizard/shared/help-tooltip/help-tooltip.component.scss b/src/app/preprocessing-wizard/shared/help-tooltip/help-tooltip.component.scss index 2526094..d185e13 100644 --- a/src/app/preprocessing-wizard/shared/help-tooltip/help-tooltip.component.scss +++ b/src/app/preprocessing-wizard/shared/help-tooltip/help-tooltip.component.scss @@ -46,7 +46,9 @@ max-width: 280px; opacity: 0; visibility: hidden; - transition: opacity 0.15s ease, visibility 0.15s ease; + transition: + opacity 0.15s ease, + visibility 0.15s ease; pointer-events: none; box-sizing: border-box; overflow: hidden; @@ -77,7 +79,8 @@ color: v.$gray-800; } - ul, ol { + ul, + ol { margin: 8px 0; padding-left: 20px; } diff --git a/src/app/preprocessing-wizard/shared/help-tooltip/help-tooltip.component.ts b/src/app/preprocessing-wizard/shared/help-tooltip/help-tooltip.component.ts index f2602d2..383d09e 100644 --- a/src/app/preprocessing-wizard/shared/help-tooltip/help-tooltip.component.ts +++ b/src/app/preprocessing-wizard/shared/help-tooltip/help-tooltip.component.ts @@ -1,4 +1,4 @@ -import { Component, Input, HostListener, ElementRef, ViewChild, AfterViewInit, ChangeDetectorRef } from '@angular/core'; +import { Component, Input, HostListener, ElementRef, ViewChild, ChangeDetectorRef } from '@angular/core'; import { CommonModule } from '@angular/common'; @Component({ @@ -6,21 +6,20 @@ import { CommonModule } from '@angular/common'; standalone: true, imports: [CommonModule], templateUrl: './help-tooltip.component.html', - styleUrl: './help-tooltip.component.scss' + styleUrl: './help-tooltip.component.scss', }) -export class HelpTooltipComponent implements AfterViewInit { - @Input() helpText: string = ''; +export class HelpTooltipComponent { + @Input() helpText = ''; @Input() position: 'top' | 'bottom' | 'left' | 'right' = 'top'; @ViewChild('tooltipContent') tooltipContent!: ElementRef; isVisible = false; - tooltipStyle: { [key: string]: string } = {}; + tooltipStyle: Record = {}; - constructor(private elementRef: ElementRef, private cdr: ChangeDetectorRef) {} - - ngAfterViewInit(): void { - // Initial positioning - } + constructor( + private elementRef: ElementRef, + private cdr: ChangeDetectorRef + ) {} showTooltip(): void { this.isVisible = true; @@ -58,18 +57,18 @@ export class HelpTooltipComponent implements AfterViewInit { switch (this.position) { case 'top': top = rect.top - tooltipRect.height - offset; - left = rect.left + (rect.width / 2) - (tooltipRect.width / 2); + left = rect.left + rect.width / 2 - tooltipRect.width / 2; break; case 'bottom': top = rect.bottom + offset; - left = rect.left + (rect.width / 2) - (tooltipRect.width / 2); + left = rect.left + rect.width / 2 - tooltipRect.width / 2; break; case 'left': - top = rect.top + (rect.height / 2) - (tooltipRect.height / 2); + top = rect.top + rect.height / 2 - tooltipRect.height / 2; left = rect.left - tooltipRect.width - offset; break; case 'right': - top = rect.top + (rect.height / 2) - (tooltipRect.height / 2); + top = rect.top + rect.height / 2 - tooltipRect.height / 2; left = rect.right + offset; break; } @@ -87,7 +86,7 @@ export class HelpTooltipComponent implements AfterViewInit { this.tooltipStyle = { top: `${top}px`, - left: `${left}px` + left: `${left}px`, }; this.cdr.detectChanges(); }, 0); diff --git a/src/app/preprocessing-wizard/shared/histogram-chart/histogram-chart.component.html b/src/app/preprocessing-wizard/shared/histogram-chart/histogram-chart.component.html deleted file mode 100644 index 88dd76e..0000000 --- a/src/app/preprocessing-wizard/shared/histogram-chart/histogram-chart.component.html +++ /dev/null @@ -1,7 +0,0 @@ -
- @if (!data || data.counts.length === 0) { -
No histogram data available
- } @else { -
- } -
diff --git a/src/app/preprocessing-wizard/shared/histogram-chart/histogram-chart.component.scss b/src/app/preprocessing-wizard/shared/histogram-chart/histogram-chart.component.scss deleted file mode 100644 index dd45db5..0000000 --- a/src/app/preprocessing-wizard/shared/histogram-chart/histogram-chart.component.scss +++ /dev/null @@ -1,29 +0,0 @@ -@use '../../../../styles/variables' as v; - -.histogram-chart { - width: 100%; - height: 100%; -} - -.chart-container { - width: 100%; - height: 100%; - - ::ng-deep svg { - display: block; - } - - ::ng-deep .bar { - cursor: pointer; - transition: opacity 0.2s ease; - } -} - -.no-data { - display: flex; - align-items: center; - justify-content: center; - height: 100%; - color: v.$gray-500; - font-size: 13px; -} diff --git a/src/app/preprocessing-wizard/shared/histogram-chart/histogram-chart.component.ts b/src/app/preprocessing-wizard/shared/histogram-chart/histogram-chart.component.ts deleted file mode 100644 index 6c7361c..0000000 --- a/src/app/preprocessing-wizard/shared/histogram-chart/histogram-chart.component.ts +++ /dev/null @@ -1,120 +0,0 @@ -import { Component, Input, OnInit, OnChanges, ElementRef, ViewChild, AfterViewInit } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import * as d3 from 'd3'; -import { HistogramData } from '../../models/column-statistics'; - -@Component({ - selector: 'app-histogram-chart', - standalone: true, - imports: [CommonModule], - templateUrl: './histogram-chart.component.html', - styleUrl: './histogram-chart.component.scss' -}) -export class HistogramChartComponent implements OnInit, OnChanges, AfterViewInit { - @ViewChild('chart', { static: false }) chartContainer!: ElementRef; - - @Input() data!: HistogramData; - @Input() width: number = 300; - @Input() height: number = 150; - @Input() showAxes: boolean = true; - @Input() color: string = '#2196F3'; - - private svg: any; - private initialized = false; - - ngOnInit(): void { - } - - ngAfterViewInit(): void { - this.initialized = true; - if (this.data) { - this.createChart(); - } - } - - ngOnChanges(): void { - if (this.initialized && this.data) { - this.createChart(); - } - } - - private createChart(): void { - if (!this.chartContainer || !this.data) return; - - // Clear previous chart - d3.select(this.chartContainer.nativeElement).selectAll('*').remove(); - - const margin = this.showAxes - ? { top: 10, right: 10, bottom: 30, left: 40 } - : { top: 5, right: 5, bottom: 5, left: 5 }; - - const width = this.width - margin.left - margin.right; - const height = this.height - margin.top - margin.bottom; - - // Create SVG - this.svg = d3.select(this.chartContainer.nativeElement) - .append('svg') - .attr('width', this.width) - .attr('height', this.height) - .append('g') - .attr('transform', `translate(${margin.left},${margin.top})`); - - // Scales - const xScale = d3.scaleLinear() - .domain([0, this.data.counts.length]) - .range([0, width]); - - const yScale = d3.scaleLinear() - .domain([0, d3.max(this.data.counts) || 1]) - .range([height, 0]); - - // Bars - const barWidth = width / this.data.counts.length; - - this.svg.selectAll('.bar') - .data(this.data.counts) - .enter() - .append('rect') - .attr('class', 'bar') - .attr('x', (d: number, i: number) => xScale(i)) - .attr('y', (d: number) => yScale(d)) - .attr('width', barWidth - 1) - .attr('height', (d: number) => height - yScale(d)) - .attr('fill', this.color) - .attr('opacity', 0.8) - .on('mouseover', function(this: SVGRectElement) { - d3.select(this).attr('opacity', 1); - }) - .on('mouseout', function(this: SVGRectElement) { - d3.select(this).attr('opacity', 0.8); - }); - - if (this.showAxes) { - // X Axis - const xAxis = d3.axisBottom(xScale) - .ticks(5) - .tickFormat((d: any) => { - const index = Math.floor(d); - if (index >= 0 && index < this.data.binEdges.length) { - return this.data.binEdges[index].toFixed(1); - } - return ''; - }); - - this.svg.append('g') - .attr('transform', `translate(0,${height})`) - .call(xAxis) - .selectAll('text') - .style('font-size', '10px'); - - // Y Axis - const yAxis = d3.axisLeft(yScale) - .ticks(5); - - this.svg.append('g') - .call(yAxis) - .selectAll('text') - .style('font-size', '10px'); - } - } -} diff --git a/src/app/preprocessing-wizard/shared/progress-stepper/progress-stepper.component.html b/src/app/preprocessing-wizard/shared/progress-stepper/progress-stepper.component.html index 6f5198a..a4b1bca 100644 --- a/src/app/preprocessing-wizard/shared/progress-stepper/progress-stepper.component.html +++ b/src/app/preprocessing-wizard/shared/progress-stepper/progress-stepper.component.html @@ -7,8 +7,10 @@ [class.active]="isStepActive($index)" [class.completed]="isStepCompleted($index)" [class.clickable]="isStepClickable($index)" - (click)="onStepClick($index)"> - + (click)="onStepClick($index)" + (keydown.enter)="onStepClick($index)" + tabindex="0" + >
@if (isStepCompleted($index) && !isStepActive($index)) { check @@ -21,10 +23,7 @@
@if ($index < steps.length - 1) { -
-
+
} } diff --git a/src/app/preprocessing-wizard/shared/progress-stepper/progress-stepper.component.scss b/src/app/preprocessing-wizard/shared/progress-stepper/progress-stepper.component.scss index faecf26..4001bf8 100644 --- a/src/app/preprocessing-wizard/shared/progress-stepper/progress-stepper.component.scss +++ b/src/app/preprocessing-wizard/shared/progress-stepper/progress-stepper.component.scss @@ -3,7 +3,7 @@ .progress-stepper { width: 100%; padding: 16px 0; - background: v.$gray-200; + background: v.$wizard-header-bg; border-bottom: 1px solid v.$gray-300; &.vertical { @@ -73,20 +73,19 @@ .stepper-container { display: flex; - align-items: center; - justify-content: space-between; + align-items: flex-start; max-width: 900px; margin: 0 auto; - padding: 0 16px; + padding: 0 24px; } .step-wrapper { display: flex; - align-items: center; + align-items: flex-start; flex: 1; &:last-child { - flex: 0; + flex: 0 0 auto; .step-connector { display: none; @@ -100,6 +99,8 @@ align-items: center; gap: 6px; cursor: default; + width: 110px; + flex-shrink: 0; &.clickable { cursor: pointer; @@ -111,13 +112,13 @@ &.active .step-circle { background: v.$active-color; - color: white; + color: v.$white; border-color: v.$active-color; } &.completed .step-circle { background: v.$gray-600; - color: white; + color: v.$white; border-color: v.$gray-600; } } @@ -127,7 +128,7 @@ height: 32px; border-radius: 50%; border: 2px solid v.$gray-400; - background: white; + background: v.$white; display: flex; align-items: center; justify-content: center; @@ -148,7 +149,7 @@ font-size: 12px; color: v.$gray-600; text-align: center; - white-space: nowrap; + line-height: 1.3; .active & { color: v.$active-color; @@ -164,7 +165,7 @@ flex: 1; height: 2px; background: v.$gray-300; - margin: 0 12px; + margin: 15px 0 0; transition: background 0.2s ease; &.completed { @@ -194,8 +195,12 @@ font-size: 12px; } + .step { + width: 80px; + } + .step-connector { - margin: 0 8px; + margin: 13px 0 0; } .progress-stepper.vertical { diff --git a/src/app/preprocessing-wizard/shared/progress-stepper/progress-stepper.component.ts b/src/app/preprocessing-wizard/shared/progress-stepper/progress-stepper.component.ts index f2ec6e1..b3d7f7c 100644 --- a/src/app/preprocessing-wizard/shared/progress-stepper/progress-stepper.component.ts +++ b/src/app/preprocessing-wizard/shared/progress-stepper/progress-stepper.component.ts @@ -1,6 +1,4 @@ import { Component, Input, Output, EventEmitter } from '@angular/core'; -import { CommonModule } from '@angular/common'; - export interface Step { label: string; icon?: string; @@ -10,14 +8,14 @@ export interface Step { @Component({ selector: 'app-progress-stepper', standalone: true, - imports: [CommonModule], + imports: [], templateUrl: './progress-stepper.component.html', - styleUrl: './progress-stepper.component.scss' + styleUrl: './progress-stepper.component.scss', }) export class ProgressStepperComponent { @Input() steps: Step[] = []; - @Input() currentStep: number = 0; - @Input() vertical: boolean = false; + @Input() currentStep = 0; + @Input() vertical = false; @Output() stepClick = new EventEmitter(); onStepClick(index: number): void { diff --git a/src/app/preprocessing-wizard/shared/sparkline-chart/sparkline-chart.component.html b/src/app/preprocessing-wizard/shared/sparkline-chart/sparkline-chart.component.html deleted file mode 100644 index e9d7862..0000000 --- a/src/app/preprocessing-wizard/shared/sparkline-chart/sparkline-chart.component.html +++ /dev/null @@ -1,27 +0,0 @@ - - @if (type === 'bar') { - @for (bar of bars; track $index) { - - {{ bar.label }} - - } - } @else { - - } - diff --git a/src/app/preprocessing-wizard/shared/sparkline-chart/sparkline-chart.component.scss b/src/app/preprocessing-wizard/shared/sparkline-chart/sparkline-chart.component.scss deleted file mode 100644 index 414b7f3..0000000 --- a/src/app/preprocessing-wizard/shared/sparkline-chart/sparkline-chart.component.scss +++ /dev/null @@ -1,17 +0,0 @@ -.sparkline { - display: inline-block; - vertical-align: middle; -} - -.sparkline-bar-item { - opacity: 0.8; - transition: opacity 0.2s ease; - - &:hover { - opacity: 1; - } -} - -.sparkline-path { - vector-effect: non-scaling-stroke; -} diff --git a/src/app/preprocessing-wizard/shared/sparkline-chart/sparkline-chart.component.ts b/src/app/preprocessing-wizard/shared/sparkline-chart/sparkline-chart.component.ts deleted file mode 100644 index 2e21a5c..0000000 --- a/src/app/preprocessing-wizard/shared/sparkline-chart/sparkline-chart.component.ts +++ /dev/null @@ -1,73 +0,0 @@ -import { Component, Input, OnChanges } from '@angular/core'; -import { CommonModule } from '@angular/common'; - -@Component({ - selector: 'app-sparkline-chart', - standalone: true, - imports: [CommonModule], - templateUrl: './sparkline-chart.component.html', - styleUrl: './sparkline-chart.component.scss' -}) -export class SparklineChartComponent implements OnChanges { - @Input() data: number[] = []; - @Input() labels: string[] = []; // Labels for tooltip - @Input() width: number = 100; - @Input() height: number = 30; - @Input() color: string = '#00bcd4'; - @Input() type: 'bar' | 'line' = 'bar'; - - svgPath: string = ''; - bars: Array<{ x: number; y: number; width: number; height: number; label: string; value: number }> = []; - maxValue: number = 0; - - ngOnChanges(): void { - if (this.data && this.data.length > 0) { - this.maxValue = Math.max(...this.data); - - if (this.type === 'bar') { - this.generateBars(); - } else { - this.generateLine(); - } - } - } - - private generateBars(): void { - const barWidth = this.width / this.data.length; - const barSpacing = barWidth * 0.1; - const actualBarWidth = barWidth - barSpacing; - - this.bars = this.data.map((value, index) => { - const barHeight = this.maxValue > 0 ? (value / this.maxValue) * this.height : 0; - // If label is provided, use it as-is (may already include count) - // Otherwise create a default label with count - const label = this.labels && this.labels[index] - ? this.labels[index] - : `#${index + 1}: ${value}`; - return { - x: index * barWidth, - y: this.height - barHeight, - width: actualBarWidth, - height: barHeight, - label: label, - value: value - }; - }); - } - - private generateLine(): void { - if (this.data.length === 0) { - this.svgPath = ''; - return; - } - - const stepX = this.width / (this.data.length - 1); - const points = this.data.map((value, index) => { - const x = index * stepX; - const y = this.maxValue > 0 ? this.height - (value / this.maxValue) * this.height : this.height; - return `${x},${y}`; - }); - - this.svgPath = `M ${points.join(' L ')}`; - } -} diff --git a/src/app/preprocessing-wizard/shared/wizard-histogram/wizard-histogram.component.ts b/src/app/preprocessing-wizard/shared/wizard-histogram/wizard-histogram.component.ts deleted file mode 100644 index c3ae70b..0000000 --- a/src/app/preprocessing-wizard/shared/wizard-histogram/wizard-histogram.component.ts +++ /dev/null @@ -1,252 +0,0 @@ -import { Component, Input, OnInit, OnChanges, ElementRef, ViewChild, AfterViewInit, SimpleChanges } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import * as d3 from 'd3'; -import { HistogramData } from '../../models/column-statistics'; -import { DataType } from '../../models/data-type.enum'; -import { StackedBin } from '../../../shared/types/histogram.types'; -import { - prepareStackedBinsFromArray, - rebinHistogramData, - darkenColor -} from '../../../shared/utils/histogram.utils'; - -@Component({ - selector: 'app-wizard-histogram', - standalone: true, - imports: [CommonModule], - templateUrl: './wizard-histogram.component.html', - styleUrl: './wizard-histogram.component.scss' -}) -export class WizardHistogramComponent implements OnInit, OnChanges, AfterViewInit { - @ViewChild('chartContainer', { static: false }) chartContainer!: ElementRef; - - @Input() data!: HistogramData; - @Input() dataType!: DataType; - @Input() color: string = '#2196F3'; - @Input() width: number = 120; - @Input() height: number = 40; - @Input() enabled: boolean = true; - - private svg: any; - private initialized = false; - private cachedStackedBins: StackedBin[] | null = null; - - hoverLabel: string = ''; - showHoverLabel: boolean = false; - private lastHoveredBar: any = null; - private hoverLabelElement: HTMLElement | null = null; - - private readonly MAX_CATEGORICAL_BINS = 40; - private readonly MAX_NUMERIC_BINS = 20; - private readonly margin = { top: 2, right: 2, bottom: 2, left: 2 }; - - ngOnInit(): void { - } - - ngAfterViewInit(): void { - this.initialized = true; - // Cache the hover label element - if (this.chartContainer) { - const parent = this.chartContainer.nativeElement.parentElement; - if (parent) { - this.hoverLabelElement = parent.querySelector('.hover-label'); - } - } - if (this.data) { - this.createChart(); - } - } - - ngOnChanges(changes: SimpleChanges): void { - if (this.initialized && this.data) { - if (changes['enabled'] || changes['data'] || changes['color']) { - this.cachedStackedBins = null; - this.createChart(); - } - } - } - - private createChart(): void { - if (!this.chartContainer || !this.data) return; - - // Clear previous chart - d3.select(this.chartContainer.nativeElement).selectAll('*').remove(); - this.lastHoveredBar = null; - this.showHoverLabel = false; - - const width = this.width - this.margin.left - this.margin.right; - const height = this.height - this.margin.top - this.margin.bottom; - - // Create SVG - this.svg = d3.select(this.chartContainer.nativeElement) - .append('svg') - .attr('width', this.width) - .attr('height', this.height) - .append('g') - .attr('transform', `translate(${this.margin.left},${this.margin.top})`); - - const effectiveType = this.getEffectiveType(); - - if (effectiveType === 'categorical') { - this.drawCategoricalHistogram(width, height); - } else { - this.drawNumericHistogram(width, height); - } - } - - private getEffectiveType(): string { - if (!this.cachedStackedBins) { - this.cachedStackedBins = this.prepareStackedBins(); - } - - const nonZeroBinCount = this.cachedStackedBins.length; - - // If declared as categorical but has too many non-zero bins, treat as numeric - if ((this.dataType === DataType.Categorical || this.dataType === DataType.Boolean) - && nonZeroBinCount > this.MAX_CATEGORICAL_BINS) { - return 'numeric'; - } - - // If categorical, boolean, or text type with reasonable bins - if (this.dataType === DataType.Categorical || - this.dataType === DataType.Boolean || - this.dataType === DataType.Text) { - return 'categorical'; - } - - // Default to numeric for numeric and date types - return 'numeric'; - } - - private prepareStackedBins(): StackedBin[] { - return prepareStackedBinsFromArray( - this.data.counts, - this.data.labels, - { availableWidth: this.width - this.margin.left - this.margin.right } - ); - } - - private drawCategoricalHistogram(width: number, height: number): void { - if (!this.data || !this.svg) return; - - const bins = this.cachedStackedBins || this.prepareStackedBins(); - if (bins.length === 0) return; - - const displayColor = this.enabled ? this.color : '#ccc'; - const darkerColor = darkenColor(displayColor); - - const bars = this.svg.selectAll('rect') - .data(bins) - .enter() - .append('rect') - .attr('class', 'histogram-bar') - .attr('x', (d: StackedBin) => d.x0) - .attr('y', 0) - .attr('width', (d: StackedBin) => d.x1 - d.x0) - .attr('height', height) - .attr('fill', displayColor) - .attr('rx', 2) - .attr('ry', 2) - .attr('opacity', this.enabled ? 0.8 : 0.5) - .style('cursor', this.enabled ? 'pointer' : 'default') - .style('pointer-events', 'all'); - - if (this.enabled) { - bars - .on('mouseenter', (event: MouseEvent, d: StackedBin) => { - const currentBar = event.currentTarget as SVGRectElement; - - // Reset previous bar if it exists - if (this.lastHoveredBar) { - d3.select(this.lastHoveredBar) - .attr('fill', displayColor) - .attr('opacity', 0.8); - } - - // Highlight current bar with darker version of original color - d3.select(currentBar) - .attr('fill', darkerColor) - .attr('opacity', 1); - - this.lastHoveredBar = currentBar; - - // Update hover label directly in DOM without triggering change detection - if (this.hoverLabelElement) { - this.hoverLabelElement.textContent = d.label || `Bin ${d.bin}`; - this.hoverLabelElement.classList.add('visible'); - } - }); - } - } - - private drawNumericHistogram(width: number, height: number): void { - if (!this.data || !this.svg) return; - // Rebin data if necessary - const counts = rebinHistogramData(this.data.counts, this.MAX_NUMERIC_BINS); - const bins = counts.map((value: number, index: number) => ({ bin: index, value })); - const displayColor = this.enabled ? this.color : '#ccc'; - const darkerColor = darkenColor(displayColor); - - const xScale = d3.scaleLinear() - .domain([0, bins.length]) - .range([0, width]); - - const maxVal = d3.max(bins, d => d.value) || 1; - - const yScale = d3.scaleLinear() - .domain([0, maxVal]) - .range([height, 0]); - - const barWidth = width / bins.length; - - const bars = this.svg.selectAll('rect') - .data(bins) - .enter() - .append('rect') - .attr('class', 'histogram-bar') - .attr('x', (d: any) => xScale(d.bin)) - .attr('y', (d: any) => yScale(d.value)) - .attr('width', Math.max(barWidth - 1, 1)) - .attr('height', (d: any) => height - yScale(d.value)) - .attr('fill', displayColor) - .attr('rx', 2) - .attr('ry', 2) - .attr('opacity', this.enabled ? 0.8 : 0.5) - .style('cursor', this.enabled ? 'pointer' : 'default') - .style('pointer-events', 'all'); - - if (this.enabled) { - bars - .on('mouseenter', (event: MouseEvent, d: any) => { - const currentBar = event.currentTarget as SVGRectElement; - - // Reset previous bar if it exists - if (this.lastHoveredBar) { - d3.select(this.lastHoveredBar) - .attr('fill', displayColor) - .attr('opacity', 0.8); - } - - // Highlight current bar with darker version of original color - d3.select(currentBar) - .attr('fill', darkerColor) - .attr('opacity', 1); - - this.lastHoveredBar = currentBar; - - const binStart = this.data.binEdges && this.data.binEdges[d.bin] !== undefined - ? this.data.binEdges[d.bin].toFixed(2) - : d.bin; - const binEnd = this.data.binEdges && this.data.binEdges[d.bin + 1] !== undefined - ? this.data.binEdges[d.bin + 1].toFixed(2) - : d.bin + 1; - - // Update hover label directly in DOM without triggering change detection - if (this.hoverLabelElement) { - this.hoverLabelElement.textContent = `${binStart} - ${binEnd}: ${d.value}`; - this.hoverLabelElement.classList.add('visible'); - } - }); - } - } -} diff --git a/src/app/preprocessing-wizard/steps/step1-upload/step1-upload.component.html b/src/app/preprocessing-wizard/steps/step1-upload/step1-upload.component.html index 5725b80..ca7d2ac 100644 --- a/src/app/preprocessing-wizard/steps/step1-upload/step1-upload.component.html +++ b/src/app/preprocessing-wizard/steps/step1-upload/step1-upload.component.html @@ -1,186 +1,169 @@
-
-

{{ stepInfo.title }}

-

{{ stepInfo.purpose }}

-
- - @if (!profile) { - -
- info -
- Supported formats: CSV files up to 50MB. - Your data will be analyzed automatically to detect column types and quality issues. -
+
+
+

{{ stepInfo.title }}

+

{{ stepInfo.purpose }}

- -
- - @if (isLoading) { -
-
-
Loading and analyzing your data...
+ @if (!profile) { + +
+ info +
+ Supported formats: CSV files up to 50MB. Your data will be analyzed automatically to detect + column types and quality issues.
- } @else { -
- cloud_upload -
- Drag and drop your CSV file here - or +
+ + +
+ @if (isLoading) { +
+
+
Loading and analyzing your data...
- -
- Maximum file size: 50MB + } @else { +
+ cloud_upload +
+ Drag and drop your CSV file here + or +
+ +
Maximum file size: 50MB
-
- } -
- - @if (error) { -
- error - {{ error }} + }
- } -
-

- File Requirements - -

-
    -
  • First row should contain column headers
  • -
  • ID column (optional): Unique identifier for each row
  • -
  • Pre-computed coordinates (optional): "<name>-x" and "<name>-y" pairs (e.g., "pca-x", "pca-y")
  • -
  • Geographic data (optional): "latitude" and "longitude" columns
  • -
  • File too large? Try filtering rows in Excel or reducing columns before upload
  • -
-
- - } @else { - -
-
-
- check_circle -

Data Loaded Successfully

-
-
- + @if (error) { +
+ error + {{ error }}
-
+ } -
-
- description -
-
File Name
-
{{ profile.fileName }}
+
+

+ File Requirements + +

+
    +
  • First row should contain column headers
  • +
  • ID column (optional): Unique identifier for each row
  • +
  • + Pre-computed coordinates (optional): "<name>-x" and "<name>-y" pairs (e.g., + "pca-x", "pca-y") +
  • +
  • Geographic data (optional): "latitude" and "longitude" columns
  • +
  • File too large? Try filtering rows in Excel or reducing columns before upload
  • +
+
+ } @else { + +
+
+
+ check_circle +

Data Loaded Successfully

-
- -
- storage -
-
File Size
-
{{ formatFileSize(profile.fileSize) }}
+
+
-
- table_rows -
-
Total Rows
-
{{ profile.totalRows }}
+
+
+ description +
+
File Name
+
{{ profile.fileName }}
+
-
-
- view_column -
-
Total Columns
-
{{ profile.totalColumns }}
+
+ storage +
+
File Size
+
{{ formatFileSize(profile.fileSize) }}
+
-
-
- assessment -
-
- Data Quality - -
-
- {{ profile.qualityScore.toFixed(1) }}% ({{ qualityLabel }}) +
+ table_rows +
+
Total Rows
+
{{ profile.totalRows }}
-
- @if (profile.duplicateCount > 0) { -
- content_copy +
+ view_column
-
Duplicates Found
-
{{ profile.duplicateCount }}
+
Total Columns
+
{{ profile.totalColumns }}
- } -
-
-

Data Preview (First 5 rows)

- - -
+
+ assessment +
+
+ Data Quality + +
+
{{ profile.qualityScore.toFixed(1) }}% ({{ qualityLabel }})
+
+
-
-

Column Overview

-
- @for (column of profile.columns; track column.name) { -
- {{ column.name }} - {{ column.dataType }} - @if (column.missingPercentage > 0) { - - {{ column.missingPercentage.toFixed(0) }}% missing - - } + @if (profile.duplicateCount > 0) { +
+ content_copy +
+
Duplicates Found
+
{{ profile.duplicateCount }}
+
}
-
-
-
-
- +
+

Data Preview (First 10 rows)

+
+ } +
+ + @if (profile) { +
+
+
+ +
}
diff --git a/src/app/preprocessing-wizard/steps/step1-upload/step1-upload.component.scss b/src/app/preprocessing-wizard/steps/step1-upload/step1-upload.component.scss index 0f3a36d..90455f6 100644 --- a/src/app/preprocessing-wizard/steps/step1-upload/step1-upload.component.scss +++ b/src/app/preprocessing-wizard/steps/step1-upload/step1-upload.component.scss @@ -4,10 +4,17 @@ .step1-upload { display: flex; flex-direction: column; - height: 100%; - max-width: 1000px; + flex: 1; + min-height: 0; +} + +.step-content { + flex: 1; + max-width: 1150px; margin: 0 auto; - padding: 16px; + padding: 16px 32px; + width: 100%; + box-sizing: border-box; } .step-header { @@ -29,7 +36,7 @@ &.drag-over { border-color: v.$active-color; - background: rgba(0, 188, 212, 0.05); + background: rgba(v.$active-color, 0.05); } &.loading { @@ -93,11 +100,6 @@ animation: spin 0.8s linear infinite; } -@keyframes spin { - 0% { transform: rotate(0deg); } - 100% { transform: rotate(360deg); } -} - .loading-text { font-size: 13px; color: v.$gray-600; @@ -219,15 +221,15 @@ } &.quality-fair .material-icons { - color: #FF9800; + color: v.$status-warning; } &.quality-poor .material-icons { - color: #F44336; + color: v.$status-error; } &.warning .material-icons { - color: #FF9800; + color: v.$status-warning; } } @@ -256,69 +258,6 @@ } } -.columns-summary { - display: flex; - flex-wrap: wrap; - gap: 8px; -} - -.column-chip { - display: flex; - align-items: center; - gap: 6px; - padding: 6px 12px; - background: white; - border: 1px solid v.$gray-300; - border-radius: 3px; - font-size: 12px; - - &[data-type="numeric"] { - border-left: 3px solid v.$active-color; - } - - &[data-type="categorical"] { - border-left: 3px solid v.$gray-600; - } - - &[data-type="text"] { - border-left: 3px solid #FF9800; - } - - &[data-type="date"] { - border-left: 3px solid v.$gray-500; - } - - &[data-type="id"] { - border-left: 3px solid v.$gray-400; - } -} - -.column-name { - font-weight: 600; - color: v.$gray-800; -} - -.column-type { - padding: 2px 6px; - background: v.$gray-100; - border-radius: 2px; - font-size: 11px; - color: v.$gray-600; - text-transform: uppercase; -} - -.column-badge { - padding: 2px 6px; - border-radius: 2px; - font-size: 11px; - font-weight: 600; - - &.warning { - background: rgba(255, 152, 0, 0.1); - color: #E65100; - } -} - .action-buttons { @include wizard.action-buttons-footer; diff --git a/src/app/preprocessing-wizard/steps/step1-upload/step1-upload.component.ts b/src/app/preprocessing-wizard/steps/step1-upload/step1-upload.component.ts index f4e057c..9fcc396 100644 --- a/src/app/preprocessing-wizard/steps/step1-upload/step1-upload.component.ts +++ b/src/app/preprocessing-wizard/steps/step1-upload/step1-upload.component.ts @@ -13,7 +13,7 @@ import { STEP_INFO } from '../../shared/constants/step-info'; standalone: true, imports: [CommonModule, FormsModule, DataPreviewTableComponent, HelpTooltipComponent], templateUrl: './step1-upload.component.html', - styleUrl: './step1-upload.component.scss' + styleUrl: './step1-upload.component.scss', }) export class Step1UploadComponent implements OnInit, OnDestroy { @Output() dataLoaded = new EventEmitter(); @@ -95,8 +95,8 @@ export class Step1UploadComponent implements OnInit, OnDestroy { this.profile = await this.preprocessingService.loadCSV(file); // Don't emit here - let user review the data first // User will click "Continue to Column Selection" button to emit and proceed - } catch (err: any) { - this.error = err.message || 'Failed to load data file'; + } catch (err: unknown) { + this.error = err instanceof Error ? err.message : 'Failed to load data file'; this.profile = null; } finally { this.isLoading = false; @@ -124,5 +124,4 @@ export class Step1UploadComponent implements OnInit, OnDestroy { if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + ' KB'; return (bytes / (1024 * 1024)).toFixed(1) + ' MB'; } - } diff --git a/src/app/preprocessing-wizard/steps/step2-column-selection/step2-column-selection.component.html b/src/app/preprocessing-wizard/steps/step2-column-selection/step2-column-selection.component.html index 3eab212..2b9684a 100644 --- a/src/app/preprocessing-wizard/steps/step2-column-selection/step2-column-selection.component.html +++ b/src/app/preprocessing-wizard/steps/step2-column-selection/step2-column-selection.component.html @@ -1,57 +1,59 @@
-
-

{{ stepInfo.title }}

-

{{ stepInfo.purpose }}

-
- - -
- info -
- Tip: Start by deselecting ID columns and text fields unless needed for tooltips. - You can search by column name or type (e.g., "numeric"). +
+
+

{{ stepInfo.title }}

+

{{ stepInfo.purpose }}

-
-
-