diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index 897be2bcc9..0000000000 --- a/.eslintignore +++ /dev/null @@ -1,16 +0,0 @@ -node_modules -dist -python -templates/neuroglancer/sliceview -src/third_party/jpgjs/jpg.js -templates -build -.tox -.nox -/lib -python -config -typings -src/mesh/draco/stub.js -tsconfig.tsbuildinfo -/examples diff --git a/.eslintrc.yml b/.eslintrc.yml deleted file mode 100644 index e033486195..0000000000 --- a/.eslintrc.yml +++ /dev/null @@ -1,68 +0,0 @@ -root: true -parser: "@typescript-eslint/parser" -plugins: - - "@typescript-eslint" - - "import" -settings: - "import/parsers": - "@typescript-eslint/parser": [".ts", ".tsx"] - "import/resolver": - "typescript": - "node": -extends: - - "eslint:recommended" - - "plugin:@typescript-eslint/eslint-recommended" - - "plugin:@typescript-eslint/recommended" - - "plugin:import/recommended" -rules: - "@typescript-eslint/no-explicit-any": "off" - "@typescript-eslint/explicit-module-boundary-types": "off" - "@typescript-eslint/no-non-null-assertion": "off" - "@typescript-eslint/no-inferrable-types": "off" - "@typescript-eslint/no-this-alias": "off" - "@typescript-eslint/no-empty-function": "off" - "@typescript-eslint/no-empty-interface": "off" - "prefer-const": - - "error" - - destructuring: "all" - "no-constant-condition": "off" - "@typescript-eslint/no-unused-vars": - - "error" - - argsIgnorePattern: "^_" - ignoreRestSiblings: true - "@typescript-eslint/ban-types": - - "error" - - types: - # unban Function - "Function": false - extendDefaults: true - "no-unsafe-finally": "off" - "require-yield": "off" - "no-inner-declarations": "off" - "import/no-named-as-default": "off" - "import/no-named-as-default-member": "off" - "import/no-cycle": "error" - "@typescript-eslint/consistent-type-imports": "error" - "import/no-unresolved": "error" - "import/no-extraneous-dependencies": "error" - "import/first": "error" - "import/order": - - "error" - - groups: - - "builtin" - - "external" - - "internal" - alphabetize: - order: "asc" - orderImportKind: "asc" -overrides: - - files: - - "src/**/*" - rules: - "no-restricted-imports": - - "error" - - patterns: - - group: - - "./" - - "../" - message: "Relative imports are not allowed." diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0c6d1ad621..e76f8eafa8 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -7,6 +7,13 @@ on: tags: - v** pull_request: + workflow_dispatch: + inputs: + debug_enabled: + type: boolean + description: "Run the build with tmate debugging enabled (https://github.com/marketplace/actions/debugging-with-tmate)" + required: false + default: false jobs: client: @@ -24,11 +31,16 @@ jobs: fetch-depth: 0 - uses: actions/setup-node@v4 with: - node-version: 20.x + node-version: 22.x cache: "npm" cache-dependency-path: | package-lock.json examples/**/package-lock.json + # go needed for fake_gcs_server used by the javascript tests + - name: Setup go + uses: actions/setup-go@v5 + with: + go-version: "stable" - run: npm install - run: npm run format:fix - name: Check for dirty working directory @@ -47,7 +59,6 @@ jobs: - run: npm run build-package - run: npm publish --dry-run working-directory: dist/package - - uses: ./.github/actions/setup-firefox - name: Run JavaScript tests (including WebGL) run: npm test if: ${{ runner.os != 'macOS' }} @@ -92,17 +103,17 @@ jobs: fetch-depth: 0 - uses: actions/setup-node@v4 with: - node-version: 20.x + node-version: 22.x - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - # Uncomment the action below for an interactive shell - # - name: Setup tmate session - # uses: mxschmitt/action-tmate@v3 + - uses: ./.github/actions/setup-firefox + - name: Setup tmate session + uses: mxschmitt/action-tmate@v3 + if: ${{ github.event_name == 'workflow_dispatch' && inputs.debug_enabled }} - name: Install Python packaging/test tools run: pip install tox nox wheel numpy -r python/requirements-test.txt - - uses: ./.github/actions/setup-firefox - run: nox -s lint format mypy - name: Check for dirty working directory run: git diff --exit-code @@ -139,7 +150,7 @@ jobs: fetch-depth: 0 - uses: actions/setup-node@v4 with: - node-version: 20.x + node-version: 22.x cache: "npm" - name: Set up Python uses: actions/setup-python@v5 @@ -214,7 +225,7 @@ jobs: - name: Use Node.js uses: actions/setup-node@v4 with: - node-version: 20.x + node-version: 22.x registry-url: "https://registry.npmjs.org" - uses: actions/download-artifact@v4 with: diff --git a/.github/workflows/build_preview.yml b/.github/workflows/build_preview.yml index 9dcac7d1e1..7a6c997612 100644 --- a/.github/workflows/build_preview.yml +++ b/.github/workflows/build_preview.yml @@ -8,7 +8,7 @@ jobs: strategy: matrix: node-version: - - "20.x" + - "22.x" runs-on: ubuntu-latest steps: diff --git a/.ncurc.yml b/.ncurc.yml new file mode 100644 index 0000000000..4250db1cf6 --- /dev/null +++ b/.ncurc.yml @@ -0,0 +1,5 @@ +reject: + # API break + - "gl-matrix" + - "@types/gl-matrix" + - "codemirror" diff --git a/.oxlintrc.json b/.oxlintrc.json new file mode 100644 index 0000000000..11df356ad1 --- /dev/null +++ b/.oxlintrc.json @@ -0,0 +1,60 @@ +{ + "$schema": "./node_modules/oxlint/configuration_schema.json", + "plugins": ["import", "typescript", "oxc", "unicorn", "promise", "vitest"], + "env": { + "browser": true + }, + "settings": {}, + "rules": { + // Seems to be buggy + "no-loss-of-precision": "off", + "import/no-cycle": "error", + "import/first": "error", + "no-unsafe-finally": "off", + "require-yield": "off", + "@typescript-eslint/no-explicit-any": "off", + "@typescript-eslint/no-non-null-assertion": "off", + "@typescript-eslint/no-inferrable-types": "off", + "@typescript-eslint/no-this-alias": "off", + "@typescript-eslint/no-empty-function": "off", + "@typescript-eslint/no-empty-interface": "off", + "erasing-op": "off", + "no-unused-vars": [ + "error", + { + "argsIgnorePattern": "^_", + "varsIgnorePattern": "^_", + "ignoreRestSiblings": true + } + ], + "no-new-array": "off", + "no-document-cookie": "off", + "@typescript-eslint/consistent-type-imports": "error" + }, + "overrides": [ + { + "files": ["*.test.ts", "*.spec.ts"], + "rules": { + "@typescript-eslint/no-explicit-any": "off" + } + } + ], + "ignorePatterns": [ + "**/node_modules", + "**/dist", + "**/python", + "templates/neuroglancer/sliceview", + "src/third_party/jpgjs/jpg.js", + "**/templates", + "**/build", + "**/.tox", + "**/.nox", + "lib", + "**/python", + "**/config", + "**/typings", + "src/mesh/draco/stub.js", + "**/tsconfig.tsbuildinfo", + "examples" + ] +} diff --git a/.prettierignore b/.prettierignore index 42541345da..1a4619071f 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,9 +1,12 @@ /templates/ /python/ /third_party/jpgjs/jpg.js -/testdata/*.json +/testdata/**/*.json +zarr.json .parcel-cache dist /lib /docs/_build/ /.ruff_cache +package.json +package-lock.json diff --git a/MANIFEST.in b/MANIFEST.in index 6d3dbc6240..54472f0285 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -14,7 +14,6 @@ prune examples exclude .clang-format exclude .editorconfig exclude .eslintignore -exclude .eslintrc exclude .style.yapf exclude cors_webserver.py exclude gulpfile.js @@ -36,8 +35,9 @@ exclude MANIFEST.in exclude *.ts exclude .prettierrc.yml exclude .prettierignore -exclude .eslintrc.yml +exclude eslint.config.js +exclude .ncurc.yml exclude index.html -exclude webpack.config.js +exclude rspack.config.js exclude firebase.json exclude .firebaserc diff --git a/build_tools/after-version-change.ts b/build_tools/after-version-change.ts index 67d88c04c5..7bb68f47f1 100644 --- a/build_tools/after-version-change.ts +++ b/build_tools/after-version-change.ts @@ -28,8 +28,17 @@ await Promise.all( await execFileAsync("npm", ["install", "--no-audit", "--no-fund"], { cwd: exampleDir, }); - await execFileAsync("git", ["add", "package-lock.json"], { - cwd: exampleDir, - }); }), ); + +await execFileAsync( + "git", + [ + "add", + ...(await glob("examples/*/*/package-lock.json", { + absolute: false, + cwd: rootDir, + })), + ], + { cwd: rootDir }, +); diff --git a/build_tools/build-package.ts b/build_tools/build-package.ts index 32c80a00b5..7a2133f807 100644 --- a/build_tools/build-package.ts +++ b/build_tools/build-package.ts @@ -32,8 +32,11 @@ function buildDeclarationFiles( program.emit(); } -async function buildPackage(options: { inplace?: boolean }) { - const { inplace = false } = options; +async function buildPackage(options: { + inplace?: boolean; + skipDeclarations?: boolean; +}) { + const { inplace = false, skipDeclarations = false } = options; const srcDir = path.resolve(rootDir, "src"); const outDir = inplace ? rootDir : path.resolve(rootDir, "dist", "package"); @@ -68,6 +71,7 @@ async function buildPackage(options: { inplace?: boolean }) { outbase: srcDir, bundle: false, outdir: libDir, + target: "es2022", }); let compilerOptionsFromConfigFile: ts.CompilerOptions = {}; @@ -80,10 +84,12 @@ async function buildPackage(options: { inplace?: boolean }) { "./", ).options; } - buildDeclarationFiles(entryPoints, { - ...compilerOptionsFromConfigFile, - outDir: libDir, - }); + if (!skipDeclarations) { + buildDeclarationFiles(entryPoints, { + ...compilerOptionsFromConfigFile, + outDir: libDir, + }); + } const otherSources = await glob(["**/*.{css,js,html,wasm}"], { cwd: srcDir, @@ -117,6 +123,7 @@ async function buildPackage(options: { inplace?: boolean }) { const { postpack } = packageJson["scripts"]; delete packageJson["scripts"]; packageJson["scripts"] = { postpack }; + packageJson["files"] = ["lib/**/*"]; } else { delete packageJson["private"]; packageJson["scripts"] = {}; @@ -156,6 +163,11 @@ async function parseArgsAndRunMain() { default: false, description: "Convert package to built format inplace.", }, + ["skip-declarations"]: { + type: "boolean", + default: false, + description: "Skip generating .d.ts files.", + }, ["if-not-toplevel"]: { type: "boolean", default: false, @@ -193,7 +205,10 @@ async function parseArgsAndRunMain() { return; } } - buildPackage({ inplace: argv.inplace }); + buildPackage({ + inplace: argv.inplace, + skipDeclarations: argv.skipDeclarations, + }); } if (process.argv[1] === import.meta.filename) { diff --git a/build_tools/cli.ts b/build_tools/cli.ts index 854871136c..0ea4a51df1 100644 --- a/build_tools/cli.ts +++ b/build_tools/cli.ts @@ -16,18 +16,17 @@ // Command-line interface for building Neuroglancer. -/// - import process from "node:process"; import { pathToFileURL } from "node:url"; import path from "path"; -import ForkTsCheckerWebpackPlugin from "fork-ts-checker-webpack-plugin"; -import type { Configuration } from "webpack"; -import webpackCli from "webpack-cli/lib/bootstrap.js"; // eslint-disable-line import/default +import { RspackCLI } from "@rspack/cli"; +import type { Configuration } from "@rspack/core"; +import ESLintPlugin from "eslint-rspack-plugin"; +import { TsCheckerRspackPlugin } from "ts-checker-rspack-plugin"; import * as webpackMerge from "webpack-merge"; import yargs from "yargs"; -import { normalizeConfigurationWithDefine } from "./webpack/configuration_with_define.js"; -import { setConfig } from "./webpack/webpack_config_from_cli.cjs"; +import { normalizeConfigurationWithDefine } from "./rspack/configuration_with_define.js"; +import { setConfig } from "./rspack/rspack_config_from_cli.js"; export interface WebpackConfigurationWithDefine extends Configuration { define?: Record | undefined; @@ -81,7 +80,7 @@ async function getWebpackConfig( ...extraConfigs: WebpackConfigurationWithDefine[] ): Promise<(...args: any[]) => Configuration> { const configPaths = [ - pathToFileURL(path.resolve(import.meta.dirname, "../webpack.config.js")) + pathToFileURL(path.resolve(import.meta.dirname, "../rspack.config.js")) .href, ...argv.config.map((configPath) => pathToFileURL(configPath).href), ]; @@ -109,15 +108,15 @@ async function getWebpackConfig( outDir = path.resolve(outDir); } const plugins = []; - if (argv.typecheck || argv.lint) { + if (argv.typecheck) { + plugins.push(new TsCheckerRspackPlugin()); + } + if (argv.lint) { plugins.push( - new ForkTsCheckerWebpackPlugin({ - typescript: argv.typecheck, - eslint: argv.lint - ? { - files: ".", - } - : undefined, + new ESLintPlugin({ + configType: "flat", + files: ".", + threads: true, }), ); } @@ -141,12 +140,11 @@ async function getWebpackConfig( } async function runWebpack(...args: string[]) { - // @ts-expect-error: no typings available - await webpackCli([ + await new RspackCLI().run([ ...process.argv.slice(0, 2), ...args, "--config", - path.resolve(import.meta.dirname, "webpack", "webpack_config_from_cli.cjs"), + path.resolve(import.meta.dirname, "rspack", "rspack_config_from_cli.js"), ]); } @@ -211,7 +209,7 @@ function parseArgs() { group: "Development server options", type: "number", nargs: 1, - default: 8080, + default: 0, description: "Port number for the development server", }, host: { diff --git a/config/generate-code.ts b/build_tools/generate-code.ts similarity index 84% rename from config/generate-code.ts rename to build_tools/generate-code.ts index b3b2e2c200..37106b61c7 100644 --- a/config/generate-code.ts +++ b/build_tools/generate-code.ts @@ -14,14 +14,11 @@ * limitations under the License. */ -"use strict"; +import fs from "node:fs"; +import path from "node:path"; +import nunjucks from "nunjucks"; -const nunjucks = require("nunjucks"); -const fs = require("fs"); -const path = require("path"); - -const rootDir = path.resolve(__dirname, ".."); -const srcDir = path.resolve(rootDir, "src"); +const rootDir = path.resolve(import.meta.dirname, ".."); const templatesDir = path.resolve(rootDir, "templates"); const env = nunjucks.configure(rootDir, { @@ -34,7 +31,11 @@ const env = nunjucks.configure(rootDir, { }, }); -function writeGenerated(sourcePath, outputPath, contents) { +function writeGenerated( + sourcePath: string, + outputPath: string, + contents: string, +) { fs.writeFileSync( path.resolve(rootDir, "src", outputPath), `// DO NOT EDIT. Generated from templates/${sourcePath}. @@ -42,7 +43,11 @@ function writeGenerated(sourcePath, outputPath, contents) { ); } -function renderTemplate(sourcePath, outputPath, context) { +function renderTemplate( + sourcePath: string, + outputPath: string, + context: Record, +) { writeGenerated( sourcePath, outputPath, @@ -58,7 +63,7 @@ function writeSegmentationCompression() { {}, ); for (const dataType of ["uint64", "uint32"]) { - const context = { + const context: Record = { dataType, strideMultiplier: dataType === "uint64" ? 2 : 1, }; @@ -72,7 +77,11 @@ function writeSegmentationCompression() { } } -function makeSubstitutions(inputPath, outputPath, replacements) { +function makeSubstitutions( + inputPath: string, + outputPath: string, + replacements: [string | RegExp, string][], +) { let inputContents = fs.readFileSync(path.resolve(templatesDir, inputPath), { encoding: "utf-8", }); @@ -107,7 +116,7 @@ function writeDataStructures() { const nextPrevReplacements = [ [/NEXT_PROPERTY/g, `next${i}`], [/PREV_PROPERTY/g, `prev${i}`], - ]; + ] as [string | RegExp, string][]; makeSubstitutions( path.join(baseDir, "linked_list.template.ts"), path.join(baseDir, `linked_list.${i}.ts`), diff --git a/build_tools/webpack/configuration_with_define.js b/build_tools/rspack/configuration_with_define.js similarity index 51% rename from build_tools/webpack/configuration_with_define.js rename to build_tools/rspack/configuration_with_define.js index 602ac51425..81dfff9aaf 100644 --- a/build_tools/webpack/configuration_with_define.js +++ b/build_tools/rspack/configuration_with_define.js @@ -1,13 +1,13 @@ -// Converts a webpack configuration that optionally contains an extra `define` -// property into a regular webpack configuration with an added `DefinePlugin`. +// Converts an rspack configuration that optionally contains an extra `define` +// property into a regular rspack configuration with an added `DefinePlugin`. -import webpack from "webpack"; +import { DefinePlugin } from "@rspack/core"; export function normalizeConfigurationWithDefine(config) { let { define, plugins, ...rest } = config; if (define !== undefined && Object.keys(define).length > 0) { plugins ??= []; - plugins.push(new webpack.DefinePlugin(define)); + plugins.push(new DefinePlugin(define)); } return { plugins, ...rest }; } diff --git a/build_tools/rspack/rspack_config_from_cli.js b/build_tools/rspack/rspack_config_from_cli.js new file mode 100644 index 0000000000..4ef6bd67d1 --- /dev/null +++ b/build_tools/rspack/rspack_config_from_cli.js @@ -0,0 +1,12 @@ +// This module is specified as the rspack config module when `cli.ts` invokes +// `@rspack/cli` programmatically. +// +// It simply returns the configuration previously set by `cli.ts`. + +let config = undefined; + +export function setConfig(newConfig) { + config = newConfig; +} + +export default (...args) => config(...args); diff --git a/build_tools/update-conditions.ts b/build_tools/update-conditions.ts index 6581bf11cc..25e0891f9d 100644 --- a/build_tools/update-conditions.ts +++ b/build_tools/update-conditions.ts @@ -17,70 +17,100 @@ const imports: Record = {}; imports["#src/third_party/jpgjs/jpg.js"] = "./src/third_party/jpgjs/jpg.js"; imports["#src/*.js"] = "./src/*.ts"; imports["#src/*"] = "./src/*"; +imports["#tests/fixtures/msw"] = { + node: "./tests/fixtures/msw_node.ts", + default: "./tests/fixtures/msw_browser.ts", +}; +imports["#tests/fixtures/gl"] = { + node: "./tests/fixtures/gl_node.ts", + default: "./tests/fixtures/gl_browser.ts", +}; +imports["#tests/*.js"] = "./tests/*.ts"; imports["#testdata/*"] = "./testdata/*"; -const datasourceDir = path.resolve(rootDir, "src", "datasource"); -const layerDir = path.resolve(rootDir, "src", "layer"); - -const datasources = ( - await fs.promises.readdir(datasourceDir, { withFileTypes: true }) -) - .filter((e) => e.isDirectory()) - .map((e) => e.name); - -const layers = (await fs.promises.readdir(layerDir, { withFileTypes: true })) - .filter((e) => e.isDirectory()) - .map((e) => e.name); - -const datasourceKeys = { - backend: "backend", - async_computation: "async_computation", - register_default: "frontend", - register_credentials_provider: "frontend", -} as const; +async function listSubdirs(dir: string): Promise { + return (await fs.promises.readdir(dir, { withFileTypes: true })) + .filter((e) => e.isDirectory()) + .map((e) => e.name); +} -const datasourceModules = Object.fromEntries( - Object.values(datasourceKeys).map((key) => [key, new Array()]), -); +async function writeModule(modulePath: string, imports: string[]) { + await fs.promises.writeFile( + modulePath, + "// DO NOT EDIT: Generated by config/update_conditions.ts\n" + + imports.map((name) => `import ${JSON.stringify(name)};\n`).join(""), + { encoding: "utf-8" }, + ); +} -for (const datasource of datasources) { - for (const [filePrefix, moduleKind] of Object.entries(datasourceKeys)) { - const sourcePrefix = `./src/datasource/${datasource}/${filePrefix}`; - if ( - await fs.promises - .stat(path.resolve(rootDir, `${sourcePrefix}.ts`)) - .catch(() => undefined) - ) { - const source = sourcePrefix + JS_EXT; - const conditions: Record = {}; - if (datasource === "python") { - conditions["neuroglancer/python"] = source; - conditions.default = NOOP; - } else { - if (filePrefix === "register_credentials_provider") { - conditions["neuroglancer/python"] = NOOP; +async function handleDrivers( + kind: string, + moduleMap: Record, +) { + const driverDir = path.resolve(rootDir, "src", kind); + const drivers = await listSubdirs(driverDir); + const modules: Record = {}; + for (const driver of drivers) { + for (const [filePrefix, moduleKinds] of Object.entries(moduleMap)) { + const sourcePrefix = `./src/${kind}/${driver}/${filePrefix}`; + if ( + await fs.promises + .stat(path.resolve(rootDir, `${sourcePrefix}.ts`)) + .catch(() => undefined) + ) { + const source = sourcePrefix + JS_EXT; + const conditions: Record = {}; + if (driver === "python") { + conditions["neuroglancer/python"] = source; + conditions.default = NOOP; + } else { + if (filePrefix === "register_credentials_provider") { + conditions["neuroglancer/python"] = NOOP; + } + conditions[`neuroglancer/${kind}/${driver}:enabled`] = source; + conditions[`neuroglancer/${kind}:none_by_default`] = NOOP; + conditions[`neuroglancer/${kind}/${driver}:disabled`] = NOOP; + conditions.default = source; + } + let moduleId = `#${kind}/${driver}`; + if (filePrefix !== "index") { + moduleId += `/${filePrefix}`; + } + imports[moduleId] = conditions; + for (const moduleKind of moduleKinds) { + if (modules[moduleKind] === undefined) { + modules[moduleKind] = []; + } + modules[moduleKind].push(moduleId); } - conditions[`neuroglancer/datasource/${datasource}:enabled`] = source; - conditions["neuroglancer/datasource:none_by_default"] = NOOP; - conditions[`neuroglancer/datasource/${datasource}:disabled`] = source; - conditions.default = source; } - const moduleId = `#datasource/${datasource}/${filePrefix}`; - imports[moduleId] = conditions; - datasourceModules[moduleKind].push(moduleId); } } + for (const [moduleKind, moduleIds] of Object.entries(modules)) { + await writeModule( + path.resolve(driverDir, `enabled_${moduleKind}_modules.ts`), + moduleIds, + ); + } } -for (const layer of layers) { - const source = `./src/layer/${layer}/index` + JS_EXT; - imports[`#layer/${layer}`] = { - [`neuroglancer/layer/${layer}:enabled`]: source, - "neuroglancer/layer:none_by_default": NOOP, - [`neuroglancer/layer/${layer}:enabled`]: source, - default: source, - }; -} +await handleDrivers("datasource", { + backend: ["backend"], + async_computation: ["async_computation"], + register_default: ["frontend"], + register_credentials_provider: ["frontend"], +}); + +await handleDrivers("kvstore", { + register: ["frontend", "backend"], + register_frontend: ["frontend"], + register_backend: ["backend"], + register_credentials_provider: ["frontend"], +}); + +await handleDrivers("layer", { + index: ["frontend"], +}); // main entrypoint. imports["#main"] = { @@ -94,38 +124,12 @@ imports["#python_integration_build"] = { default: NOOP, }; -async function writeModule(modulePath: string, imports: string[]) { - await fs.promises.writeFile( - modulePath, - "// DO NOT EDIT: Generated by config/update_conditions.ts\n" + - imports.map((name) => `import ${JSON.stringify(name)};\n`).join(""), - { encoding: "utf-8" }, - ); -} - -for (const [moduleKind, moduleIds] of Object.entries(datasourceModules)) { - await writeModule( - path.resolve( - rootDir, - "src", - "datasource", - `enabled_${moduleKind}_modules.ts`, - ), - moduleIds, - ); -} - -await writeModule( - path.resolve(rootDir, "src", "layer", "enabled_frontend_modules.ts"), - layers.map((name) => `#layer/${name}`), -); - packageJson.imports = imports; packageJson.exports = { ".": "./src/main_module.ts", - "./*.js": "./src/*.ts", - "./*": "./src/*", + "./unstable/*.js": "./src/*.ts", + "./unstable/*": "./src/*", }; const tempPackageJsonPath = packageJsonPath + ".tmp"; diff --git a/build_tools/vitest/build_fake_gcs_server.ts b/build_tools/vitest/build_fake_gcs_server.ts new file mode 100644 index 0000000000..2009ba7365 --- /dev/null +++ b/build_tools/vitest/build_fake_gcs_server.ts @@ -0,0 +1,57 @@ +/** + * @license + * Copyright 2024 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { spawnSync } from "node:child_process"; +import fs from "node:fs/promises"; +import path from "node:path"; + +export async function getFakeGcsServerBin(): Promise { + const binDir = path.join( + import.meta.dirname, + "..", + "..", + "node_modules", + ".cache", + "gobin", + ); + const serverBinPath = + path.join(binDir, "fake-gcs-server") + + (process.platform === "win32" ? ".exe" : ""); + if ( + !(await fs.access(serverBinPath).then( + () => true, + () => false, + )) + ) { + console.log("Building fake-gcs-server"); + // Note: For unknown reasons, using `await promisify(spawn)` in place of + // `spawnSync` causes the vitest process to exit as soon as the child + // process completes. + spawnSync( + "go", + [ + "install", + "github.com/fsouza/fake-gcs-server@3b3d059cbaade55b480196a51dedb7aa82ec2b0a", + ], + { + env: { ...process.env, GOBIN: binDir }, + stdio: ["ignore", "inherit", "inherit"], + }, + ); + console.log("Done building fake-gcs-server"); + } + return serverBinPath; +} diff --git a/build_tools/vitest/fake_ngauth_server.ts b/build_tools/vitest/fake_ngauth_server.ts new file mode 100644 index 0000000000..ed0068b333 --- /dev/null +++ b/build_tools/vitest/fake_ngauth_server.ts @@ -0,0 +1,98 @@ +/** + * @license + * Copyright 2024 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Fake ngauth server used for tests. + +import type { AddressInfo } from "node:net"; +import cookie from "cookie"; +import express from "express"; + +const COOKIE_NAME = "ngauth_login"; +const COOKIE_VALUE = "fake_login"; +const TOKEN_VALUE = "fake_token"; + +export interface FakeNgauthServer extends AsyncDisposable { + url: string; +} + +export function startFakeNgauthServer(): Promise { + const app = express(); + app.use(express.json({ inflate: false, type: "*/*" })); + app.get("/login", (req, res) => { + const origin = (req.query.origin ?? "").toString(); + res.contentType("text/html"); + // Note: The real ngauth marks this cookie as http-only, but that prevents + // JavaScript from clearing it. + res.cookie(COOKIE_NAME, COOKIE_VALUE, { sameSite: "lax" }); + const jsonToken = JSON.stringify({ token: TOKEN_VALUE }); + const jsonOrigin = JSON.stringify(origin); + res.send(` + + + + + +`); + }); + app.post("/token", (req, res) => { + const cookies = cookie.parse(req.headers.cookie ?? ""); + const origin = req.headers.origin ?? ""; + res.set("x-frame-options", "deny"); + res.set("access-control-allow-origin", origin); + res.set("access-control-allow-credentials", "true"); + res.set("vary", "origin"); + + if (cookies[COOKIE_NAME] === COOKIE_VALUE) { + res.contentType("text/plain"); + res.send(TOKEN_VALUE); + } else { + res.status(401); + res.send(); + } + }); + app.post("/gcs_token", (req, res) => { + const origin = req.headers.origin ?? ""; + res.set("access-control-allow-origin", origin); + res.set("vary", "origin"); + const { body } = req; + if ( + typeof body !== "object" || + Array.isArray(body) || + body.token !== TOKEN_VALUE + ) { + res.status(400); + res.send(); + } else { + res.json({ token: "fake_gcs_token:" + body.bucket }); + } + }); + const server = app.listen(0, "localhost"); + // Don't block node from exiting while this server is running. + server.unref(); + return new Promise((resolve, reject) => { + server.on("error", reject); + server.on("listening", () => { + const port = (server.address() as AddressInfo).port; + resolve({ + url: `http://localhost:${port}`, + [Symbol.asyncDispose]: () => + new Promise((resolve) => server.close(() => resolve())), + }); + }); + }); +} diff --git a/build_tools/vitest/polyfill-browser-globals-in-node.ts b/build_tools/vitest/polyfill-browser-globals-in-node.ts new file mode 100644 index 0000000000..c4d2ce3452 --- /dev/null +++ b/build_tools/vitest/polyfill-browser-globals-in-node.ts @@ -0,0 +1,16 @@ +import { webcrypto } from "node:crypto"; +import type { JSDOM } from "jsdom"; + +declare let jsdom: JSDOM; + +Object.defineProperty(globalThis, "crypto", { + value: webcrypto, +}); + +for (const name of [ + /*"DOMParser", "XPathResult", "navigator"*/ +] as const) { + Object.defineProperty(globalThis, name, { + value: jsdom.window[name], + }); +} diff --git a/build_tools/vitest/setup-crypto.ts b/build_tools/vitest/setup-crypto.ts deleted file mode 100644 index 65e56e55a2..0000000000 --- a/build_tools/vitest/setup-crypto.ts +++ /dev/null @@ -1,7 +0,0 @@ -// Polyfill for missing `crypto` in jsdom. - -import { webcrypto } from "node:crypto"; - -Object.defineProperty(globalThis, "crypto", { - value: webcrypto, -}); diff --git a/build_tools/vitest/test_data_server.ts b/build_tools/vitest/test_data_server.ts new file mode 100644 index 0000000000..cde0e7ce18 --- /dev/null +++ b/build_tools/vitest/test_data_server.ts @@ -0,0 +1,51 @@ +/** + * @license + * Copyright 2024 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type * as http from "node:http"; +import type { AddressInfo } from "node:net"; +import { createServer } from "http-server"; + +export interface TestDataServer extends AsyncDisposable { + url: string; +} + +export async function startTestDataServer( + rootDirectory: string, +): Promise { + const server: http.Server = ( + createServer({ + root: rootDirectory, + cache: -1, + cors: true, + }) as any + ).server; + // Don't block node from exiting. + server.unref(); + const serverUrl = await new Promise((resolve, reject) => { + server.on("error", reject); + server.listen(0, "localhost", () => { + const port = (server.address() as AddressInfo).port; + resolve(`http://localhost:${port}/`); + }); + }); + console.log(`Serving ${rootDirectory} at ${serverUrl}`); + return { + url: serverUrl, + [Symbol.asyncDispose]: async () => { + await new Promise((resolve) => server.close(resolve)); + }, + }; +} diff --git a/build_tools/webpack/webpack_config_from_cli.cjs b/build_tools/webpack/webpack_config_from_cli.cjs deleted file mode 100644 index a566f4591e..0000000000 --- a/build_tools/webpack/webpack_config_from_cli.cjs +++ /dev/null @@ -1,14 +0,0 @@ -// This module is specified as the webpack config module when `cli.ts` invokes -// `webpack-cli` programmatically. -// -// It simply returns the configuration previously set by `cli.ts`. -// -// This module is in cjs format rather than esm format to avoid a separate copy -// being loaded, for some reason, by tsx. - -let config = undefined; - -module.exports = (...args) => config(...args); -module.exports.setConfig = (newConfig) => { - config = newConfig; -}; diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 0000000000..cbc657c4c5 --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,124 @@ +// @ts-check + +import eslint from "@eslint/js"; +// @ts-expect-error missing .d.ts file +import importPlugin from "eslint-plugin-import"; +import tseslint from "typescript-eslint"; + +export default tseslint.config( + { + ignores: [ + "**/node_modules", + "**/dist", + "**/python", + "templates/neuroglancer/sliceview", + "src/third_party/jpgjs/jpg.js", + "**/templates", + "**/build", + "**/.tox", + "**/.nox", + "lib", + "**/python", + "**/config", + "**/typings", + "src/mesh/draco/stub.js", + "**/tsconfig.tsbuildinfo", + "examples", + ], + }, + eslint.configs.recommended, + tseslint.configs.recommended, + importPlugin.flatConfigs.recommended, + importPlugin.flatConfigs.typescript, + { + settings: { + "import/resolver": { + typescript: {}, + node: {}, + }, + }, + rules: { + "@typescript-eslint/no-explicit-any": "off", + "@typescript-eslint/explicit-module-boundary-types": "off", + "@typescript-eslint/no-non-null-assertion": "off", + "@typescript-eslint/no-inferrable-types": "off", + "@typescript-eslint/no-this-alias": "off", + "@typescript-eslint/no-empty-function": "off", + "@typescript-eslint/no-empty-interface": "off", + + "prefer-const": [ + "error", + { + destructuring: "all", + }, + ], + + "no-constant-condition": "off", + + "no-unused-disable": "off", + + "@typescript-eslint/no-unused-vars": [ + "error", + { + argsIgnorePattern: "^_", + varsIgnorePattern: "^_", + ignoreRestSiblings: true, + }, + ], + + "@typescript-eslint/no-unsafe-function-type": "off", + + "no-unsafe-finally": "off", + "require-yield": "off", + "no-inner-declarations": "off", + + // Supported by oxlint + "import/namespace": "off", + "import/default": "off", + + "import/no-named-as-default": "off", + "import/no-named-as-default-member": "off", + "@typescript-eslint/consistent-type-imports": "error", + "import/no-unresolved": "error", + "import/no-extraneous-dependencies": "error", + + "import/order": [ + "error", + { + groups: ["builtin", "external", "internal"], + + alphabetize: { + order: "asc", + orderImportKind: "asc", + }, + }, + ], + + // Neuroglancer uses `varname;` to suppress unused parameter warnings. + "@typescript-eslint/no-unused-expressions": "off", + }, + }, + { + files: ["src/**/*"], + + rules: { + "no-restricted-imports": [ + "error", + { + patterns: [ + { + group: ["./", "../"], + message: "Relative imports are not allowed.", + }, + ], + }, + ], + }, + }, + { + files: ["build_tools/**/*.cjs"], + languageOptions: { + sourceType: "commonjs", + }, + }, +); diff --git a/examples/README.md b/examples/README.md index 41a0df3e65..78ebd5b272 100644 --- a/examples/README.md +++ b/examples/README.md @@ -31,6 +31,8 @@ Neuroglancer can be used as a dependency in two ways: The following bundlers are known to be compatible: - [webpack](./webpack/) (recommended) +- [rspack](./rspack/) +- [rsbuild](./rsbuild/) - [parcel](./parcel/) - [vite](./vite/) diff --git a/examples/parcel/parcel-project-built/package-lock.json b/examples/parcel/parcel-project-built/package-lock.json index 84b1c7eb7e..5923e257ab 100644 --- a/examples/parcel/parcel-project-built/package-lock.json +++ b/examples/parcel/parcel-project-built/package-lock.json @@ -23,16 +23,16 @@ "license": "Apache-2.0", "dependencies": { "codemirror": "^5.61.1", + "core-js": "^3.40.0", + "crc-32": "^1.2.2", "gl-matrix": "3.1.0", - "glsl-editor": "^1.0.0", "ikonate": "github:mikolajdobrucki/ikonate#a86b4107c6ec717e7877f880a930d1ccf0b59d89", "lodash-es": "^4.17.21", "nifti-reader-js": "^0.6.8", - "numcodecs": "^0.3.1", - "pako": "^2.1.0" + "numcodecs": "^0.3.2" }, "engines": { - "node": ">=20.10 <21 || >=21.2" + "node": ">=22" } }, "node_modules/@babel/code-frame": { diff --git a/examples/parcel/parcel-project-source/package-lock.json b/examples/parcel/parcel-project-source/package-lock.json index d48589d7eb..fa9f90d194 100644 --- a/examples/parcel/parcel-project-source/package-lock.json +++ b/examples/parcel/parcel-project-source/package-lock.json @@ -18,58 +18,67 @@ } }, "../../..": { - "name": "neuroglancer", "version": "2.40.1", "license": "Apache-2.0", "dependencies": { "codemirror": "^5.61.1", + "core-js": "^3.40.0", + "crc-32": "^1.2.2", "gl-matrix": "3.1.0", - "glsl-editor": "^1.0.0", "ikonate": "github:mikolajdobrucki/ikonate#a86b4107c6ec717e7877f880a930d1ccf0b59d89", "lodash-es": "^4.17.21", "nifti-reader-js": "^0.6.8", - "numcodecs": "^0.3.1", - "pako": "^2.1.0" + "numcodecs": "^0.3.2" }, "devDependencies": { + "@eslint/js": "^9.18.0", + "@iodigital/vite-plugin-msw": "^2.0.0", + "@playwright/browser-chromium": "^1.49.1", + "@rspack/cli": "^1.1.8", + "@rspack/core": "^1.1.8", "@types/codemirror": "5.60.15", "@types/gl-matrix": "^2.4.5", + "@types/http-server": "^0.12.4", + "@types/jsdom": "^21.1.7", "@types/lodash-es": "^4.17.12", - "@types/node": "^20.14.12", - "@types/pako": "^2.0.3", - "@types/yargs": "^17.0.32", - "@typescript-eslint/eslint-plugin": "^7.17.0", - "@typescript-eslint/parser": "^7.17.0", - "@vitest/browser": "^2.0.4", - "@vitest/ui": "^2.0.4", + "@types/node": "^22.10.7", + "@types/nunjucks": "^3.2.6", + "@types/s3rver": "^3.7.4", + "@types/yargs": "^17.0.33", + "@vitest/browser": "^3.0.2", + "@vitest/ui": "^3.0.2", + "@vitest/web-worker": "^3.0.2", + "cookie": "^1.0.2", "css-loader": "^7.1.2", - "esbuild": "^0.23.0", - "esbuild-loader": "^4.2.2", - "eslint": "^8.56.0", + "esbuild": "^0.24.2", + "eslint": "^9.18.0", "eslint-formatter-codeframe": "^7.32.1", - "eslint-import-resolver-typescript": "^3.6.1", - "eslint-interactive": "^10.8.0", - "eslint-plugin-import": "^2.29.1", - "eslint-webpack-plugin": "^4.0.1", - "fork-ts-checker-webpack-plugin": "^6.5.3", - "glob": "^11.0.0", - "html-webpack-plugin": "^5.6.0", - "mini-css-extract-plugin": "^2.9.0", - "prettier": "3.3.3", - "style-loader": "^4.0.0", - "svg-inline-loader": "^0.8.2", - "tsx": "^4.16.2", - "typescript": "^5.5.4", - "vitest": "^2.0.4", - "webdriverio": "^8.39.1", - "webpack": "^5.93.0", + "eslint-import-resolver-typescript": "^3.7.0", + "eslint-plugin-import": "^2.31.0", + "eslint-plugin-oxlint": "^0.15.7", + "eslint-rspack-plugin": "^4.2.1", + "express": "^4.21.2", + "glob": "^11.0.1", + "http-server": "^14.1.1", + "jsdom": "^26.0.0", + "msw": "^2.7.0", + "nunjucks": "^3.2.4", + "oxlint": "^0.15.7", + "playwright": "^1.49.1", + "prettier": "3.4.2", + "s3rver": "^3.7.1", + "ts-checker-rspack-plugin": "^1.1.1", + "tsx": "^4.19.2", + "typescript": "^5.7.3", + "typescript-eslint": "^8.20.0", + "vitest": "^3.0.2", "webpack-bundle-analyzer": "^4.10.2", - "webpack-cli": "^5.1.4", - "webpack-dev-server": "^5.0.4", - "webpack-merge": "^6.0.1" + "webpack-merge": "^6.0.1", + "yargs": "^17.7.2", + "yauzl": "^3.2.0" }, "engines": { - "node": ">=20.10 <21 || >=21.2" + "node": ">=22" } }, "../../../node_modules/@aashutoshrathi/word-wrap": { @@ -80,99 +89,6 @@ "node": ">=0.10.0" } }, - "../../../node_modules/@babel/code-frame": { - "version": "7.12.11", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/highlight": "^7.10.4" - } - }, - "../../../node_modules/@babel/helper-validator-identifier": { - "version": "7.22.20", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "../../../node_modules/@babel/highlight": { - "version": "7.23.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-validator-identifier": "^7.22.20", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "../../../node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "../../../node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "../../../node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "1.1.3" - } - }, - "../../../node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/@babel/highlight/node_modules/escape-string-regexp": { - "version": "1.0.5", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, - "../../../node_modules/@babel/highlight/node_modules/has-flag": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "../../../node_modules/@babel/highlight/node_modules/supports-color": { - "version": "5.5.0", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, "../../../node_modules/@discoveryjs/json-ext": { "version": "0.5.7", "dev": true, @@ -719,26 +635,12 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "../../../node_modules/@jest/types": { - "version": "29.6.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/schemas": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, "../../../node_modules/@jridgewell/gen-mapping": { "version": "0.3.5", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -752,6 +654,8 @@ "version": "3.1.2", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=6.0.0" } @@ -760,6 +664,8 @@ "version": "1.2.1", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=6.0.0" } @@ -768,6 +674,8 @@ "version": "0.3.5", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@jridgewell/gen-mapping": "^0.3.0", "@jridgewell/trace-mapping": "^0.3.9" @@ -782,16 +690,13 @@ "version": "0.3.25", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "../../../node_modules/@leichtgewicht/ip-codec": { - "version": "2.0.4", - "dev": true, - "license": "MIT" - }, "../../../node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "dev": true, @@ -845,6 +750,8 @@ "version": "2.0.1", "dev": true, "license": "Apache-2.0", + "optional": true, + "peer": true, "dependencies": { "debug": "4.3.4", "extract-zip": "2.0.1", @@ -1078,6 +985,8 @@ "version": "5.6.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=14.16" }, @@ -1089,6 +998,8 @@ "version": "5.0.1", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "defer-to-connect": "^2.0.1" }, @@ -1100,8 +1011,6 @@ "version": "1.1.2", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "engines": { "node": ">= 6" } @@ -1109,24 +1018,9 @@ "../../../node_modules/@tootallnate/quickjs-emscripten": { "version": "0.23.0", "dev": true, - "license": "MIT" - }, - "../../../node_modules/@types/body-parser": { - "version": "1.19.5", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/connect": "*", - "@types/node": "*" - } - }, - "../../../node_modules/@types/bonjour": { - "version": "3.5.13", - "dev": true, "license": "MIT", - "dependencies": { - "@types/node": "*" - } + "optional": true, + "peer": true }, "../../../node_modules/@types/codemirror": { "version": "5.60.15", @@ -1136,27 +1030,12 @@ "@types/tern": "*" } }, - "../../../node_modules/@types/connect": { - "version": "3.4.38", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "../../../node_modules/@types/connect-history-api-fallback": { - "version": "1.5.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/express-serve-static-core": "*", - "@types/node": "*" - } - }, "../../../node_modules/@types/eslint": { "version": "8.56.5", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@types/estree": "*", "@types/json-schema": "*" @@ -1166,6 +1045,8 @@ "version": "3.7.7", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@types/eslint": "*", "@types/estree": "*" @@ -1176,81 +1057,24 @@ "dev": true, "license": "MIT" }, - "../../../node_modules/@types/express": { - "version": "4.17.21", - "dev": true, - "license": "MIT", - "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.17.43", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*", - "@types/send": "*" - } - }, "../../../node_modules/@types/gl-matrix": { "version": "2.4.5", "dev": true, "license": "MIT" }, - "../../../node_modules/@types/html-minifier-terser": { - "version": "6.1.0", - "dev": true, - "license": "MIT" - }, "../../../node_modules/@types/http-cache-semantics": { "version": "4.0.4", "dev": true, - "license": "MIT" - }, - "../../../node_modules/@types/http-errors": { - "version": "2.0.4", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/@types/http-proxy": { - "version": "1.17.14", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "../../../node_modules/@types/istanbul-lib-coverage": { - "version": "2.0.6", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/@types/istanbul-lib-report": { - "version": "3.0.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-coverage": "*" - } - }, - "../../../node_modules/@types/istanbul-reports": { - "version": "3.0.4", - "dev": true, "license": "MIT", - "dependencies": { - "@types/istanbul-lib-report": "*" - } + "optional": true, + "peer": true }, "../../../node_modules/@types/json-schema": { "version": "7.0.15", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/@types/json5": { "version": "0.0.29", @@ -1270,11 +1094,6 @@ "@types/lodash": "*" } }, - "../../../node_modules/@types/mime": { - "version": "1.3.5", - "dev": true, - "license": "MIT" - }, "../../../node_modules/@types/node": { "version": "20.11.20", "dev": true, @@ -1283,79 +1102,6 @@ "undici-types": "~5.26.4" } }, - "../../../node_modules/@types/node-forge": { - "version": "1.3.11", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "../../../node_modules/@types/pako": { - "version": "2.0.3", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/@types/parse-json": { - "version": "4.0.2", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/@types/qs": { - "version": "6.9.12", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/@types/range-parser": { - "version": "1.2.7", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/@types/retry": { - "version": "0.12.2", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/@types/semver": { - "version": "7.5.7", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/@types/send": { - "version": "0.17.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/mime": "^1", - "@types/node": "*" - } - }, - "../../../node_modules/@types/serve-index": { - "version": "1.9.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/express": "*" - } - }, - "../../../node_modules/@types/serve-static": { - "version": "1.15.5", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/http-errors": "*", - "@types/mime": "*", - "@types/node": "*" - } - }, - "../../../node_modules/@types/sockjs": { - "version": "0.3.36", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, "../../../node_modules/@types/tern": { "version": "0.23.9", "dev": true, @@ -1367,12 +1113,16 @@ "../../../node_modules/@types/which": { "version": "2.0.2", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/@types/ws": { "version": "8.5.10", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@types/node": "*" } @@ -1395,199 +1145,18 @@ "dev": true, "license": "MIT", "optional": true, + "peer": true, "dependencies": { "@types/node": "*" } }, - "../../../node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "7.0.2", - "@typescript-eslint/type-utils": "7.0.2", - "@typescript-eslint/utils": "7.0.2", - "@typescript-eslint/visitor-keys": "7.0.2", - "debug": "^4.3.4", - "graphemer": "^1.4.0", - "ignore": "^5.2.4", - "natural-compare": "^1.4.0", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^7.0.0", - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "../../../node_modules/@typescript-eslint/parser": { - "version": "7.0.2", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "@typescript-eslint/scope-manager": "7.0.2", - "@typescript-eslint/types": "7.0.2", - "@typescript-eslint/typescript-estree": "7.0.2", - "@typescript-eslint/visitor-keys": "7.0.2", - "debug": "^4.3.4" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "../../../node_modules/@typescript-eslint/scope-manager": { - "version": "7.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "7.0.2", - "@typescript-eslint/visitor-keys": "7.0.2" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "../../../node_modules/@typescript-eslint/type-utils": { - "version": "7.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/typescript-estree": "7.0.2", - "@typescript-eslint/utils": "7.0.2", - "debug": "^4.3.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "../../../node_modules/@typescript-eslint/types": { - "version": "7.0.2", - "dev": true, - "license": "MIT", - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "../../../node_modules/@typescript-eslint/typescript-estree": { - "version": "7.0.2", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "@typescript-eslint/types": "7.0.2", - "@typescript-eslint/visitor-keys": "7.0.2", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "9.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "../../../node_modules/@typescript-eslint/utils": { - "version": "7.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@types/json-schema": "^7.0.12", - "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "7.0.2", - "@typescript-eslint/types": "7.0.2", - "@typescript-eslint/typescript-estree": "7.0.2", - "semver": "^7.5.4" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - } - }, - "../../../node_modules/@typescript-eslint/visitor-keys": { - "version": "7.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "7.0.2", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "../../../node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "dev": true, - "license": "ISC" - }, - "../../../node_modules/@vitest/browser": { - "version": "1.3.1", + "../../../node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "dev": true, + "license": "ISC" + }, + "../../../node_modules/@vitest/browser": { + "version": "1.3.1", "dev": true, "license": "MIT", "dependencies": { @@ -1736,6 +1305,8 @@ "version": "8.32.3", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@wdio/logger": "8.28.0", "@wdio/types": "8.32.2", @@ -1753,6 +1324,8 @@ "version": "8.28.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "chalk": "^5.1.2", "loglevel": "^1.6.0", @@ -1767,6 +1340,8 @@ "version": "6.0.1", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=12" }, @@ -1778,6 +1353,8 @@ "version": "5.3.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": "^12.17.0 || ^14.13 || >=16.0.0" }, @@ -1789,6 +1366,8 @@ "version": "7.1.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "ansi-regex": "^6.0.1" }, @@ -1802,12 +1381,16 @@ "../../../node_modules/@wdio/protocols": { "version": "8.32.0", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/@wdio/repl": { "version": "8.24.12", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@types/node": "^20.1.0" }, @@ -1819,6 +1402,8 @@ "version": "8.32.2", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@types/node": "^20.1.0" }, @@ -1830,6 +1415,8 @@ "version": "8.32.3", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@puppeteer/browsers": "^1.6.0", "@wdio/logger": "8.28.0", @@ -1853,6 +1440,8 @@ "version": "1.11.6", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@webassemblyjs/helper-numbers": "1.11.6", "@webassemblyjs/helper-wasm-bytecode": "1.11.6" @@ -1861,22 +1450,30 @@ "../../../node_modules/@webassemblyjs/floating-point-hex-parser": { "version": "1.11.6", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/@webassemblyjs/helper-api-error": { "version": "1.11.6", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/@webassemblyjs/helper-buffer": { "version": "1.11.6", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/@webassemblyjs/helper-numbers": { "version": "1.11.6", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@webassemblyjs/floating-point-hex-parser": "1.11.6", "@webassemblyjs/helper-api-error": "1.11.6", @@ -1886,12 +1483,16 @@ "../../../node_modules/@webassemblyjs/helper-wasm-bytecode": { "version": "1.11.6", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/@webassemblyjs/helper-wasm-section": { "version": "1.11.6", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@webassemblyjs/ast": "1.11.6", "@webassemblyjs/helper-buffer": "1.11.6", @@ -1903,6 +1504,8 @@ "version": "1.11.6", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@xtuc/ieee754": "^1.2.0" } @@ -1911,6 +1514,8 @@ "version": "1.11.6", "dev": true, "license": "Apache-2.0", + "optional": true, + "peer": true, "dependencies": { "@xtuc/long": "4.2.2" } @@ -1918,12 +1523,16 @@ "../../../node_modules/@webassemblyjs/utf8": { "version": "1.11.6", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/@webassemblyjs/wasm-edit": { "version": "1.11.6", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@webassemblyjs/ast": "1.11.6", "@webassemblyjs/helper-buffer": "1.11.6", @@ -1939,6 +1548,8 @@ "version": "1.11.6", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@webassemblyjs/ast": "1.11.6", "@webassemblyjs/helper-wasm-bytecode": "1.11.6", @@ -1951,6 +1562,8 @@ "version": "1.11.6", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@webassemblyjs/ast": "1.11.6", "@webassemblyjs/helper-buffer": "1.11.6", @@ -1962,6 +1575,8 @@ "version": "1.11.6", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@webassemblyjs/ast": "1.11.6", "@webassemblyjs/helper-api-error": "1.11.6", @@ -1975,68 +1590,31 @@ "version": "1.11.6", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@webassemblyjs/ast": "1.11.6", "@xtuc/long": "4.2.2" } }, - "../../../node_modules/@webpack-cli/configtest": { - "version": "2.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14.15.0" - }, - "peerDependencies": { - "webpack": "5.x.x", - "webpack-cli": "5.x.x" - } - }, - "../../../node_modules/@webpack-cli/info": { - "version": "2.0.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14.15.0" - }, - "peerDependencies": { - "webpack": "5.x.x", - "webpack-cli": "5.x.x" - } - }, - "../../../node_modules/@webpack-cli/serve": { - "version": "2.0.5", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14.15.0" - }, - "peerDependencies": { - "webpack": "5.x.x", - "webpack-cli": "5.x.x" - }, - "peerDependenciesMeta": { - "webpack-dev-server": { - "optional": true - } - } - }, "../../../node_modules/@xtuc/ieee754": { "version": "1.2.0", "dev": true, - "license": "BSD-3-Clause" + "license": "BSD-3-Clause", + "optional": true, + "peer": true }, "../../../node_modules/@xtuc/long": { "version": "4.2.2", "dev": true, - "license": "Apache-2.0" + "license": "Apache-2.0", + "optional": true, + "peer": true }, "../../../node_modules/abab": { "version": "2.0.6", "dev": true, - "license": "BSD-3-Clause", - "optional": true, - "peer": true + "license": "BSD-3-Clause" }, "../../../node_modules/abbrev": { "version": "2.0.0", @@ -2045,18 +1623,6 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "../../../node_modules/accepts": { - "version": "1.3.8", - "dev": true, - "license": "MIT", - "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - }, - "engines": { - "node": ">= 0.6" - } - }, "../../../node_modules/acorn": { "version": "8.11.3", "dev": true, @@ -2072,8 +1638,6 @@ "version": "6.0.0", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "dependencies": { "acorn": "^7.1.1", "acorn-walk": "^7.1.1" @@ -2083,8 +1647,6 @@ "version": "7.4.1", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -2096,6 +1658,8 @@ "version": "1.9.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "peerDependencies": { "acorn": "^8" } @@ -2112,8 +1676,6 @@ "version": "7.2.0", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "engines": { "node": ">=0.4.0" } @@ -2122,8 +1684,6 @@ "version": "6.0.2", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "dependencies": { "debug": "4" }, @@ -2145,120 +1705,16 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "../../../node_modules/ajv-formats": { - "version": "2.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } - } - }, - "../../../node_modules/ajv-formats/node_modules/ajv": { - "version": "8.12.0", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "../../../node_modules/ajv-formats/node_modules/json-schema-traverse": { - "version": "1.0.0", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/ajv-keywords": { - "version": "3.5.2", + "../../../node_modules/ajv-keywords": { + "version": "3.5.2", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "peerDependencies": { "ajv": "^6.9.1" } }, - "../../../node_modules/ansi-align": { - "version": "3.0.1", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^4.1.0" - } - }, - "../../../node_modules/ansi-align/node_modules/emoji-regex": { - "version": "8.0.0", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/ansi-align/node_modules/string-width": { - "version": "4.2.3", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "../../../node_modules/ansi-colors": { - "version": "4.1.3", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "../../../node_modules/ansi-escapes": { - "version": "5.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "type-fest": "^1.0.2" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/ansi-escapes/node_modules/type-fest": { - "version": "1.4.0", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/ansi-html-community": { - "version": "0.0.8", - "dev": true, - "engines": [ - "node >= 0.8.0" - ], - "license": "Apache-2.0", - "bin": { - "ansi-html": "bin/ansi-html" - } - }, "../../../node_modules/ansi-regex": { "version": "5.0.1", "license": "MIT", @@ -2279,22 +1735,12 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "../../../node_modules/anymatch": { - "version": "3.1.3", - "dev": true, - "license": "ISC", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, "../../../node_modules/archiver": { "version": "6.0.1", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "archiver-utils": "^4.0.1", "async": "^3.2.4", @@ -2312,6 +1758,8 @@ "version": "4.0.1", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "glob": "^8.0.0", "graceful-fs": "^4.2.0", @@ -2328,6 +1776,8 @@ "version": "8.1.0", "dev": true, "license": "ISC", + "optional": true, + "peer": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -2346,6 +1796,8 @@ "version": "5.1.6", "dev": true, "license": "ISC", + "optional": true, + "peer": true, "dependencies": { "brace-expansion": "^2.0.1" }, @@ -2357,6 +1809,8 @@ "version": "3.6.2", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -2370,6 +1824,8 @@ "version": "3.6.2", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -2388,6 +1844,8 @@ "version": "5.3.0", "dev": true, "license": "Apache-2.0", + "optional": true, + "peer": true, "dependencies": { "dequal": "^2.0.3" } @@ -2411,11 +1869,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "../../../node_modules/array-flatten": { - "version": "1.1.1", - "dev": true, - "license": "MIT" - }, "../../../node_modules/array-includes": { "version": "3.1.7", "dev": true, @@ -2434,14 +1887,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "../../../node_modules/array-union": { - "version": "2.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "../../../node_modules/array.prototype.findlastindex": { "version": "1.2.3", "dev": true, @@ -2540,6 +1985,8 @@ "version": "0.13.4", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "tslib": "^2.0.1" }, @@ -2547,18 +1994,12 @@ "node": ">=4" } }, - "../../../node_modules/astral-regex": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "../../../node_modules/async": { "version": "3.2.5", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/async-limiter": { "version": "1.0.1", @@ -2568,14 +2009,6 @@ "version": "0.4.0", "license": "MIT" }, - "../../../node_modules/at-least-node": { - "version": "1.0.0", - "dev": true, - "license": "ISC", - "engines": { - "node": ">= 4.0.0" - } - }, "../../../node_modules/available-typed-arrays": { "version": "1.0.5", "dev": true, @@ -2601,7 +2034,9 @@ "../../../node_modules/b4a": { "version": "1.6.4", "dev": true, - "license": "ISC" + "license": "ISC", + "optional": true, + "peer": true }, "../../../node_modules/balanced-match": { "version": "1.0.2", @@ -2611,13 +2046,15 @@ "version": "2.2.0", "dev": true, "license": "Apache-2.0", - "optional": true + "optional": true, + "peer": true }, "../../../node_modules/bare-fs": { "version": "2.1.5", "dev": true, "license": "Apache-2.0", "optional": true, + "peer": true, "dependencies": { "bare-events": "^2.0.0", "bare-os": "^2.0.0", @@ -2629,13 +2066,15 @@ "version": "2.2.0", "dev": true, "license": "Apache-2.0", - "optional": true + "optional": true, + "peer": true }, "../../../node_modules/bare-path": { "version": "2.1.0", "dev": true, "license": "Apache-2.0", "optional": true, + "peer": true, "dependencies": { "bare-os": "^2.1.0" } @@ -2657,21 +2096,20 @@ "url": "https://feross.org/support" } ], - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/basic-ftp": { "version": "5.0.4", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=10.0.0" } }, - "../../../node_modules/batch": { - "version": "0.6.1", - "dev": true, - "license": "MIT" - }, "../../../node_modules/bcrypt-pbkdf": { "version": "1.0.2", "license": "BSD-3-Clause", @@ -2683,320 +2121,119 @@ "version": "1.6.52", "dev": true, "license": "Unlicense", + "optional": true, + "peer": true, "engines": { "node": ">=0.6" } }, - "../../../node_modules/big.js": { - "version": "5.2.2", - "dev": true, - "license": "MIT", - "engines": { - "node": "*" - } - }, "../../../node_modules/binary": { "version": "0.3.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "buffers": "~0.1.1", "chainsaw": "~0.1.0" } }, - "../../../node_modules/binary-extensions": { - "version": "2.2.0", + "../../../node_modules/bluebird": { + "version": "3.4.7", "dev": true, "license": "MIT", - "engines": { - "node": ">=8" - } + "optional": true, + "peer": true }, - "../../../node_modules/bl": { - "version": "5.1.0", - "dev": true, + "../../../node_modules/brace-expansion": { + "version": "2.0.1", "license": "MIT", "dependencies": { - "buffer": "^6.0.3", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" + "balanced-match": "^1.0.0" } }, - "../../../node_modules/bl/node_modules/readable-stream": { - "version": "3.6.2", + "../../../node_modules/braces": { + "version": "3.0.2", "dev": true, "license": "MIT", "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" + "fill-range": "^7.0.1" }, "engines": { - "node": ">= 6" + "node": ">=8" } }, - "../../../node_modules/bluebird": { - "version": "3.4.7", - "dev": true, - "license": "MIT" + "../../../node_modules/browser-process-hrtime": { + "version": "1.0.0", + "license": "BSD-2-Clause" }, - "../../../node_modules/body-parser": { - "version": "1.20.2", + "../../../node_modules/browserslist": { + "version": "4.23.0", "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", + "optional": true, + "peer": true, "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.11.0", - "raw-body": "2.5.2", - "type-is": "~1.6.18", - "unpipe": "1.0.0" + "caniuse-lite": "^1.0.30001587", + "electron-to-chromium": "^1.4.668", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.13" + }, + "bin": { + "browserslist": "cli.js" }, "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "../../../node_modules/body-parser/node_modules/bytes": { - "version": "3.1.2", + "../../../node_modules/buffer-crc32": { + "version": "0.2.13", "dev": true, "license": "MIT", "engines": { - "node": ">= 0.8" + "node": "*" } }, - "../../../node_modules/body-parser/node_modules/debug": { - "version": "2.6.9", + "../../../node_modules/buffer-from": { + "version": "1.1.2", "dev": true, "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "../../../node_modules/body-parser/node_modules/ms": { - "version": "2.0.0", - "dev": true, - "license": "MIT" + "optional": true, + "peer": true }, - "../../../node_modules/body-parser/node_modules/qs": { - "version": "6.11.0", + "../../../node_modules/buffer-indexof-polyfill": { + "version": "1.0.2", "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "side-channel": "^1.0.4" - }, + "license": "MIT", + "optional": true, + "peer": true, "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=0.10" } }, - "../../../node_modules/bonjour-service": { - "version": "1.2.1", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "multicast-dns": "^7.2.5" - } - }, - "../../../node_modules/boolbase": { - "version": "1.0.0", - "dev": true, - "license": "ISC" - }, - "../../../node_modules/boxen": { - "version": "7.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-align": "^3.0.1", - "camelcase": "^7.0.1", - "chalk": "^5.2.0", - "cli-boxes": "^3.0.0", - "string-width": "^5.1.2", - "type-fest": "^2.13.0", - "widest-line": "^4.0.1", - "wrap-ansi": "^8.1.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/boxen/node_modules/chalk": { - "version": "5.3.0", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "../../../node_modules/brace-expansion": { - "version": "2.0.1", - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "../../../node_modules/braces": { - "version": "3.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "../../../node_modules/brfs": { - "version": "1.6.1", - "license": "MIT", - "dependencies": { - "quote-stream": "^1.0.1", - "resolve": "^1.1.5", - "static-module": "^2.2.0", - "through2": "^2.0.0" - }, - "bin": { - "brfs": "bin/cmd.js" - } - }, - "../../../node_modules/brfs/node_modules/through2": { - "version": "2.0.5", - "license": "MIT", - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "../../../node_modules/browser-process-hrtime": { - "version": "1.0.0", - "license": "BSD-2-Clause" - }, - "../../../node_modules/browserslist": { - "version": "4.23.0", - "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": { - "caniuse-lite": "^1.0.30001587", - "electron-to-chromium": "^1.4.668", - "node-releases": "^2.0.14", - "update-browserslist-db": "^1.0.13" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "../../../node_modules/buffer": { - "version": "6.0.3", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, - "../../../node_modules/buffer-crc32": { - "version": "0.2.13", - "dev": true, - "license": "MIT", - "engines": { - "node": "*" - } - }, - "../../../node_modules/buffer-equal": { - "version": "0.0.1", - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, - "../../../node_modules/buffer-from": { - "version": "1.1.2", - "license": "MIT" - }, - "../../../node_modules/buffer-indexof-polyfill": { - "version": "1.0.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10" - } - }, - "../../../node_modules/buffers": { - "version": "0.1.1", + "../../../node_modules/buffers": { + "version": "0.1.1", "dev": true, + "optional": true, + "peer": true, "engines": { "node": ">=0.2.0" } }, - "../../../node_modules/bundle-name": { - "version": "4.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "run-applescript": "^7.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/bytes": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, "../../../node_modules/cac": { "version": "6.7.14", "dev": true, @@ -3009,6 +2246,8 @@ "version": "7.0.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=14.16" } @@ -3017,6 +2256,8 @@ "version": "10.2.14", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@types/http-cache-semantics": "^4.0.2", "get-stream": "^6.0.1", @@ -3034,6 +2275,8 @@ "version": "6.0.1", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=10" }, @@ -3062,26 +2305,6 @@ "node": ">=6" } }, - "../../../node_modules/camel-case": { - "version": "4.1.2", - "dev": true, - "license": "MIT", - "dependencies": { - "pascal-case": "^3.1.2", - "tslib": "^2.0.3" - } - }, - "../../../node_modules/camelcase": { - "version": "7.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "../../../node_modules/caniuse-lite": { "version": "1.0.30001596", "dev": true, @@ -3099,7 +2322,9 @@ "url": "https://github.com/sponsors/ai" } ], - "license": "CC-BY-4.0" + "license": "CC-BY-4.0", + "optional": true, + "peer": true }, "../../../node_modules/caseless": { "version": "0.12.0", @@ -3126,6 +2351,8 @@ "version": "0.1.0", "dev": true, "license": "MIT/X11", + "optional": true, + "peer": true, "dependencies": { "traverse": ">=0.3.0 <0.4" } @@ -3156,44 +2383,12 @@ "node": "*" } }, - "../../../node_modules/chokidar": { - "version": "3.6.0", - "dev": true, - "license": "MIT", - "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" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "../../../node_modules/chokidar/node_modules/glob-parent": { - "version": "5.1.2", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "../../../node_modules/chrome-trace-event": { "version": "1.0.3", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=6.0" } @@ -3202,6 +2397,8 @@ "version": "0.4.16", "dev": true, "license": "Apache-2.0", + "optional": true, + "peer": true, "dependencies": { "mitt": "3.0.0" }, @@ -3209,107 +2406,46 @@ "devtools-protocol": "*" } }, - "../../../node_modules/ci-info": { - "version": "3.9.0", + "../../../node_modules/cliui": { + "version": "8.0.1", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "license": "MIT", + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, "engines": { - "node": ">=8" + "node": ">=12" } }, - "../../../node_modules/clean-css": { - "version": "5.3.3", + "../../../node_modules/cliui/node_modules/emoji-regex": { + "version": "8.0.0", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/cliui/node_modules/string-width": { + "version": "4.2.3", "dev": true, "license": "MIT", "dependencies": { - "source-map": "~0.6.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" }, "engines": { - "node": ">= 10.0" + "node": ">=8" } }, - "../../../node_modules/cli-boxes": { - "version": "3.0.0", + "../../../node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", "dev": true, "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/cli-cursor": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "restore-cursor": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/cli-spinners": { - "version": "2.9.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/cliui": { - "version": "8.0.1", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "../../../node_modules/cliui/node_modules/emoji-regex": { - "version": "8.0.0", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/cliui/node_modules/string-width": { - "version": "4.2.3", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "../../../node_modules/cliui/node_modules/wrap-ansi": { - "version": "7.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, "engines": { "node": ">=10" }, @@ -3356,11 +2492,6 @@ "version": "1.1.4", "license": "MIT" }, - "../../../node_modules/colorette": { - "version": "2.0.20", - "dev": true, - "license": "MIT" - }, "../../../node_modules/combined-stream": { "version": "1.0.8", "license": "MIT", @@ -3371,28 +2502,22 @@ "node": ">= 0.8" } }, - "../../../node_modules/comlink": { - "version": "4.4.1", - "dev": true, - "license": "Apache-2.0" - }, "../../../node_modules/commander": { "version": "9.5.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": "^12.20.0 || >=14" } }, - "../../../node_modules/common-path-prefix": { - "version": "3.0.0", - "dev": true, - "license": "ISC" - }, "../../../node_modules/compress-commons": { "version": "5.0.1", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "crc-32": "^1.2.0", "crc32-stream": "^5.0.0", @@ -3407,6 +2532,8 @@ "version": "3.6.2", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -3416,70 +2543,11 @@ "node": ">= 6" } }, - "../../../node_modules/compressible": { - "version": "2.0.18", - "dev": true, - "license": "MIT", - "dependencies": { - "mime-db": ">= 1.43.0 < 2" - }, - "engines": { - "node": ">= 0.6" - } - }, - "../../../node_modules/compression": { - "version": "1.7.4", - "dev": true, - "license": "MIT", - "dependencies": { - "accepts": "~1.3.5", - "bytes": "3.0.0", - "compressible": "~2.0.16", - "debug": "2.6.9", - "on-headers": "~1.0.2", - "safe-buffer": "5.1.2", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "../../../node_modules/compression/node_modules/debug": { - "version": "2.6.9", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "../../../node_modules/compression/node_modules/ms": { - "version": "2.0.0", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/compression/node_modules/safe-buffer": { - "version": "5.1.2", - "dev": true, - "license": "MIT" - }, "../../../node_modules/concat-map": { "version": "0.0.1", "dev": true, "license": "MIT" }, - "../../../node_modules/concat-stream": { - "version": "1.6.2", - "engines": [ - "node >= 0.8" - ], - "license": "MIT", - "dependencies": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, "../../../node_modules/condense-newlines": { "version": "0.2.1", "license": "MIT", @@ -3504,73 +2572,15 @@ "version": "1.3.8", "license": "ISC" }, - "../../../node_modules/connect-history-api-fallback": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8" - } - }, - "../../../node_modules/content-disposition": { - "version": "0.5.4", - "dev": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "5.2.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "../../../node_modules/content-type": { - "version": "1.0.5", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "../../../node_modules/convert-source-map": { - "version": "1.9.0", - "license": "MIT" - }, - "../../../node_modules/cookie": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "../../../node_modules/cookie-signature": { - "version": "1.0.6", - "dev": true, - "license": "MIT" - }, "../../../node_modules/core-util-is": { "version": "1.0.3", - "license": "MIT" - }, - "../../../node_modules/cosmiconfig": { - "version": "6.0.0", "dev": true, "license": "MIT", - "dependencies": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.1.0", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.7.2" - }, - "engines": { - "node": ">=8" - } + "optional": true, + "peer": true }, "../../../node_modules/crc-32": { "version": "1.2.2", - "dev": true, "license": "Apache-2.0", "bin": { "crc32": "bin/crc32.njs" @@ -3583,6 +2593,8 @@ "version": "5.0.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "crc-32": "^1.2.0", "readable-stream": "^3.4.0" @@ -3595,6 +2607,8 @@ "version": "3.6.2", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -3608,6 +2622,8 @@ "version": "4.0.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "node-fetch": "^2.6.12" } @@ -3616,6 +2632,8 @@ "version": "2.7.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "whatwg-url": "^5.0.0" }, @@ -3634,17 +2652,23 @@ "../../../node_modules/cross-fetch/node_modules/tr46": { "version": "0.0.3", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/cross-fetch/node_modules/webidl-conversions": { "version": "3.0.1", "dev": true, - "license": "BSD-2-Clause" + "license": "BSD-2-Clause", + "optional": true, + "peer": true }, "../../../node_modules/cross-fetch/node_modules/whatwg-url": { "version": "5.0.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" @@ -3696,39 +2720,17 @@ } } }, - "../../../node_modules/css-select": { - "version": "4.3.0", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^6.0.1", - "domhandler": "^4.3.1", - "domutils": "^2.8.0", - "nth-check": "^2.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, "../../../node_modules/css-shorthand-properties": { "version": "1.1.1", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "../../../node_modules/css-value": { "version": "0.0.1", - "dev": true - }, - "../../../node_modules/css-what": { - "version": "6.1.0", "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">= 6" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } + "optional": true, + "peer": true }, "../../../node_modules/cssesc": { "version": "3.0.0", @@ -3744,16 +2746,12 @@ "../../../node_modules/cssom": { "version": "0.5.0", "dev": true, - "license": "MIT", - "optional": true, - "peer": true + "license": "MIT" }, "../../../node_modules/cssstyle": { "version": "2.3.0", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "dependencies": { "cssom": "~0.3.6" }, @@ -3764,9 +2762,7 @@ "../../../node_modules/cssstyle/node_modules/cssom": { "version": "0.3.8", "dev": true, - "license": "MIT", - "optional": true, - "peer": true + "license": "MIT" }, "../../../node_modules/dashdash": { "version": "1.14.1", @@ -3782,6 +2778,8 @@ "version": "4.0.1", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">= 12" } @@ -3790,8 +2788,6 @@ "version": "3.0.2", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "dependencies": { "abab": "^2.0.6", "whatwg-mimetype": "^3.0.0", @@ -3805,8 +2801,6 @@ "version": "3.0.0", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "dependencies": { "punycode": "^2.1.1" }, @@ -3818,8 +2812,6 @@ "version": "7.0.0", "dev": true, "license": "BSD-2-Clause", - "optional": true, - "peer": true, "engines": { "node": ">=12" } @@ -3828,8 +2820,6 @@ "version": "3.0.0", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "engines": { "node": ">=12" } @@ -3838,8 +2828,6 @@ "version": "11.0.0", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "dependencies": { "tr46": "^3.0.0", "webidl-conversions": "^7.0.0" @@ -3873,6 +2861,8 @@ "version": "6.0.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, @@ -3883,14 +2873,14 @@ "../../../node_modules/decimal.js": { "version": "10.4.3", "dev": true, - "license": "MIT", - "optional": true, - "peer": true + "license": "MIT" }, "../../../node_modules/decompress-response": { "version": "6.0.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "mimic-response": "^3.1.0" }, @@ -3905,6 +2895,8 @@ "version": "3.1.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=10" }, @@ -3927,147 +2919,22 @@ "version": "0.1.4", "license": "MIT" }, - "../../../node_modules/deepmerge": { - "version": "4.3.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "../../../node_modules/deepmerge-ts": { "version": "5.1.0", "dev": true, "license": "BSD-3-Clause", + "optional": true, + "peer": true, "engines": { "node": ">=16.0.0" } }, - "../../../node_modules/default-browser": { - "version": "5.2.1", - "dev": true, - "license": "MIT", - "dependencies": { - "bundle-name": "^4.1.0", - "default-browser-id": "^5.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/default-browser-id": { - "version": "5.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/default-gateway": { - "version": "6.0.3", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "execa": "^5.0.0" - }, - "engines": { - "node": ">= 10" - } - }, - "../../../node_modules/default-gateway/node_modules/execa": { - "version": "5.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "../../../node_modules/default-gateway/node_modules/get-stream": { - "version": "6.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/default-gateway/node_modules/human-signals": { - "version": "2.1.0", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=10.17.0" - } - }, - "../../../node_modules/default-gateway/node_modules/is-stream": { - "version": "2.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/default-gateway/node_modules/signal-exit": { - "version": "3.0.7", - "dev": true, - "license": "ISC" - }, - "../../../node_modules/default-gateway/node_modules/strip-final-newline": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "../../../node_modules/defaults": { - "version": "1.0.4", - "dev": true, - "license": "MIT", - "dependencies": { - "clone": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/defaults/node_modules/clone": { - "version": "1.0.4", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8" - } - }, "../../../node_modules/defer-to-connect": { "version": "2.0.1", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=10" } @@ -4085,17 +2952,6 @@ "node": ">= 0.4" } }, - "../../../node_modules/define-lazy-prop": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "../../../node_modules/define-properties": { "version": "1.2.1", "dev": true, @@ -4116,6 +2972,8 @@ "version": "5.0.1", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "ast-types": "^0.13.4", "escodegen": "^2.1.0", @@ -4132,31 +2990,16 @@ "node": ">=0.4.0" } }, - "../../../node_modules/depd": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, "../../../node_modules/dequal": { "version": "2.0.3", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=6" } }, - "../../../node_modules/destroy": { - "version": "1.2.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, "../../../node_modules/detect-libc": { "version": "1.0.3", "dev": true, @@ -4170,15 +3013,12 @@ "node": ">=0.10" } }, - "../../../node_modules/detect-node": { - "version": "2.1.0", - "dev": true, - "license": "MIT" - }, "../../../node_modules/devtools-protocol": { "version": "0.0.1262051", "dev": true, - "license": "BSD-3-Clause" + "license": "BSD-3-Clause", + "optional": true, + "peer": true }, "../../../node_modules/diff-sequences": { "version": "29.6.3", @@ -4188,28 +3028,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "../../../node_modules/dir-glob": { - "version": "3.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "../../../node_modules/dns-packet": { - "version": "5.6.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@leichtgewicht/ip-codec": "^2.0.1" - }, - "engines": { - "node": ">=6" - } - }, "../../../node_modules/doctrine": { "version": "3.0.0", "dev": true, @@ -4221,44 +3039,10 @@ "node": ">=6.0.0" } }, - "../../../node_modules/dom-converter": { - "version": "0.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "utila": "~0.4" - } - }, - "../../../node_modules/dom-serializer": { - "version": "1.4.1", - "dev": true, - "license": "MIT", - "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.0", - "entities": "^2.0.0" - }, - "funding": { - "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" - } - }, - "../../../node_modules/domelementtype": { - "version": "2.3.0", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "license": "BSD-2-Clause" - }, "../../../node_modules/domexception": { "version": "2.0.1", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "dependencies": { "webidl-conversions": "^5.0.0" }, @@ -4270,48 +3054,10 @@ "version": "5.0.0", "dev": true, "license": "BSD-2-Clause", - "optional": true, - "peer": true, "engines": { "node": ">=8" } }, - "../../../node_modules/domhandler": { - "version": "4.3.1", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "domelementtype": "^2.2.0" - }, - "engines": { - "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" - } - }, - "../../../node_modules/domutils": { - "version": "2.8.0", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "dom-serializer": "^1.0.1", - "domelementtype": "^2.2.0", - "domhandler": "^4.2.0" - }, - "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" - } - }, - "../../../node_modules/dot-case": { - "version": "3.0.4", - "dev": true, - "license": "MIT", - "dependencies": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, "../../../node_modules/duplexer": { "version": "0.1.2", "dev": true, @@ -4319,7 +3065,10 @@ }, "../../../node_modules/duplexer2": { "version": "0.1.4", + "dev": true, "license": "BSD-3-Clause", + "optional": true, + "peer": true, "dependencies": { "readable-stream": "^2.0.2" } @@ -4340,6 +3089,8 @@ "version": "3.0.5", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@types/which": "^2.0.1", "which": "^2.0.2" @@ -4356,6 +3107,8 @@ "dev": true, "hasInstallScript": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@wdio/logger": "^8.28.0", "decamelize": "^6.0.0", @@ -4372,6 +3125,8 @@ "version": "3.1.1", "dev": true, "license": "ISC", + "optional": true, + "peer": true, "engines": { "node": ">=16" } @@ -4380,6 +3135,8 @@ "version": "4.0.0", "dev": true, "license": "ISC", + "optional": true, + "peer": true, "dependencies": { "isexe": "^3.1.1" }, @@ -4426,44 +3183,23 @@ "url": "https://github.com/sponsors/isaacs" } }, - "../../../node_modules/ee-first": { - "version": "1.1.1", - "dev": true, - "license": "MIT" - }, "../../../node_modules/electron-to-chromium": { "version": "1.4.699", "dev": true, - "license": "ISC" - }, - "../../../node_modules/element-size": { - "version": "1.1.1", - "license": "MIT" + "license": "ISC", + "optional": true, + "peer": true }, "../../../node_modules/emoji-regex": { "version": "9.2.2", "license": "MIT" }, - "../../../node_modules/emojis-list": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "../../../node_modules/encodeurl": { - "version": "1.0.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, "../../../node_modules/end-of-stream": { "version": "1.4.4", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "once": "^1.4.0" } @@ -4480,47 +3216,8 @@ "node": ">=10.13.0" } }, - "../../../node_modules/enquirer": { - "version": "2.4.1", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-colors": "^4.1.1", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "../../../node_modules/entities": { - "version": "2.2.0", - "dev": true, - "license": "BSD-2-Clause", - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "../../../node_modules/envinfo": { - "version": "7.11.1", - "dev": true, - "license": "MIT", - "bin": { - "envinfo": "dist/cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "../../../node_modules/error-ex": { - "version": "1.3.2", - "dev": true, - "license": "MIT", - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "../../../node_modules/es-abstract": { - "version": "1.22.3", + "../../../node_modules/es-abstract": { + "version": "1.22.3", "dev": true, "license": "MIT", "dependencies": { @@ -4574,7 +3271,9 @@ "../../../node_modules/es-module-lexer": { "version": "1.4.1", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/es-set-tostringtag": { "version": "2.0.2", @@ -4650,23 +3349,6 @@ "@esbuild/win32-x64": "0.20.1" } }, - "../../../node_modules/esbuild-loader": { - "version": "4.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "esbuild": "^0.20.0", - "get-tsconfig": "^4.7.0", - "loader-utils": "^2.0.4", - "webpack-sources": "^1.4.3" - }, - "funding": { - "url": "https://github.com/privatenumber/esbuild-loader?sponsor=1" - }, - "peerDependencies": { - "webpack": "^4.40.0 || ^5.0.0" - } - }, "../../../node_modules/esbuild/node_modules/@esbuild/aix-ppc64": { "version": "0.20.1", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.1.tgz", @@ -5027,11 +3709,6 @@ "node": ">=6" } }, - "../../../node_modules/escape-html": { - "version": "1.0.3", - "dev": true, - "license": "MIT" - }, "../../../node_modules/escape-string-regexp": { "version": "4.0.0", "dev": true, @@ -5045,6 +3722,7 @@ }, "../../../node_modules/escodegen": { "version": "2.1.0", + "dev": true, "license": "BSD-2-Clause", "dependencies": { "esprima": "^4.0.1", @@ -5116,18 +3794,6 @@ "url": "https://opencollective.com/eslint" } }, - "../../../node_modules/eslint-formatter-codeframe": { - "version": "7.32.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "7.12.11", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, "../../../node_modules/eslint-import-resolver-node": { "version": "0.3.9", "dev": true, @@ -5170,71 +3836,6 @@ "eslint-plugin-import": "*" } }, - "../../../node_modules/eslint-interactive": { - "version": "10.8.0", - "dev": true, - "license": "MIT", - "dependencies": { - "boxen": "^7.0.2", - "chalk": "^5.0.1", - "comlink": "^4.3.1", - "enquirer": "^2.3.6", - "eslint-formatter-codeframe": "^7.32.1", - "estraverse": "^5.3.0", - "find-cache-dir": "^4.0.0", - "is-installed-globally": "^0.4.0", - "ora": "^6.1.2", - "strip-ansi": "^7.0.1", - "table": "^6.8.1", - "terminal-link": "^3.0.0", - "yargs": "^17.5.1" - }, - "bin": { - "eslint-interactive": "bin/eslint-interactive.js" - }, - "engines": { - "node": "^14.13.1 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" - } - }, - "../../../node_modules/eslint-interactive/node_modules/ansi-regex": { - "version": "6.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "../../../node_modules/eslint-interactive/node_modules/chalk": { - "version": "5.3.0", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "../../../node_modules/eslint-interactive/node_modules/strip-ansi": { - "version": "7.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, "../../../node_modules/eslint-module-utils": { "version": "2.8.0", "dev": true, @@ -5362,106 +3963,6 @@ "url": "https://opencollective.com/eslint" } }, - "../../../node_modules/eslint-webpack-plugin": { - "version": "4.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/eslint": "^8.37.0", - "jest-worker": "^29.5.0", - "micromatch": "^4.0.5", - "normalize-path": "^3.0.0", - "schema-utils": "^4.0.0" - }, - "engines": { - "node": ">= 14.15.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "eslint": "^8.0.0", - "webpack": "^5.0.0" - } - }, - "../../../node_modules/eslint-webpack-plugin/node_modules/ajv": { - "version": "8.12.0", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "../../../node_modules/eslint-webpack-plugin/node_modules/ajv-keywords": { - "version": "5.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, - "../../../node_modules/eslint-webpack-plugin/node_modules/jest-worker": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*", - "jest-util": "^29.7.0", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "../../../node_modules/eslint-webpack-plugin/node_modules/json-schema-traverse": { - "version": "1.0.0", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/eslint-webpack-plugin/node_modules/schema-utils": { - "version": "4.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.9.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.1.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "../../../node_modules/eslint-webpack-plugin/node_modules/supports-color": { - "version": "8.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, "../../../node_modules/eslint/node_modules/brace-expansion": { "version": "1.1.11", "dev": true, @@ -5533,6 +4034,7 @@ }, "../../../node_modules/estraverse": { "version": "5.3.0", + "dev": true, "license": "BSD-2-Clause", "engines": { "node": ">=4.0" @@ -5545,26 +4047,6 @@ "node": ">=0.10.0" } }, - "../../../node_modules/etag": { - "version": "1.8.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "../../../node_modules/eventemitter3": { - "version": "4.0.7", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/events": { - "version": "1.1.1", - "license": "MIT", - "engines": { - "node": ">=0.4.x" - } - }, "../../../node_modules/execa": { "version": "8.0.1", "dev": true, @@ -5637,75 +4119,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "../../../node_modules/express": { - "version": "4.19.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", - "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", - "dev": true, - "dependencies": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.2", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.6.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.2.0", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.7", - "qs": "6.11.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "../../../node_modules/express/node_modules/debug": { - "version": "2.6.9", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "../../../node_modules/express/node_modules/ms": { - "version": "2.0.0", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/express/node_modules/qs": { - "version": "6.11.0", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "../../../node_modules/extend": { "version": "3.0.2", "license": "MIT" @@ -5724,6 +4137,8 @@ "version": "2.0.1", "dev": true, "license": "BSD-2-Clause", + "optional": true, + "peer": true, "dependencies": { "debug": "^4.1.1", "get-stream": "^5.1.0", @@ -5743,6 +4158,8 @@ "version": "5.2.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "pump": "^3.0.0" }, @@ -5757,507 +4174,194 @@ "version": "1.3.0", "engines": [ "node >=0.6.0" - ], - "license": "MIT" - }, - "../../../node_modules/falafel": { - "version": "2.2.5", - "license": "MIT", - "dependencies": { - "acorn": "^7.1.1", - "isarray": "^2.0.1" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "../../../node_modules/falafel/node_modules/acorn": { - "version": "7.4.1", - "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "../../../node_modules/fast-deep-equal": { - "version": "3.1.3", - "license": "MIT" - }, - "../../../node_modules/fast-fifo": { - "version": "1.3.2", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/fast-glob": { - "version": "3.3.2", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "../../../node_modules/fast-glob/node_modules/glob-parent": { - "version": "5.1.2", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "../../../node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "license": "MIT" - }, - "../../../node_modules/fast-levenshtein": { - "version": "2.0.6", - "license": "MIT" - }, - "../../../node_modules/fastest-levenshtein": { - "version": "1.0.16", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4.9.1" - } - }, - "../../../node_modules/fastq": { - "version": "1.17.0", - "dev": true, - "license": "ISC", - "dependencies": { - "reusify": "^1.0.4" - } - }, - "../../../node_modules/faye-websocket": { - "version": "0.11.4", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "websocket-driver": ">=0.5.1" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "../../../node_modules/fd-slicer": { - "version": "1.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "pend": "~1.2.0" - } - }, - "../../../node_modules/fetch-blob": { - "version": "3.2.0", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/jimmywarting" - }, - { - "type": "paypal", - "url": "https://paypal.me/jimmywarting" - } - ], - "license": "MIT", - "dependencies": { - "node-domexception": "^1.0.0", - "web-streams-polyfill": "^3.0.3" - }, - "engines": { - "node": "^12.20 || >= 14.13" - } - }, - "../../../node_modules/fflate": { - "version": "0.8.1", - "license": "MIT" - }, - "../../../node_modules/file-entry-cache": { - "version": "6.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "../../../node_modules/fill-range": { - "version": "7.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "../../../node_modules/finalhandler": { - "version": "1.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "../../../node_modules/finalhandler/node_modules/debug": { - "version": "2.6.9", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "../../../node_modules/finalhandler/node_modules/ms": { - "version": "2.0.0", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/find-cache-dir": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "common-path-prefix": "^3.0.0", - "pkg-dir": "^7.0.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/find-up": { - "version": "5.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/flat": { - "version": "5.0.2", - "dev": true, - "license": "BSD-3-Clause", - "bin": { - "flat": "cli.js" - } - }, - "../../../node_modules/flat-cache": { - "version": "3.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "../../../node_modules/flatted": { - "version": "3.2.9", - "dev": true, - "license": "ISC" - }, - "../../../node_modules/follow-redirects": { - "version": "1.15.5", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "license": "MIT", - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, - "../../../node_modules/for-each": { - "version": "0.3.3", - "dev": true, - "license": "MIT", - "dependencies": { - "is-callable": "^1.1.3" - } - }, - "../../../node_modules/foreground-child": { - "version": "3.1.1", - "license": "ISC", - "dependencies": { - "cross-spawn": "^7.0.0", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "../../../node_modules/forever-agent": { - "version": "0.6.1", - "license": "Apache-2.0", - "engines": { - "node": "*" - } - }, - "../../../node_modules/fork-ts-checker-webpack-plugin": { - "version": "6.5.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.8.3", - "@types/json-schema": "^7.0.5", - "chalk": "^4.1.0", - "chokidar": "^3.4.2", - "cosmiconfig": "^6.0.0", - "deepmerge": "^4.2.2", - "fs-extra": "^9.0.0", - "glob": "^7.1.6", - "memfs": "^3.1.2", - "minimatch": "^3.0.4", - "schema-utils": "2.7.0", - "semver": "^7.3.2", - "tapable": "^1.0.0" - }, - "engines": { - "node": ">=10", - "yarn": ">=1.0.0" - }, - "peerDependencies": { - "eslint": ">= 6", - "typescript": ">= 2.7", - "vue-template-compiler": "*", - "webpack": ">= 4" - }, - "peerDependenciesMeta": { - "eslint": { - "optional": true - }, - "vue-template-compiler": { - "optional": true - } - } + ], + "license": "MIT" + }, + "../../../node_modules/fast-deep-equal": { + "version": "3.1.3", + "license": "MIT" + }, + "../../../node_modules/fast-fifo": { + "version": "1.3.2", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true }, - "../../../node_modules/fork-ts-checker-webpack-plugin/node_modules/@babel/code-frame": { - "version": "7.23.5", + "../../../node_modules/fast-glob": { + "version": "3.3.2", "dev": true, "license": "MIT", "dependencies": { - "@babel/highlight": "^7.23.4", - "chalk": "^2.4.2" + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" }, "engines": { - "node": ">=6.9.0" + "node": ">=8.6.0" } }, - "../../../node_modules/fork-ts-checker-webpack-plugin/node_modules/@babel/code-frame/node_modules/chalk": { - "version": "2.4.2", + "../../../node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", "dev": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "is-glob": "^4.0.1" }, "engines": { - "node": ">=4" + "node": ">= 6" } }, - "../../../node_modules/fork-ts-checker-webpack-plugin/node_modules/ansi-styles": { - "version": "3.2.1", + "../../../node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "license": "MIT" + }, + "../../../node_modules/fast-levenshtein": { + "version": "2.0.6", + "license": "MIT" + }, + "../../../node_modules/fastq": { + "version": "1.17.0", "dev": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" + "reusify": "^1.0.4" } }, - "../../../node_modules/fork-ts-checker-webpack-plugin/node_modules/brace-expansion": { - "version": "1.1.11", + "../../../node_modules/fd-slicer": { + "version": "1.1.0", "dev": true, "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "pend": "~1.2.0" } }, - "../../../node_modules/fork-ts-checker-webpack-plugin/node_modules/color-convert": { - "version": "1.9.3", + "../../../node_modules/fetch-blob": { + "version": "3.2.0", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "paypal", + "url": "https://paypal.me/jimmywarting" + } + ], "license": "MIT", + "optional": true, + "peer": true, "dependencies": { - "color-name": "1.1.3" + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + }, + "engines": { + "node": "^12.20 || >= 14.13" } }, - "../../../node_modules/fork-ts-checker-webpack-plugin/node_modules/color-name": { - "version": "1.1.3", - "dev": true, + "../../../node_modules/fflate": { + "version": "0.8.1", "license": "MIT" }, - "../../../node_modules/fork-ts-checker-webpack-plugin/node_modules/escape-string-regexp": { - "version": "1.0.5", + "../../../node_modules/file-entry-cache": { + "version": "6.0.1", "dev": true, "license": "MIT", + "dependencies": { + "flat-cache": "^3.0.4" + }, "engines": { - "node": ">=0.8.0" + "node": "^10.12.0 || >=12.0.0" } }, - "../../../node_modules/fork-ts-checker-webpack-plugin/node_modules/fs-extra": { - "version": "9.1.0", + "../../../node_modules/fill-range": { + "version": "7.0.1", "dev": true, "license": "MIT", "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" + "to-regex-range": "^5.0.1" }, "engines": { - "node": ">=10" + "node": ">=8" } }, - "../../../node_modules/fork-ts-checker-webpack-plugin/node_modules/glob": { - "version": "7.2.3", + "../../../node_modules/find-up": { + "version": "5.0.0", "dev": true, - "license": "ISC", + "license": "MIT", "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" + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" }, "engines": { - "node": "*" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/sponsors/sindresorhus" } }, - "../../../node_modules/fork-ts-checker-webpack-plugin/node_modules/has-flag": { - "version": "3.0.0", + "../../../node_modules/flat": { + "version": "5.0.2", "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" + "license": "BSD-3-Clause", + "bin": { + "flat": "cli.js" } }, - "../../../node_modules/fork-ts-checker-webpack-plugin/node_modules/memfs": { - "version": "3.5.3", + "../../../node_modules/flat-cache": { + "version": "3.2.0", "dev": true, - "license": "Unlicense", + "license": "MIT", "dependencies": { - "fs-monkey": "^1.0.4" + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" }, "engines": { - "node": ">= 4.0.0" + "node": "^10.12.0 || >=12.0.0" } }, - "../../../node_modules/fork-ts-checker-webpack-plugin/node_modules/minimatch": { - "version": "3.1.2", + "../../../node_modules/flatted": { + "version": "3.2.9", "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } + "license": "ISC" }, - "../../../node_modules/fork-ts-checker-webpack-plugin/node_modules/schema-utils": { - "version": "2.7.0", + "../../../node_modules/for-each": { + "version": "0.3.3", "dev": true, "license": "MIT", "dependencies": { - "@types/json-schema": "^7.0.4", - "ajv": "^6.12.2", - "ajv-keywords": "^3.4.1" - }, - "engines": { - "node": ">= 8.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" + "is-callable": "^1.1.3" } }, - "../../../node_modules/fork-ts-checker-webpack-plugin/node_modules/supports-color": { - "version": "5.5.0", - "dev": true, - "license": "MIT", + "../../../node_modules/foreground-child": { + "version": "3.1.1", + "license": "ISC", "dependencies": { - "has-flag": "^3.0.0" + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" }, "engines": { - "node": ">=4" - } - }, - "../../../node_modules/fork-ts-checker-webpack-plugin/node_modules/tapable": { - "version": "1.1.3", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "../../../node_modules/fork-ts-checker-webpack-plugin/node_modules/universalify": { - "version": "2.0.1", - "dev": true, - "license": "MIT", + "../../../node_modules/forever-agent": { + "version": "0.6.1", + "license": "Apache-2.0", "engines": { - "node": ">= 10.0.0" + "node": "*" } }, "../../../node_modules/form-data": { "version": "4.0.0", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -6271,6 +4375,8 @@ "version": "2.1.4", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">= 14.17" } @@ -6279,6 +4385,8 @@ "version": "4.0.10", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "fetch-blob": "^3.1.2" }, @@ -6286,26 +4394,12 @@ "node": ">=12.20.0" } }, - "../../../node_modules/forwarded": { - "version": "0.2.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "../../../node_modules/fresh": { - "version": "0.5.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, "../../../node_modules/fs-extra": { "version": "11.2.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", @@ -6319,15 +4413,12 @@ "version": "2.0.1", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">= 10.0.0" } }, - "../../../node_modules/fs-monkey": { - "version": "1.0.5", - "dev": true, - "license": "Unlicense" - }, "../../../node_modules/fs.realpath": { "version": "1.0.0", "dev": true, @@ -6351,6 +4442,8 @@ "version": "1.0.12", "dev": true, "license": "ISC", + "optional": true, + "peer": true, "dependencies": { "graceful-fs": "^4.1.2", "inherits": "~2.0.0", @@ -6365,6 +4458,8 @@ "version": "1.1.11", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -6374,6 +4469,8 @@ "version": "7.2.3", "dev": true, "license": "ISC", + "optional": true, + "peer": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -6393,6 +4490,8 @@ "version": "3.1.2", "dev": true, "license": "ISC", + "optional": true, + "peer": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -6404,6 +4503,8 @@ "version": "2.7.1", "dev": true, "license": "ISC", + "optional": true, + "peer": true, "dependencies": { "glob": "^7.1.3" }, @@ -6413,6 +4514,7 @@ }, "../../../node_modules/function-bind": { "version": "1.1.2", + "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" @@ -6448,6 +4550,8 @@ "dev": true, "hasInstallScript": true, "license": "MPL-2.0", + "optional": true, + "peer": true, "dependencies": { "@wdio/logger": "^8.28.0", "decamelize": "^6.0.0", @@ -6469,6 +4573,8 @@ "version": "7.1.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "debug": "^4.3.4" }, @@ -6480,6 +4586,8 @@ "version": "7.0.2", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "agent-base": "^7.1.0", "debug": "^4.3.4" @@ -6492,6 +4600,8 @@ "version": "7.0.4", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "agent-base": "^7.0.2", "debug": "4" @@ -6504,6 +4614,8 @@ "version": "3.1.1", "dev": true, "license": "ISC", + "optional": true, + "peer": true, "engines": { "node": ">=16" } @@ -6512,6 +4624,8 @@ "version": "4.0.0", "dev": true, "license": "ISC", + "optional": true, + "peer": true, "dependencies": { "isexe": "^3.1.1" }, @@ -6556,6 +4670,8 @@ "version": "7.0.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=16" }, @@ -6604,6 +4720,8 @@ "version": "6.0.3", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "basic-ftp": "^5.0.2", "data-uri-to-buffer": "^6.0.2", @@ -6618,6 +4736,8 @@ "version": "6.0.2", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">= 14" } @@ -6664,24 +4784,12 @@ "node": ">=10.13.0" } }, - "../../../node_modules/glob-to-regexp": { - "version": "0.4.1", - "dev": true, - "license": "BSD-2-Clause" - }, - "../../../node_modules/global-dirs": { - "version": "3.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "ini": "2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } + "../../../node_modules/glob-to-regexp": { + "version": "0.4.1", + "dev": true, + "license": "BSD-2-Clause", + "optional": true, + "peer": true }, "../../../node_modules/globals": { "version": "13.24.0", @@ -6722,42 +4830,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "../../../node_modules/globby": { - "version": "11.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/glsl-editor": { - "version": "1.0.0", - "license": "MIT", - "dependencies": { - "brfs": "^1.2.0", - "codemirror": "^4.5.0", - "element-size": "^1.1.1", - "events": "^1.0.2", - "inherits": "^2.0.1", - "insert-css": "^0.2.0", - "through2": "^0.6.1", - "xtend": "^4.0.0" - } - }, - "../../../node_modules/glsl-editor/node_modules/codemirror": { - "version": "4.13.0" - }, "../../../node_modules/gopd": { "version": "1.0.1", "dev": true, @@ -6773,6 +4845,8 @@ "version": "12.6.1", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@sindresorhus/is": "^5.2.0", "@szmarczak/http-timer": "^5.0.1", @@ -6797,6 +4871,8 @@ "version": "6.0.1", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=10" }, @@ -6812,7 +4888,9 @@ "../../../node_modules/grapheme-splitter": { "version": "1.0.4", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/graphemer": { "version": "1.4.0", @@ -6833,11 +4911,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "../../../node_modules/handle-thing": { - "version": "2.0.1", - "dev": true, - "license": "MIT" - }, "../../../node_modules/har-schema": { "version": "2.0.0", "license": "ISC", @@ -6856,13 +4929,6 @@ "node": ">=6" } }, - "../../../node_modules/has": { - "version": "1.0.4", - "license": "MIT", - "engines": { - "node": ">= 0.4.0" - } - }, "../../../node_modules/has-bigints": { "version": "1.0.2", "dev": true, @@ -6928,6 +4994,7 @@ }, "../../../node_modules/hasown": { "version": "2.0.0", + "dev": true, "license": "MIT", "dependencies": { "function-bind": "^1.1.2" @@ -6936,31 +5003,10 @@ "node": ">= 0.4" } }, - "../../../node_modules/he": { - "version": "1.2.0", - "dev": true, - "license": "MIT", - "bin": { - "he": "bin/he" - } - }, - "../../../node_modules/hpack.js": { - "version": "2.1.6", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.1", - "obuf": "^1.0.0", - "readable-stream": "^2.0.1", - "wbuf": "^1.1.0" - } - }, "../../../node_modules/html-encoding-sniffer": { "version": "2.0.1", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "dependencies": { "whatwg-encoding": "^1.0.5" }, @@ -6968,152 +5014,22 @@ "node": ">=10" } }, - "../../../node_modules/html-entities": { - "version": "2.5.2", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/mdevils" - }, - { - "type": "patreon", - "url": "https://patreon.com/mdevils" - } - ], - "license": "MIT" - }, "../../../node_modules/html-escaper": { "version": "2.0.2", "dev": true, "license": "MIT" }, - "../../../node_modules/html-minifier-terser": { - "version": "6.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "camel-case": "^4.1.2", - "clean-css": "^5.2.2", - "commander": "^8.3.0", - "he": "^1.2.0", - "param-case": "^3.0.4", - "relateurl": "^0.2.7", - "terser": "^5.10.0" - }, - "bin": { - "html-minifier-terser": "cli.js" - }, - "engines": { - "node": ">=12" - } - }, - "../../../node_modules/html-minifier-terser/node_modules/commander": { - "version": "8.3.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 12" - } - }, - "../../../node_modules/html-webpack-plugin": { - "version": "5.6.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/html-minifier-terser": "^6.0.0", - "html-minifier-terser": "^6.0.2", - "lodash": "^4.17.21", - "pretty-error": "^4.0.0", - "tapable": "^2.0.0" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/html-webpack-plugin" - }, - "peerDependencies": { - "@rspack/core": "0.x || 1.x", - "webpack": "^5.20.0" - }, - "peerDependenciesMeta": { - "@rspack/core": { - "optional": true - }, - "webpack": { - "optional": true - } - } - }, - "../../../node_modules/htmlparser2": { - "version": "6.1.0", - "dev": true, - "funding": [ - "https://github.com/fb55/htmlparser2?sponsor=1", - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "license": "MIT", - "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.0.0", - "domutils": "^2.5.2", - "entities": "^2.0.0" - } - }, "../../../node_modules/http-cache-semantics": { "version": "4.1.1", "dev": true, - "license": "BSD-2-Clause" - }, - "../../../node_modules/http-deceiver": { - "version": "1.2.7", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/http-errors": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "../../../node_modules/http-parser-js": { - "version": "0.5.8", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/http-proxy": { - "version": "1.18.1", - "dev": true, - "license": "MIT", - "dependencies": { - "eventemitter3": "^4.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" - }, - "engines": { - "node": ">=8.0.0" - } + "license": "BSD-2-Clause", + "optional": true, + "peer": true }, "../../../node_modules/http-proxy-agent": { "version": "4.0.1", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "dependencies": { "@tootallnate/once": "1", "agent-base": "6", @@ -7123,40 +5039,6 @@ "node": ">= 6" } }, - "../../../node_modules/http-proxy-middleware": { - "version": "2.0.6", - "dev": true, - "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" - }, - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "@types/express": "^4.17.13" - }, - "peerDependenciesMeta": { - "@types/express": { - "optional": true - } - } - }, - "../../../node_modules/http-proxy-middleware/node_modules/is-plain-obj": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "../../../node_modules/http-signature": { "version": "1.2.0", "license": "MIT", @@ -7174,6 +5056,8 @@ "version": "2.2.1", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "quick-lru": "^5.1.1", "resolve-alpn": "^1.2.0" @@ -7186,8 +5070,6 @@ "version": "5.0.1", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "dependencies": { "agent-base": "6", "debug": "4" @@ -7242,7 +5124,9 @@ "url": "https://feross.org/support" } ], - "license": "BSD-3-Clause" + "license": "BSD-3-Clause", + "optional": true, + "peer": true }, "../../../node_modules/ignore": { "version": "5.3.0", @@ -7484,113 +5368,38 @@ "dependencies": { "lodash.sortby": "^4.7.0", "tr46": "^1.0.1", - "webidl-conversions": "^4.0.2" - } - }, - "../../../node_modules/ikonate/node_modules/ws": { - "version": "4.1.0", - "license": "MIT", - "dependencies": { - "async-limiter": "~1.0.0", - "safe-buffer": "~5.1.0" - } - }, - "../../../node_modules/import-fresh": { - "version": "3.3.0", - "dev": true, - "license": "MIT", - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/import-local": { - "version": "3.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - }, - "bin": { - "import-local-fixture": "fixtures/cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/import-local/node_modules/find-up": { - "version": "4.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "../../../node_modules/import-local/node_modules/locate-path": { - "version": "5.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "../../../node_modules/import-local/node_modules/p-limit": { - "version": "2.3.0", - "dev": true, - "license": "MIT", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "webidl-conversions": "^4.0.2" } }, - "../../../node_modules/import-local/node_modules/p-locate": { + "../../../node_modules/ikonate/node_modules/ws": { "version": "4.1.0", - "dev": true, "license": "MIT", "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" + "async-limiter": "~1.0.0", + "safe-buffer": "~5.1.0" } }, - "../../../node_modules/import-local/node_modules/pkg-dir": { - "version": "4.2.0", + "../../../node_modules/import-fresh": { + "version": "3.3.0", "dev": true, "license": "MIT", "dependencies": { - "find-up": "^4.0.0" + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" }, "engines": { - "node": ">=8" + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "../../../node_modules/import-meta-resolve": { "version": "4.0.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -7615,19 +5424,8 @@ }, "../../../node_modules/inherits": { "version": "2.0.4", - "license": "ISC" - }, - "../../../node_modules/ini": { - "version": "2.0.0", "dev": true, - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "../../../node_modules/insert-css": { - "version": "0.2.0", - "license": "MIT" + "license": "ISC" }, "../../../node_modules/internal-slot": { "version": "1.0.6", @@ -7642,18 +5440,12 @@ "node": ">= 0.4" } }, - "../../../node_modules/interpret": { - "version": "3.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10.13.0" - } - }, "../../../node_modules/ip-address": { "version": "9.0.5", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "jsbn": "1.1.0", "sprintf-js": "^1.1.3" @@ -7665,15 +5457,9 @@ "../../../node_modules/ip-address/node_modules/jsbn": { "version": "1.1.0", "dev": true, - "license": "MIT" - }, - "../../../node_modules/ipaddr.js": { - "version": "2.1.0", - "dev": true, "license": "MIT", - "engines": { - "node": ">= 10" - } + "optional": true, + "peer": true }, "../../../node_modules/is-array-buffer": { "version": "3.0.2", @@ -7688,11 +5474,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "../../../node_modules/is-arrayish": { - "version": "0.2.1", - "dev": true, - "license": "MIT" - }, "../../../node_modules/is-bigint": { "version": "1.0.4", "dev": true, @@ -7704,17 +5485,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "../../../node_modules/is-binary-path": { - "version": "2.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, "../../../node_modules/is-boolean-object": { "version": "1.1.2", "dev": true, @@ -7747,6 +5517,7 @@ }, "../../../node_modules/is-core-module": { "version": "2.13.1", + "dev": true, "license": "MIT", "dependencies": { "hasown": "^2.0.0" @@ -7769,20 +5540,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "../../../node_modules/is-docker": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "../../../node_modules/is-extendable": { "version": "0.1.1", "license": "MIT", @@ -7816,49 +5573,6 @@ "node": ">=0.10.0" } }, - "../../../node_modules/is-inside-container": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "is-docker": "^3.0.0" - }, - "bin": { - "is-inside-container": "cli.js" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/is-installed-globally": { - "version": "0.4.0", - "dev": true, - "license": "MIT", - "dependencies": { - "global-dirs": "^3.0.0", - "is-path-inside": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/is-interactive": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "../../../node_modules/is-negative-zero": { "version": "2.0.2", "dev": true, @@ -7870,17 +5584,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "../../../node_modules/is-network-error": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "../../../node_modules/is-number": { "version": "7.0.0", "dev": true, @@ -7915,6 +5618,8 @@ "version": "4.1.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=12" }, @@ -7936,9 +5641,7 @@ "../../../node_modules/is-potential-custom-element-name": { "version": "1.0.1", "dev": true, - "license": "MIT", - "optional": true, - "peer": true + "license": "MIT" }, "../../../node_modules/is-regex": { "version": "1.1.4", @@ -8023,17 +5726,6 @@ "version": "1.0.0", "license": "MIT" }, - "../../../node_modules/is-unicode-supported": { - "version": "1.3.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "../../../node_modules/is-weakref": { "version": "1.0.2", "dev": true, @@ -8052,22 +5744,9 @@ "node": ">=0.10.0" } }, - "../../../node_modules/is-wsl": { - "version": "3.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "is-inside-container": "^1.0.0" - }, - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "../../../node_modules/isarray": { "version": "2.0.5", + "dev": true, "license": "MIT" }, "../../../node_modules/isexe": { @@ -8102,26 +5781,12 @@ "@pkgjs/parseargs": "^0.11.0" } }, - "../../../node_modules/jest-util": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, "../../../node_modules/jest-worker": { "version": "27.5.1", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@types/node": "*", "merge-stream": "^2.0.0", @@ -8135,6 +5800,8 @@ "version": "8.1.1", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -8163,11 +5830,6 @@ "node": ">=14" } }, - "../../../node_modules/js-tokens": { - "version": "4.0.0", - "dev": true, - "license": "MIT" - }, "../../../node_modules/js-yaml": { "version": "4.1.0", "dev": true, @@ -8187,8 +5849,6 @@ "version": "17.0.0", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "dependencies": { "abab": "^2.0.5", "acorn": "^8.4.1", @@ -8238,7 +5898,9 @@ "../../../node_modules/json-parse-even-better-errors": { "version": "2.3.1", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/json-schema": { "version": "0.4.0", @@ -8257,17 +5919,6 @@ "version": "5.0.1", "license": "ISC" }, - "../../../node_modules/json5": { - "version": "2.2.3", - "dev": true, - "license": "MIT", - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, "../../../node_modules/jsonc-parser": { "version": "3.2.1", "dev": true, @@ -8277,6 +5928,8 @@ "version": "6.1.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "universalify": "^2.0.0" }, @@ -8288,6 +5941,8 @@ "version": "2.0.1", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">= 10.0.0" } @@ -8327,6 +5982,8 @@ "version": "0.33.3", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=14.16" }, @@ -8334,19 +5991,12 @@ "url": "https://github.com/sindresorhus/ky?sponsor=1" } }, - "../../../node_modules/launch-editor": { - "version": "2.6.1", - "dev": true, - "license": "MIT", - "dependencies": { - "picocolors": "^1.0.0", - "shell-quote": "^1.8.1" - } - }, "../../../node_modules/lazystream": { "version": "1.0.1", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "readable-stream": "^2.0.5" }, @@ -8438,37 +6088,23 @@ "url": "https://opencollective.com/parcel" } }, - "../../../node_modules/lines-and-columns": { - "version": "1.2.4", - "dev": true, - "license": "MIT" - }, "../../../node_modules/listenercount": { "version": "1.0.1", "dev": true, - "license": "ISC" + "license": "ISC", + "optional": true, + "peer": true }, "../../../node_modules/loader-runner": { "version": "4.3.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=6.11.5" } }, - "../../../node_modules/loader-utils": { - "version": "2.0.4", - "dev": true, - "license": "MIT", - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - }, - "engines": { - "node": ">=8.9.0" - } - }, "../../../node_modules/local-pkg": { "version": "0.5.0", "dev": true, @@ -8488,6 +6124,8 @@ "version": "2.2.20", "dev": true, "license": "SEE LICENSE IN LICENSE", + "optional": true, + "peer": true, "dependencies": { "n12": "1.8.23", "type-fest": "2.13.0", @@ -8498,6 +6136,8 @@ "version": "2.13.0", "dev": true, "license": "(MIT OR CC0-1.0)", + "optional": true, + "peer": true, "engines": { "node": ">=12.20" }, @@ -8530,7 +6170,9 @@ "../../../node_modules/lodash.clonedeep": { "version": "4.5.0", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/lodash.merge": { "version": "4.6.2", @@ -8541,46 +6183,19 @@ "version": "4.7.0", "license": "MIT" }, - "../../../node_modules/lodash.truncate": { - "version": "4.4.2", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/lodash.zip": { - "version": "4.2.0", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/log-symbols": { - "version": "5.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^5.0.0", - "is-unicode-supported": "^1.1.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/log-symbols/node_modules/chalk": { - "version": "5.3.0", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, + "../../../node_modules/lodash.zip": { + "version": "4.2.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, "../../../node_modules/loglevel": { "version": "1.9.1", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">= 0.6.0" }, @@ -8592,7 +6207,9 @@ "../../../node_modules/loglevel-plugin-prefix": { "version": "0.8.4", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/loupe": { "version": "2.3.7", @@ -8602,18 +6219,12 @@ "get-func-name": "^2.0.1" } }, - "../../../node_modules/lower-case": { - "version": "2.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "tslib": "^2.0.3" - } - }, "../../../node_modules/lowercase-keys": { "version": "3.0.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, @@ -8639,48 +6250,6 @@ "node": ">=12" } }, - "../../../node_modules/media-typer": { - "version": "0.3.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "../../../node_modules/memfs": { - "version": "4.7.7", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.0.0" - }, - "engines": { - "node": ">= 4.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - } - }, - "../../../node_modules/merge-descriptors": { - "version": "1.0.1", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/merge-source-map": { - "version": "1.0.4", - "license": "MIT", - "dependencies": { - "source-map": "^0.5.6" - } - }, - "../../../node_modules/merge-source-map/node_modules/source-map": { - "version": "0.5.7", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, "../../../node_modules/merge-stream": { "version": "2.0.0", "dev": true, @@ -8694,14 +6263,6 @@ "node": ">= 8" } }, - "../../../node_modules/methods": { - "version": "1.1.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, "../../../node_modules/micromatch": { "version": "4.0.5", "dev": true, @@ -8714,17 +6275,6 @@ "node": ">=8.6" } }, - "../../../node_modules/mime": { - "version": "1.6.0", - "dev": true, - "license": "MIT", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, "../../../node_modules/mime-db": { "version": "1.52.0", "license": "MIT", @@ -8742,18 +6292,12 @@ "node": ">= 0.6" } }, - "../../../node_modules/mimic-fn": { - "version": "2.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "../../../node_modules/mimic-response": { "version": "4.0.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, @@ -8761,79 +6305,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "../../../node_modules/mini-css-extract-plugin": { - "version": "2.8.1", - "dev": true, - "license": "MIT", - "dependencies": { - "schema-utils": "^4.0.0", - "tapable": "^2.2.1" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.0.0" - } - }, - "../../../node_modules/mini-css-extract-plugin/node_modules/ajv": { - "version": "8.12.0", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "../../../node_modules/mini-css-extract-plugin/node_modules/ajv-keywords": { - "version": "5.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, - "../../../node_modules/mini-css-extract-plugin/node_modules/json-schema-traverse": { - "version": "1.0.0", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/mini-css-extract-plugin/node_modules/schema-utils": { - "version": "4.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.9.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.1.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "../../../node_modules/minimalistic-assert": { - "version": "1.0.1", - "dev": true, - "license": "ISC" - }, "../../../node_modules/minimatch": { "version": "9.0.3", "license": "ISC", @@ -8849,6 +6320,7 @@ }, "../../../node_modules/minimist": { "version": "1.2.8", + "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" @@ -8864,12 +6336,16 @@ "../../../node_modules/mitt": { "version": "3.0.0", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/mkdirp": { "version": "0.5.6", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "minimist": "^1.2.6" }, @@ -8901,22 +6377,12 @@ "dev": true, "license": "MIT" }, - "../../../node_modules/multicast-dns": { - "version": "7.2.5", - "dev": true, - "license": "MIT", - "dependencies": { - "dns-packet": "^5.2.2", - "thunky": "^1.0.2" - }, - "bin": { - "multicast-dns": "cli.js" - } - }, "../../../node_modules/n12": { "version": "1.8.23", "dev": true, - "license": "SEE LICENSE IN LICENSE" + "license": "SEE LICENSE IN LICENSE", + "optional": true, + "peer": true }, "../../../node_modules/nanoid": { "version": "3.3.7", @@ -8940,23 +6406,19 @@ "dev": true, "license": "MIT" }, - "../../../node_modules/negotiator": { - "version": "0.6.3", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, "../../../node_modules/neo-async": { "version": "2.6.2", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/netmask": { "version": "2.0.2", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">= 0.4.0" } @@ -8968,15 +6430,6 @@ "fflate": "*" } }, - "../../../node_modules/no-case": { - "version": "3.0.4", - "dev": true, - "license": "MIT", - "dependencies": { - "lower-case": "^2.0.2", - "tslib": "^2.0.3" - } - }, "../../../node_modules/node-domexception": { "version": "1.0.0", "dev": true, @@ -8991,6 +6444,8 @@ } ], "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=10.5.0" } @@ -8999,6 +6454,8 @@ "version": "3.3.2", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "data-uri-to-buffer": "^4.0.0", "fetch-blob": "^3.1.4", @@ -9012,18 +6469,12 @@ "url": "https://opencollective.com/node-fetch" } }, - "../../../node_modules/node-forge": { - "version": "1.3.1", - "dev": true, - "license": "(BSD-3-Clause OR GPL-2.0)", - "engines": { - "node": ">= 6.13.0" - } - }, "../../../node_modules/node-releases": { "version": "2.0.14", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/nopt": { "version": "7.2.0", @@ -9042,6 +6493,8 @@ "version": "3.0.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=0.10.0" } @@ -9050,6 +6503,8 @@ "version": "8.0.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=14.16" }, @@ -9057,28 +6512,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "../../../node_modules/npm-run-path": { - "version": "4.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "path-key": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "../../../node_modules/nth-check": { - "version": "2.1.1", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "boolbase": "^1.0.0" - }, - "funding": { - "url": "https://github.com/fb55/nth-check?sponsor=1" - } - }, "../../../node_modules/numcodecs": { "version": "0.3.1", "license": "MIT", @@ -9093,9 +6526,7 @@ "../../../node_modules/nwsapi": { "version": "2.2.7", "dev": true, - "license": "MIT", - "optional": true, - "peer": true + "license": "MIT" }, "../../../node_modules/oauth-sign": { "version": "0.9.0", @@ -9104,14 +6535,6 @@ "node": "*" } }, - "../../../node_modules/object-assign": { - "version": "4.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "../../../node_modules/object-inspect": { "version": "1.13.1", "dev": true, @@ -9188,30 +6611,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "../../../node_modules/obuf": { - "version": "1.1.2", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/on-finished": { - "version": "2.4.1", - "dev": true, - "license": "MIT", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "../../../node_modules/on-headers": { - "version": "1.0.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, "../../../node_modules/once": { "version": "1.4.0", "dev": true, @@ -9220,37 +6619,6 @@ "wrappy": "1" } }, - "../../../node_modules/onetime": { - "version": "5.1.2", - "dev": true, - "license": "MIT", - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/open": { - "version": "10.1.0", - "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" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "../../../node_modules/opener": { "version": "1.5.2", "dev": true, @@ -9275,68 +6643,12 @@ "node": ">= 0.8.0" } }, - "../../../node_modules/ora": { - "version": "6.3.1", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^5.0.0", - "cli-cursor": "^4.0.0", - "cli-spinners": "^2.6.1", - "is-interactive": "^2.0.0", - "is-unicode-supported": "^1.1.0", - "log-symbols": "^5.1.0", - "stdin-discarder": "^0.1.0", - "strip-ansi": "^7.0.1", - "wcwidth": "^1.0.1" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/ora/node_modules/ansi-regex": { - "version": "6.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "../../../node_modules/ora/node_modules/chalk": { - "version": "5.3.0", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "../../../node_modules/ora/node_modules/strip-ansi": { - "version": "7.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, "../../../node_modules/p-cancelable": { "version": "3.0.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=12.20" } @@ -9369,34 +6681,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "../../../node_modules/p-retry": { - "version": "6.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/retry": "0.12.2", - "is-network-error": "^1.0.0", - "retry": "^0.13.1" - }, - "engines": { - "node": ">=16.17" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/p-try": { - "version": "2.2.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "../../../node_modules/pac-proxy-agent": { "version": "7.0.1", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@tootallnate/quickjs-emscripten": "^0.23.0", "agent-base": "^7.0.2", @@ -9415,6 +6705,8 @@ "version": "7.1.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "debug": "^4.3.4" }, @@ -9426,6 +6718,8 @@ "version": "7.0.2", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "agent-base": "^7.1.0", "debug": "^4.3.4" @@ -9438,6 +6732,8 @@ "version": "7.0.4", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "agent-base": "^7.0.2", "debug": "4" @@ -9450,6 +6746,8 @@ "version": "7.0.1", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "degenerator": "^5.0.0", "netmask": "^2.0.2" @@ -9458,19 +6756,6 @@ "node": ">= 14" } }, - "../../../node_modules/pako": { - "version": "2.1.0", - "license": "(MIT AND Zlib)" - }, - "../../../node_modules/param-case": { - "version": "3.0.4", - "dev": true, - "license": "MIT", - "dependencies": { - "dot-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, "../../../node_modules/parent-module": { "version": "1.0.1", "dev": true, @@ -9482,46 +6767,10 @@ "node": ">=6" } }, - "../../../node_modules/parse-json": { - "version": "5.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "../../../node_modules/parse5": { "version": "6.0.1", "dev": true, - "license": "MIT", - "optional": true, - "peer": true - }, - "../../../node_modules/parseurl": { - "version": "1.3.3", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "../../../node_modules/pascal-case": { - "version": "3.1.2", - "dev": true, - "license": "MIT", - "dependencies": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } + "license": "MIT" }, "../../../node_modules/path-exists": { "version": "4.0.0", @@ -9548,6 +6797,7 @@ }, "../../../node_modules/path-parse": { "version": "1.0.7", + "dev": true, "license": "MIT" }, "../../../node_modules/path-scurry": { @@ -9564,19 +6814,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "../../../node_modules/path-to-regexp": { - "version": "0.1.7", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/path-type": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "../../../node_modules/pathe": { "version": "1.1.2", "dev": true, @@ -9616,96 +6853,6 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "../../../node_modules/pkg-dir": { - "version": "7.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "find-up": "^6.3.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/pkg-dir/node_modules/find-up": { - "version": "6.3.0", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^7.1.0", - "path-exists": "^5.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/pkg-dir/node_modules/locate-path": { - "version": "7.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^6.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/pkg-dir/node_modules/p-limit": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "yocto-queue": "^1.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/pkg-dir/node_modules/p-locate": { - "version": "6.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/pkg-dir/node_modules/path-exists": { - "version": "5.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - } - }, - "../../../node_modules/pkg-dir/node_modules/yocto-queue": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "../../../node_modules/pkg-types": { "version": "1.0.3", "dev": true, @@ -9854,15 +7001,6 @@ "node": ">=0.10.0" } }, - "../../../node_modules/pretty-error": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "lodash": "^4.17.20", - "renderkid": "^3.0.0" - } - }, "../../../node_modules/pretty-format": { "version": "29.7.0", "dev": true, @@ -9889,12 +7027,17 @@ }, "../../../node_modules/process-nextick-args": { "version": "2.0.1", - "license": "MIT" + "dev": true, + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/progress": { "version": "2.0.3", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=0.4.0" } @@ -9903,30 +7046,12 @@ "version": "1.2.4", "license": "ISC" }, - "../../../node_modules/proxy-addr": { - "version": "2.0.7", - "dev": true, - "license": "MIT", - "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "../../../node_modules/proxy-addr/node_modules/ipaddr.js": { - "version": "1.9.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.10" - } - }, "../../../node_modules/proxy-agent": { "version": "6.4.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "agent-base": "^7.0.2", "debug": "^4.3.4", @@ -9945,6 +7070,8 @@ "version": "7.1.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "debug": "^4.3.4" }, @@ -9956,6 +7083,8 @@ "version": "7.0.2", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "agent-base": "^7.1.0", "debug": "^4.3.4" @@ -9968,6 +7097,8 @@ "version": "7.0.4", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "agent-base": "^7.0.2", "debug": "4" @@ -9980,6 +7111,8 @@ "version": "7.18.3", "dev": true, "license": "ISC", + "optional": true, + "peer": true, "engines": { "node": ">=12" } @@ -9987,7 +7120,9 @@ "../../../node_modules/proxy-from-env": { "version": "1.1.0", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/psl": { "version": "1.9.0", @@ -9997,6 +7132,8 @@ "version": "3.0.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -10013,6 +7150,8 @@ "version": "20.9.0", "dev": true, "license": "Apache-2.0", + "optional": true, + "peer": true, "dependencies": { "@puppeteer/browsers": "1.4.6", "chromium-bidi": "0.4.16", @@ -10036,12 +7175,16 @@ "../../../node_modules/puppeteer-core/node_modules/devtools-protocol": { "version": "0.0.1147663", "dev": true, - "license": "BSD-3-Clause" + "license": "BSD-3-Clause", + "optional": true, + "peer": true }, "../../../node_modules/puppeteer-core/node_modules/ws": { "version": "8.13.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=10.0.0" }, @@ -10068,14 +7211,14 @@ "../../../node_modules/query-selector-shadow-dom": { "version": "1.0.1", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/querystringify": { "version": "2.2.0", "dev": true, - "license": "MIT", - "optional": true, - "peer": true + "license": "MIT" }, "../../../node_modules/queue-microtask": { "version": "1.2.3", @@ -10099,12 +7242,16 @@ "../../../node_modules/queue-tick": { "version": "1.0.1", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/quick-lru": { "version": "5.1.1", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=10" }, @@ -10112,64 +7259,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "../../../node_modules/quote-stream": { - "version": "1.0.2", - "license": "MIT", - "dependencies": { - "buffer-equal": "0.0.1", - "minimist": "^1.1.3", - "through2": "^2.0.0" - }, - "bin": { - "quote-stream": "bin/cmd.js" - } - }, - "../../../node_modules/quote-stream/node_modules/through2": { - "version": "2.0.5", - "license": "MIT", - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, "../../../node_modules/randombytes": { "version": "2.1.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "safe-buffer": "^5.1.0" } }, - "../../../node_modules/range-parser": { - "version": "1.2.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "../../../node_modules/raw-body": { - "version": "2.5.2", - "dev": true, - "license": "MIT", - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "../../../node_modules/raw-body/node_modules/bytes": { - "version": "3.1.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, "../../../node_modules/react-is": { "version": "18.2.0", "dev": true, @@ -10177,7 +7276,10 @@ }, "../../../node_modules/readable-stream": { "version": "2.3.8", + "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -10190,16 +7292,24 @@ }, "../../../node_modules/readable-stream/node_modules/isarray": { "version": "1.0.0", - "license": "MIT" + "dev": true, + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/readable-stream/node_modules/safe-buffer": { "version": "5.1.2", - "license": "MIT" + "dev": true, + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/readdir-glob": { "version": "1.1.3", "dev": true, "license": "Apache-2.0", + "optional": true, + "peer": true, "dependencies": { "minimatch": "^5.1.0" } @@ -10208,6 +7318,8 @@ "version": "5.1.6", "dev": true, "license": "ISC", + "optional": true, + "peer": true, "dependencies": { "brace-expansion": "^2.0.1" }, @@ -10215,28 +7327,6 @@ "node": ">=10" } }, - "../../../node_modules/readdirp": { - "version": "3.6.0", - "dev": true, - "license": "MIT", - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "../../../node_modules/rechoir": { - "version": "0.8.0", - "dev": true, - "license": "MIT", - "dependencies": { - "resolve": "^1.20.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, "../../../node_modules/regexp.prototype.flags": { "version": "1.5.1", "dev": true, @@ -10253,26 +7343,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "../../../node_modules/relateurl": { - "version": "0.2.7", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.10" - } - }, - "../../../node_modules/renderkid": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "css-select": "^4.1.3", - "dom-converter": "^0.2.0", - "htmlparser2": "^6.1.0", - "lodash": "^4.17.21", - "strip-ansi": "^6.0.1" - } - }, "../../../node_modules/request": { "version": "2.88.2", "license": "Apache-2.0", @@ -10372,14 +7442,6 @@ "node": ">=0.10.0" } }, - "../../../node_modules/require-from-string": { - "version": "2.0.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "../../../node_modules/requires-port": { "version": "1.0.0", "dev": true, @@ -10387,6 +7449,7 @@ }, "../../../node_modules/resolve": { "version": "1.22.8", + "dev": true, "license": "MIT", "dependencies": { "is-core-module": "^2.13.0", @@ -10403,26 +7466,9 @@ "../../../node_modules/resolve-alpn": { "version": "1.2.1", "dev": true, - "license": "MIT" - }, - "../../../node_modules/resolve-cwd": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "../../../node_modules/resolve-cwd/node_modules/resolve-from": { - "version": "5.0.0", - "dev": true, "license": "MIT", - "engines": { - "node": ">=8" - } + "optional": true, + "peer": true }, "../../../node_modules/resolve-from": { "version": "4.0.0", @@ -10444,6 +7490,8 @@ "version": "3.0.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "lowercase-keys": "^3.0.0" }, @@ -10458,6 +7506,8 @@ "version": "1.11.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "fast-deep-equal": "^2.0.1" } @@ -10465,35 +7515,9 @@ "../../../node_modules/resq/node_modules/fast-deep-equal": { "version": "2.0.1", "dev": true, - "license": "MIT" - }, - "../../../node_modules/restore-cursor": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/restore-cursor/node_modules/signal-exit": { - "version": "3.0.7", - "dev": true, - "license": "ISC" - }, - "../../../node_modules/retry": { - "version": "0.13.1", - "dev": true, "license": "MIT", - "engines": { - "node": ">= 4" - } + "optional": true, + "peer": true }, "../../../node_modules/reusify": { "version": "1.0.4", @@ -10507,7 +7531,9 @@ "../../../node_modules/rgb2hex": { "version": "0.2.5", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/rimraf": { "version": "3.0.2", @@ -10597,17 +7623,6 @@ "fsevents": "~2.3.2" } }, - "../../../node_modules/run-applescript": { - "version": "7.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "../../../node_modules/run-parallel": { "version": "1.2.0", "dev": true, @@ -10633,7 +7648,9 @@ "../../../node_modules/safaridriver": { "version": "0.1.2", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/safe-array-concat": { "version": "1.1.0", @@ -10698,8 +7715,6 @@ "version": "5.0.1", "dev": true, "license": "ISC", - "optional": true, - "peer": true, "dependencies": { "xmlchars": "^2.2.0" }, @@ -10711,6 +7726,8 @@ "version": "3.3.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@types/json-schema": "^7.0.8", "ajv": "^6.12.5", @@ -10724,23 +7741,6 @@ "url": "https://opencollective.com/webpack" } }, - "../../../node_modules/select-hose": { - "version": "2.0.0", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/selfsigned": { - "version": "2.4.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node-forge": "^1.3.0", - "node-forge": "^1" - }, - "engines": { - "node": ">=10" - } - }, "../../../node_modules/semver": { "version": "7.5.4", "license": "ISC", @@ -10751,164 +7751,43 @@ "semver": "bin/semver.js" }, "engines": { - "node": ">=10" - } - }, - "../../../node_modules/semver/node_modules/lru-cache": { - "version": "6.0.0", - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "../../../node_modules/send": { - "version": "0.18.0", - "dev": true, - "license": "MIT", - "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" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "../../../node_modules/send/node_modules/debug": { - "version": "2.6.9", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "../../../node_modules/send/node_modules/debug/node_modules/ms": { - "version": "2.0.0", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/send/node_modules/ms": { - "version": "2.1.3", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/serialize-error": { - "version": "11.0.3", - "dev": true, - "license": "MIT", - "dependencies": { - "type-fest": "^2.12.2" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/serialize-javascript": { - "version": "6.0.2", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "randombytes": "^2.1.0" - } - }, - "../../../node_modules/serve-index": { - "version": "1.9.1", - "dev": true, - "license": "MIT", - "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" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "../../../node_modules/serve-index/node_modules/debug": { - "version": "2.6.9", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "../../../node_modules/serve-index/node_modules/depd": { - "version": "1.1.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" + "node": ">=10" } }, - "../../../node_modules/serve-index/node_modules/http-errors": { - "version": "1.6.3", - "dev": true, - "license": "MIT", + "../../../node_modules/semver/node_modules/lru-cache": { + "version": "6.0.0", + "license": "ISC", "dependencies": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": ">= 1.4.0 < 2" + "yallist": "^4.0.0" }, "engines": { - "node": ">= 0.6" + "node": ">=10" } }, - "../../../node_modules/serve-index/node_modules/inherits": { - "version": "2.0.3", - "dev": true, - "license": "ISC" - }, - "../../../node_modules/serve-index/node_modules/ms": { - "version": "2.0.0", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/serve-index/node_modules/setprototypeof": { - "version": "1.1.0", - "dev": true, - "license": "ISC" - }, - "../../../node_modules/serve-index/node_modules/statuses": { - "version": "1.5.0", + "../../../node_modules/serialize-error": { + "version": "11.0.3", "dev": true, "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "type-fest": "^2.12.2" + }, "engines": { - "node": ">= 0.6" + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "../../../node_modules/serve-static": { - "version": "1.15.0", + "../../../node_modules/serialize-javascript": { + "version": "6.0.2", "dev": true, - "license": "MIT", + "license": "BSD-3-Clause", + "optional": true, + "peer": true, "dependencies": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.18.0" - }, - "engines": { - "node": ">= 0.8.0" + "randombytes": "^2.1.0" } }, "../../../node_modules/set-function-length": { @@ -10942,12 +7821,9 @@ "../../../node_modules/setimmediate": { "version": "1.0.5", "dev": true, - "license": "MIT" - }, - "../../../node_modules/setprototypeof": { - "version": "1.2.0", - "dev": true, - "license": "ISC" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/shallow-clone": { "version": "3.0.1", @@ -10968,10 +7844,6 @@ "node": ">=0.10.0" } }, - "../../../node_modules/shallow-copy": { - "version": "0.0.1", - "license": "MIT" - }, "../../../node_modules/shebang-command": { "version": "2.0.0", "license": "MIT", @@ -10989,14 +7861,6 @@ "node": ">=8" } }, - "../../../node_modules/shell-quote": { - "version": "1.8.1", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "../../../node_modules/side-channel": { "version": "1.0.4", "dev": true, @@ -11025,11 +7889,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "../../../node_modules/simple-html-tokenizer": { - "version": "0.1.1", - "dev": true, - "license": "MIT" - }, "../../../node_modules/sirv": { "version": "2.0.4", "dev": true, @@ -11043,61 +7902,23 @@ "node": ">= 10" } }, - "../../../node_modules/slash": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "../../../node_modules/slice-ansi": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" - } - }, "../../../node_modules/smart-buffer": { "version": "4.2.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">= 6.0.0", "npm": ">= 3.0.0" } }, - "../../../node_modules/sockjs": { - "version": "0.3.24", - "dev": true, - "license": "MIT", - "dependencies": { - "faye-websocket": "^0.11.3", - "uuid": "^8.3.2", - "websocket-driver": "^0.7.4" - } - }, - "../../../node_modules/sockjs/node_modules/uuid": { - "version": "8.3.2", - "dev": true, - "license": "MIT", - "bin": { - "uuid": "dist/bin/uuid" - } - }, "../../../node_modules/socks": { "version": "2.7.3", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "ip-address": "^9.0.5", "smart-buffer": "^4.2.0" @@ -11111,6 +7932,8 @@ "version": "8.0.2", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "agent-base": "^7.0.2", "debug": "^4.3.4", @@ -11124,6 +7947,8 @@ "version": "7.1.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "debug": "^4.3.4" }, @@ -11131,15 +7956,10 @@ "node": ">= 14" } }, - "../../../node_modules/source-list-map": { - "version": "2.0.1", - "dev": true, - "license": "MIT" - }, "../../../node_modules/source-map": { "version": "0.6.1", - "devOptional": true, "license": "BSD-3-Clause", + "optional": true, "engines": { "node": ">=0.10.0" } @@ -11157,56 +7977,19 @@ "version": "0.5.21", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" } }, - "../../../node_modules/spdy": { - "version": "4.0.2", - "dev": true, - "license": "MIT", - "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" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "../../../node_modules/spdy-transport": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "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_modules/spdy-transport/node_modules/readable-stream": { - "version": "3.6.2", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "../../../node_modules/split2": { "version": "4.2.0", "dev": true, "license": "ISC", + "optional": true, + "peer": true, "engines": { "node": ">= 10.x" } @@ -11214,189 +7997,43 @@ "../../../node_modules/sprintf-js": { "version": "1.1.3", "dev": true, - "license": "BSD-3-Clause" + "license": "BSD-3-Clause", + "optional": true, + "peer": true }, "../../../node_modules/sshpk": { "version": "1.18.0", "license": "MIT", "dependencies": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "bin": { - "sshpk-conv": "bin/sshpk-conv", - "sshpk-sign": "bin/sshpk-sign", - "sshpk-verify": "bin/sshpk-verify" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "../../../node_modules/stackback": { - "version": "0.0.2", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/static-eval": { - "version": "2.1.1", - "license": "MIT", - "dependencies": { - "escodegen": "^2.1.0" - } - }, - "../../../node_modules/static-module": { - "version": "2.2.5", - "license": "MIT", - "dependencies": { - "concat-stream": "~1.6.0", - "convert-source-map": "^1.5.1", - "duplexer2": "~0.1.4", - "escodegen": "~1.9.0", - "falafel": "^2.1.0", - "has": "^1.0.1", - "magic-string": "^0.22.4", - "merge-source-map": "1.0.4", - "object-inspect": "~1.4.0", - "quote-stream": "~1.0.2", - "readable-stream": "~2.3.3", - "shallow-copy": "~0.0.1", - "static-eval": "^2.0.0", - "through2": "~2.0.3" - } - }, - "../../../node_modules/static-module/node_modules/escodegen": { - "version": "1.9.1", - "license": "BSD-2-Clause", - "dependencies": { - "esprima": "^3.1.3", - "estraverse": "^4.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1" - }, - "bin": { - "escodegen": "bin/escodegen.js", - "esgenerate": "bin/esgenerate.js" - }, - "engines": { - "node": ">=4.0" - }, - "optionalDependencies": { - "source-map": "~0.6.1" - } - }, - "../../../node_modules/static-module/node_modules/esprima": { - "version": "3.1.3", - "license": "BSD-2-Clause", - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "../../../node_modules/static-module/node_modules/estraverse": { - "version": "4.3.0", - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, - "../../../node_modules/static-module/node_modules/levn": { - "version": "0.3.0", - "license": "MIT", - "dependencies": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "../../../node_modules/static-module/node_modules/magic-string": { - "version": "0.22.5", - "license": "MIT", - "dependencies": { - "vlq": "^0.2.2" - } - }, - "../../../node_modules/static-module/node_modules/object-inspect": { - "version": "1.4.1", - "license": "MIT" - }, - "../../../node_modules/static-module/node_modules/optionator": { - "version": "0.8.3", - "license": "MIT", - "dependencies": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "../../../node_modules/static-module/node_modules/prelude-ls": { - "version": "1.1.2", - "engines": { - "node": ">= 0.8.0" - } - }, - "../../../node_modules/static-module/node_modules/through2": { - "version": "2.0.5", - "license": "MIT", - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "../../../node_modules/static-module/node_modules/type-check": { - "version": "0.3.2", - "license": "MIT", - "dependencies": { - "prelude-ls": "~1.1.2" + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" }, "engines": { - "node": ">= 0.8.0" + "node": ">=0.10.0" } }, - "../../../node_modules/statuses": { - "version": "2.0.1", + "../../../node_modules/stackback": { + "version": "0.0.2", "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } + "license": "MIT" }, "../../../node_modules/std-env": { "version": "3.7.0", "dev": true, "license": "MIT" }, - "../../../node_modules/stdin-discarder": { - "version": "0.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "bl": "^5.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "../../../node_modules/stealthy-require": { "version": "1.1.1", "license": "ISC", @@ -11408,6 +8045,8 @@ "version": "2.15.6", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "fast-fifo": "^1.1.0", "queue-tick": "^1.0.1" @@ -11415,14 +8054,20 @@ }, "../../../node_modules/string_decoder": { "version": "1.1.1", + "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "safe-buffer": "~5.1.0" } }, "../../../node_modules/string_decoder/node_modules/safe-buffer": { "version": "5.1.2", - "license": "MIT" + "dev": true, + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/string-width": { "version": "5.1.2", @@ -11588,21 +8233,6 @@ "dev": true, "license": "MIT" }, - "../../../node_modules/style-loader": { - "version": "3.3.4", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.0.0" - } - }, "../../../node_modules/supports-color": { "version": "7.2.0", "dev": true, @@ -11614,20 +8244,9 @@ "node": ">=8" } }, - "../../../node_modules/supports-hyperlinks": { - "version": "2.3.0", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0", - "supports-color": "^7.0.0" - }, - "engines": { - "node": ">=8" - } - }, "../../../node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -11636,97 +8255,10 @@ "url": "https://github.com/sponsors/ljharb" } }, - "../../../node_modules/svg-inline-loader": { - "version": "0.8.2", - "dev": true, - "license": "MIT", - "dependencies": { - "loader-utils": "^1.1.0", - "object-assign": "^4.0.1", - "simple-html-tokenizer": "^0.1.1" - } - }, - "../../../node_modules/svg-inline-loader/node_modules/json5": { - "version": "1.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" - } - }, - "../../../node_modules/svg-inline-loader/node_modules/loader-utils": { - "version": "1.4.2", - "dev": true, - "license": "MIT", - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - }, - "engines": { - "node": ">=4.0.0" - } - }, "../../../node_modules/symbol-tree": { "version": "3.2.4", "license": "MIT" }, - "../../../node_modules/table": { - "version": "6.8.1", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "ajv": "^8.0.1", - "lodash.truncate": "^4.4.2", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "../../../node_modules/table/node_modules/ajv": { - "version": "8.12.0", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "../../../node_modules/table/node_modules/emoji-regex": { - "version": "8.0.0", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/table/node_modules/json-schema-traverse": { - "version": "1.0.0", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/table/node_modules/string-width": { - "version": "4.2.3", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, "../../../node_modules/tapable": { "version": "2.2.1", "dev": true, @@ -11739,6 +8271,8 @@ "version": "3.0.5", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "pump": "^3.0.0", "tar-stream": "^3.1.5" @@ -11752,31 +8286,20 @@ "version": "3.1.7", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "b4a": "^1.6.4", "fast-fifo": "^1.2.0", "streamx": "^2.15.0" } }, - "../../../node_modules/terminal-link": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-escapes": "^5.0.0", - "supports-hyperlinks": "^2.2.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "../../../node_modules/terser": { "version": "5.29.1", "dev": true, "license": "BSD-2-Clause", + "optional": true, + "peer": true, "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.8.2", @@ -11794,6 +8317,8 @@ "version": "5.3.10", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@jridgewell/trace-mapping": "^0.3.20", "jest-worker": "^27.4.5", @@ -11826,7 +8351,9 @@ "../../../node_modules/terser/node_modules/commander": { "version": "2.20.3", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/text-table": { "version": "0.2.0", @@ -11836,38 +8363,9 @@ "../../../node_modules/through": { "version": "2.3.8", "dev": true, - "license": "MIT" - }, - "../../../node_modules/through2": { - "version": "0.6.5", "license": "MIT", - "dependencies": { - "readable-stream": ">=1.0.33-1 <1.1.0-0", - "xtend": ">=4.0.0 <4.1.0-0" - } - }, - "../../../node_modules/through2/node_modules/isarray": { - "version": "0.0.1", - "license": "MIT" - }, - "../../../node_modules/through2/node_modules/readable-stream": { - "version": "1.0.34", - "license": "MIT", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "../../../node_modules/through2/node_modules/string_decoder": { - "version": "0.10.31", - "license": "MIT" - }, - "../../../node_modules/thunky": { - "version": "1.1.0", - "dev": true, - "license": "MIT" + "optional": true, + "peer": true }, "../../../node_modules/tinybench": { "version": "2.6.0", @@ -11901,14 +8399,6 @@ "node": ">=8.0" } }, - "../../../node_modules/toidentifier": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.6" - } - }, "../../../node_modules/totalist": { "version": "3.0.1", "dev": true, @@ -11921,8 +8411,6 @@ "version": "4.1.3", "dev": true, "license": "BSD-3-Clause", - "optional": true, - "peer": true, "dependencies": { "psl": "^1.1.33", "punycode": "^2.1.1", @@ -11937,8 +8425,6 @@ "version": "2.1.0", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "dependencies": { "punycode": "^2.1.1" }, @@ -11949,18 +8435,9 @@ "../../../node_modules/traverse": { "version": "0.3.9", "dev": true, - "license": "MIT/X11" - }, - "../../../node_modules/ts-api-utils": { - "version": "1.2.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=16" - }, - "peerDependencies": { - "typescript": ">=4.2.0" - } + "license": "MIT/X11", + "optional": true, + "peer": true }, "../../../node_modules/tsconfig-paths": { "version": "3.15.0", @@ -11987,7 +8464,9 @@ "../../../node_modules/tslib": { "version": "2.6.2", "dev": true, - "license": "0BSD" + "license": "0BSD", + "optional": true, + "peer": true }, "../../../node_modules/tsx": { "version": "4.7.1", @@ -12448,6 +8927,8 @@ "version": "2.19.0", "dev": true, "license": "(MIT OR CC0-1.0)", + "optional": true, + "peer": true, "engines": { "node": ">=12.20" }, @@ -12455,18 +8936,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "../../../node_modules/type-is": { - "version": "1.6.18", - "dev": true, - "license": "MIT", - "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - }, - "engines": { - "node": ">= 0.6" - } - }, "../../../node_modules/typed-array-buffer": { "version": "1.0.0", "dev": true, @@ -12528,10 +8997,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "../../../node_modules/typedarray": { - "version": "0.0.6", - "license": "MIT" - }, "../../../node_modules/typescript": { "version": "5.3.3", "dev": true, @@ -12567,6 +9032,8 @@ "version": "1.4.3", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "buffer": "^5.2.1", "through": "^2.3.8" @@ -12590,6 +9057,8 @@ } ], "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" @@ -12604,24 +9073,16 @@ "version": "0.2.0", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "engines": { "node": ">= 4.0.0" } }, - "../../../node_modules/unpipe": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, "../../../node_modules/unzipper": { "version": "0.10.14", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "big-integer": "^1.6.17", "binary": "~0.3.0", @@ -12653,6 +9114,8 @@ } ], "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "escalade": "^3.1.1", "picocolors": "^1.0.0" @@ -12675,8 +9138,6 @@ "version": "1.5.10", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "dependencies": { "querystringify": "^2.1.1", "requires-port": "^1.0.0" @@ -12685,40 +9146,22 @@ "../../../node_modules/userhome": { "version": "1.0.0", "dev": true, + "optional": true, + "peer": true, "engines": { "node": ">= 0.8.0" } }, "../../../node_modules/util-deprecate": { "version": "1.0.2", - "license": "MIT" - }, - "../../../node_modules/utila": { - "version": "0.4.0", "dev": true, "license": "MIT" }, - "../../../node_modules/utils-merge": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4.0" - } - }, "../../../node_modules/uuid": { "version": "3.4.0", - "license": "MIT", - "bin": { - "uuid": "bin/uuid" - } - }, - "../../../node_modules/vary": { - "version": "1.1.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" + "license": "MIT", + "bin": { + "uuid": "bin/uuid" } }, "../../../node_modules/verror": { @@ -12939,10 +9382,6 @@ "node": ">=0.4.0" } }, - "../../../node_modules/vlq": { - "version": "0.2.3", - "license": "MIT" - }, "../../../node_modules/w3c-hr-time": { "version": "1.0.2", "license": "MIT", @@ -12954,8 +9393,6 @@ "version": "2.0.0", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "dependencies": { "xml-name-validator": "^3.0.0" }, @@ -12967,6 +9404,8 @@ "version": "1.1.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "chalk": "^4.1.2", "commander": "^9.3.0", @@ -12983,6 +9422,8 @@ "version": "2.4.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.1.2" @@ -12991,26 +9432,12 @@ "node": ">=10.13.0" } }, - "../../../node_modules/wbuf": { - "version": "1.7.3", - "dev": true, - "license": "MIT", - "dependencies": { - "minimalistic-assert": "^1.0.0" - } - }, - "../../../node_modules/wcwidth": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "defaults": "^1.0.3" - } - }, "../../../node_modules/web-streams-polyfill": { "version": "3.3.3", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">= 8" } @@ -13019,6 +9446,8 @@ "version": "8.32.3", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@types/node": "^20.1.0", "@types/ws": "^8.5.3", @@ -13040,6 +9469,8 @@ "version": "8.32.3", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@types/node": "^20.1.0", "@wdio/config": "8.32.3", @@ -13082,8 +9513,6 @@ "version": "6.1.0", "dev": true, "license": "BSD-2-Clause", - "optional": true, - "peer": true, "engines": { "node": ">=10.4" } @@ -13092,6 +9521,8 @@ "version": "5.90.3", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@types/eslint-scope": "^3.7.3", "@types/estree": "^1.0.5", @@ -13204,260 +9635,6 @@ } } }, - "../../../node_modules/webpack-cli": { - "version": "5.1.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@discoveryjs/json-ext": "^0.5.0", - "@webpack-cli/configtest": "^2.1.1", - "@webpack-cli/info": "^2.0.2", - "@webpack-cli/serve": "^2.0.5", - "colorette": "^2.0.14", - "commander": "^10.0.1", - "cross-spawn": "^7.0.3", - "envinfo": "^7.7.3", - "fastest-levenshtein": "^1.0.12", - "import-local": "^3.0.2", - "interpret": "^3.1.1", - "rechoir": "^0.8.0", - "webpack-merge": "^5.7.3" - }, - "bin": { - "webpack-cli": "bin/cli.js" - }, - "engines": { - "node": ">=14.15.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "5.x.x" - }, - "peerDependenciesMeta": { - "@webpack-cli/generators": { - "optional": true - }, - "webpack-bundle-analyzer": { - "optional": true - }, - "webpack-dev-server": { - "optional": true - } - } - }, - "../../../node_modules/webpack-cli/node_modules/commander": { - "version": "10.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14" - } - }, - "../../../node_modules/webpack-dev-middleware": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-7.1.1.tgz", - "integrity": "sha512-NmRVq4AvRQs66dFWyDR4GsFDJggtSi2Yn38MXLk0nffgF9n/AIP4TFBg2TQKYaRAN4sHuKOTiz9BnNCENDLEVA==", - "dev": true, - "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" - }, - "engines": { - "node": ">= 18.12.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.0.0" - }, - "peerDependenciesMeta": { - "webpack": { - "optional": true - } - } - }, - "../../../node_modules/webpack-dev-middleware/node_modules/ajv": { - "version": "8.12.0", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "../../../node_modules/webpack-dev-middleware/node_modules/ajv-keywords": { - "version": "5.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, - "../../../node_modules/webpack-dev-middleware/node_modules/json-schema-traverse": { - "version": "1.0.0", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/webpack-dev-middleware/node_modules/schema-utils": { - "version": "4.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.9.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.1.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "../../../node_modules/webpack-dev-server": { - "version": "5.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/bonjour": "^3.5.13", - "@types/connect-history-api-fallback": "^1.5.4", - "@types/express": "^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", - "default-gateway": "^6.0.3", - "express": "^4.17.3", - "graceful-fs": "^4.2.6", - "html-entities": "^2.4.0", - "http-proxy-middleware": "^2.0.3", - "ipaddr.js": "^2.1.0", - "launch-editor": "^2.6.1", - "open": "^10.0.3", - "p-retry": "^6.2.0", - "rimraf": "^5.0.5", - "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.0.0", - "ws": "^8.16.0" - }, - "bin": { - "webpack-dev-server": "bin/webpack-dev-server.js" - }, - "engines": { - "node": ">= 18.12.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.0.0" - }, - "peerDependenciesMeta": { - "webpack": { - "optional": true - }, - "webpack-cli": { - "optional": true - } - } - }, - "../../../node_modules/webpack-dev-server/node_modules/ajv": { - "version": "8.12.0", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "../../../node_modules/webpack-dev-server/node_modules/ajv-keywords": { - "version": "5.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, - "../../../node_modules/webpack-dev-server/node_modules/json-schema-traverse": { - "version": "1.0.0", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/webpack-dev-server/node_modules/rimraf": { - "version": "5.0.5", - "dev": true, - "license": "ISC", - "dependencies": { - "glob": "^10.3.7" - }, - "bin": { - "rimraf": "dist/esm/bin.mjs" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "../../../node_modules/webpack-dev-server/node_modules/schema-utils": { - "version": "4.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.9.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.1.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, "../../../node_modules/webpack-merge": { "version": "5.10.0", "dev": true, @@ -13471,19 +9648,12 @@ "node": ">=10.0.0" } }, - "../../../node_modules/webpack-sources": { - "version": "1.4.3", - "dev": true, - "license": "MIT", - "dependencies": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" - } - }, "../../../node_modules/webpack/node_modules/eslint-scope": { "version": "5.1.1", "dev": true, "license": "BSD-2-Clause", + "optional": true, + "peer": true, "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^4.1.1" @@ -13496,6 +9666,8 @@ "version": "4.3.0", "dev": true, "license": "BSD-2-Clause", + "optional": true, + "peer": true, "engines": { "node": ">=4.0" } @@ -13504,6 +9676,8 @@ "version": "3.3.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=0.8.x" } @@ -13512,31 +9686,12 @@ "version": "3.2.3", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=10.13.0" } }, - "../../../node_modules/websocket-driver": { - "version": "0.7.4", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "http-parser-js": ">=0.5.1", - "safe-buffer": ">=5.1.0", - "websocket-extensions": ">=0.1.1" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "../../../node_modules/websocket-extensions": { - "version": "0.1.4", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=0.8.0" - } - }, "../../../node_modules/whatwg-encoding": { "version": "1.0.5", "license": "MIT", @@ -13552,8 +9707,6 @@ "version": "9.1.0", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "dependencies": { "tr46": "^2.1.0", "webidl-conversions": "^6.1.0" @@ -13623,20 +9776,6 @@ "node": ">=8" } }, - "../../../node_modules/widest-line": { - "version": "4.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "string-width": "^5.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "../../../node_modules/wildcard": { "version": "2.0.1", "dev": true, @@ -13761,9 +9900,7 @@ "../../../node_modules/xmlchars": { "version": "2.2.0", "dev": true, - "license": "MIT", - "optional": true, - "peer": true + "license": "MIT" }, "../../../node_modules/xmldom": { "version": "0.1.31", @@ -13772,13 +9909,6 @@ "node": ">=0.1" } }, - "../../../node_modules/xtend": { - "version": "4.0.2", - "license": "MIT", - "engines": { - "node": ">=0.4" - } - }, "../../../node_modules/y18n": { "version": "5.0.8", "dev": true, @@ -13791,14 +9921,6 @@ "version": "4.0.0", "license": "ISC" }, - "../../../node_modules/yaml": { - "version": "1.10.2", - "dev": true, - "license": "ISC", - "engines": { - "node": ">= 6" - } - }, "../../../node_modules/yargs": { "version": "17.7.2", "dev": true, @@ -13866,6 +9988,8 @@ "version": "5.0.1", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "archiver-utils": "^4.0.1", "compress-commons": "^5.0.1", @@ -13879,6 +10003,8 @@ "version": "3.6.2", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", diff --git a/examples/rsbuild/rsbuild-project-built/.gitignore b/examples/rsbuild/rsbuild-project-built/.gitignore new file mode 100644 index 0000000000..b0a5c349ca --- /dev/null +++ b/examples/rsbuild/rsbuild-project-built/.gitignore @@ -0,0 +1,2 @@ +/node_modules/ +/dist/ diff --git a/examples/rsbuild/rsbuild-project-built/README.md b/examples/rsbuild/rsbuild-project-built/README.md new file mode 100644 index 0000000000..be1275aabe --- /dev/null +++ b/examples/rsbuild/rsbuild-project-built/README.md @@ -0,0 +1 @@ +This demonstrates a dependent project that uses rsbuild for building. diff --git a/examples/rsbuild/rsbuild-project-built/package-lock.json b/examples/rsbuild/rsbuild-project-built/package-lock.json new file mode 100644 index 0000000000..3c908105d8 --- /dev/null +++ b/examples/rsbuild/rsbuild-project-built/package-lock.json @@ -0,0 +1,306 @@ +{ + "name": "neuroglancer-rsbuild-project-built", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "neuroglancer-rsbuild-project-built", + "version": "0.0.0", + "license": "Apache-2.0", + "dependencies": { + "neuroglancer": "file:../../../dist/package" + }, + "devDependencies": { + "@rsbuild/core": "^1.1.9" + } + }, + "../../../dist/package": { + "name": "neuroglancer", + "version": "2.40.1", + "license": "Apache-2.0", + "dependencies": { + "codemirror": "^5.61.1", + "core-js": "^3.40.0", + "crc-32": "^1.2.2", + "gl-matrix": "3.1.0", + "ikonate": "github:mikolajdobrucki/ikonate#a86b4107c6ec717e7877f880a930d1ccf0b59d89", + "lodash-es": "^4.17.21", + "nifti-reader-js": "^0.6.8", + "numcodecs": "^0.3.2" + }, + "engines": { + "node": ">=22" + } + }, + "node_modules/@module-federation/runtime": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@module-federation/runtime/-/runtime-0.5.1.tgz", + "integrity": "sha512-xgiMUWwGLWDrvZc9JibuEbXIbhXg6z2oUkemogSvQ4LKvrl/n0kbqP1Blk669mXzyWbqtSp6PpvNdwaE1aN5xQ==", + "dev": true, + "dependencies": { + "@module-federation/sdk": "0.5.1" + } + }, + "node_modules/@module-federation/runtime-tools": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@module-federation/runtime-tools/-/runtime-tools-0.5.1.tgz", + "integrity": "sha512-nfBedkoZ3/SWyO0hnmaxuz0R0iGPSikHZOAZ0N/dVSQaIzlffUo35B5nlC2wgWIc0JdMZfkwkjZRrnuuDIJbzg==", + "dev": true, + "dependencies": { + "@module-federation/runtime": "0.5.1", + "@module-federation/webpack-bundler-runtime": "0.5.1" + } + }, + "node_modules/@module-federation/sdk": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@module-federation/sdk/-/sdk-0.5.1.tgz", + "integrity": "sha512-exvchtjNURJJkpqjQ3/opdbfeT2wPKvrbnGnyRkrwW5o3FH1LaST1tkiNviT6OXTexGaVc2DahbdniQHVtQ7pA==", + "dev": true + }, + "node_modules/@module-federation/webpack-bundler-runtime": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@module-federation/webpack-bundler-runtime/-/webpack-bundler-runtime-0.5.1.tgz", + "integrity": "sha512-mMhRFH0k2VjwHt3Jol9JkUsmI/4XlrAoBG3E0o7HoyoPYv1UFOWyqAflfANcUPgbYpvqmyLzDcO+3IT36LXnrA==", + "dev": true, + "dependencies": { + "@module-federation/runtime": "0.5.1", + "@module-federation/sdk": "0.5.1" + } + }, + "node_modules/@rsbuild/core": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@rsbuild/core/-/core-1.1.9.tgz", + "integrity": "sha512-mHZveEwlTtW9nxWa+T0xUm6ssm+HkDYZ0NENLfWMUmsL0LjMJrpQzRlbD+p5+9Uf+KXUo3Dbtv0ScA+p7cuGTg==", + "dev": true, + "dependencies": { + "@rspack/core": "~1.1.5", + "@rspack/lite-tapable": "~1.0.1", + "@swc/helpers": "^0.5.15", + "core-js": "~3.39.0" + }, + "bin": { + "rsbuild": "bin/rsbuild.js" + }, + "engines": { + "node": ">=16.7.0" + } + }, + "node_modules/@rspack/binding": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@rspack/binding/-/binding-1.1.6.tgz", + "integrity": "sha512-vfeBEgGOYVwqj5cQjGyvdfrr/BEihAHlyIsobL98FZjTF0uig+bj2yJUH5Ib5F0BpIUKVG3Pw0IjlUBqcVpZsQ==", + "dev": true, + "optionalDependencies": { + "@rspack/binding-darwin-arm64": "1.1.6", + "@rspack/binding-darwin-x64": "1.1.6", + "@rspack/binding-linux-arm64-gnu": "1.1.6", + "@rspack/binding-linux-arm64-musl": "1.1.6", + "@rspack/binding-linux-x64-gnu": "1.1.6", + "@rspack/binding-linux-x64-musl": "1.1.6", + "@rspack/binding-win32-arm64-msvc": "1.1.6", + "@rspack/binding-win32-ia32-msvc": "1.1.6", + "@rspack/binding-win32-x64-msvc": "1.1.6" + } + }, + "node_modules/@rspack/binding-darwin-arm64": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@rspack/binding-darwin-arm64/-/binding-darwin-arm64-1.1.6.tgz", + "integrity": "sha512-x9dxm2yyiMuL1FBwvWNNMs2/mEUJmRoSRgYb8pblR7HDaTRORrjBFCqhaYlGyAqtQaeUy7o2VAQlE0BavIiFYA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rspack/binding-darwin-x64": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@rspack/binding-darwin-x64/-/binding-darwin-x64-1.1.6.tgz", + "integrity": "sha512-o0seilveftGiDjy3VPxug20HmAgYyQbNEuagR3i93/t/PT/eWXHnik+C1jjwqcivZL1Zllqvy4tbZw393aROEQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rspack/binding-linux-arm64-gnu": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@rspack/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.1.6.tgz", + "integrity": "sha512-4atnoknJx/c3KaQElsMIxHMpPf2jcRRdWsH/SdqJIRSrkWWakMK9Yv4TFwH680I4HDTMf1XLboMVScHzW8e+Mg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rspack/binding-linux-arm64-musl": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@rspack/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.1.6.tgz", + "integrity": "sha512-7QMtwUtgFpt3/Y3/X18fSyN+kk4H8ZnZ8tDzQskVWc/j2AQYShZq56XQYqrhClzwujcCVAHauIQ2eiuJ2ASGag==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rspack/binding-linux-x64-gnu": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@rspack/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.1.6.tgz", + "integrity": "sha512-MTjDEfPn4TwHoqs5d5Fck06kmXiTHZctGIcRVfrpg0RK0r1NLEHN+oosavRZ9c9H70f34+NmcHk+/qvV4c8lWg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rspack/binding-linux-x64-musl": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@rspack/binding-linux-x64-musl/-/binding-linux-x64-musl-1.1.6.tgz", + "integrity": "sha512-LqDw7PTVr/4ZuGA0izgDQfamfr72USFHltR1Qhy2YVC3JmDmhG/pQi13LHcOLVaGH1xoeyCmEPNJpVizzDxSjg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rspack/binding-win32-arm64-msvc": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@rspack/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.1.6.tgz", + "integrity": "sha512-RHApLM93YN0WdHpS35u2cm7VCqZ8Yg3CrNRL16VJtyT9e6MBqeScoe4XIgIWKPm7edFyedYAjLX0wQOApwfjkg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rspack/binding-win32-ia32-msvc": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@rspack/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-1.1.6.tgz", + "integrity": "sha512-Y6lx4q0eJawRfMPBo/AclTJAPTZ325DSPFBQJB3TnWh9Z2X7P7pQcYc8PHDmfDuYRIdg5WRsQRvVxihSvF7v8w==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rspack/binding-win32-x64-msvc": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@rspack/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.1.6.tgz", + "integrity": "sha512-UuCsfhC/yNuU7xLASOxNXcmsXi2ZvBX14GkxvcdChw6q7IIGNYUKXo1zgR8C1PE/6qDSxmLxbRMS+71d0H3HQg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rspack/core": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@rspack/core/-/core-1.1.6.tgz", + "integrity": "sha512-q0VLphOF5VW2FEG7Vbdq3Ke4I74FbELE/8xmKghSalFtULLZ44SoSz8lyotfMim9GXIRFhDokAaH8WICmPxG+g==", + "dev": true, + "dependencies": { + "@module-federation/runtime-tools": "0.5.1", + "@rspack/binding": "1.1.6", + "@rspack/lite-tapable": "1.0.1", + "caniuse-lite": "^1.0.30001616" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@swc/helpers": ">=0.5.1" + }, + "peerDependenciesMeta": { + "@swc/helpers": { + "optional": true + } + } + }, + "node_modules/@rspack/lite-tapable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@rspack/lite-tapable/-/lite-tapable-1.0.1.tgz", + "integrity": "sha512-VynGOEsVw2s8TAlLf/uESfrgfrq2+rcXB1muPJYBWbsm1Oa6r5qVQhjA5ggM6z/coYPrsVMgovl3Ff7Q7OCp1w==", + "dev": true, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@swc/helpers": { + "version": "0.5.15", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz", + "integrity": "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==", + "dev": true, + "dependencies": { + "tslib": "^2.8.0" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001687", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001687.tgz", + "integrity": "sha512-0S/FDhf4ZiqrTUiQ39dKeUjYRjkv7lOZU1Dgif2rIqrTzX/1wV2hfKu9TOm1IHkdSijfLswxTFzl/cvir+SLSQ==", + "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/core-js": { + "version": "3.39.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.39.0.tgz", + "integrity": "sha512-raM0ew0/jJUqkJ0E6e8UDtl+y/7ktFivgWvqw8dNSQeNWoSDLvQ1H/RN3aPXB9tBd4/FhyR4RDPGhsNIMsAn7g==", + "dev": true, + "hasInstallScript": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/neuroglancer": { + "resolved": "../../../dist/package", + "link": true + }, + "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==", + "dev": true + } + } +} diff --git a/examples/rsbuild/rsbuild-project-built/package.json b/examples/rsbuild/rsbuild-project-built/package.json new file mode 100644 index 0000000000..f7bedd282c --- /dev/null +++ b/examples/rsbuild/rsbuild-project-built/package.json @@ -0,0 +1,23 @@ +{ + "name": "neuroglancer-rsbuild-project-built", + "version": "0.0.0", + "private": true, + "description": "Test of an rsbuild project that depends on Neuroglancer.", + "scripts": { + "build": "rsbuild build", + "dev-server": "rsbuild dev" + }, + "dependencies": { + "neuroglancer": "file:../../../dist/package" + }, + "browserslist": [ + "last 2 Chrome versions", + "last 2 Firefox versions", + "last 2 Safari versions" + ], + "license": "Apache-2.0", + "devDependencies": { + "@rsbuild/core": "^1.1.9" + }, + "type": "module" +} diff --git a/examples/rsbuild/rsbuild-project-built/rsbuild.config.ts b/examples/rsbuild/rsbuild-project-built/rsbuild.config.ts new file mode 100644 index 0000000000..0f435fed84 --- /dev/null +++ b/examples/rsbuild/rsbuild-project-built/rsbuild.config.ts @@ -0,0 +1,43 @@ +import { defineConfig } from "@rsbuild/core"; + +export default defineConfig({ + html: { + title: "rsbuild neuroglancer test", + scriptLoading: "module", + mountId: "neuroglancer-container", + }, + output: { + assetPrefix: "./", + distPath: { + js: "", + jsAsync: "", + wasm: "", + css: "", + }, + }, + tools: { + rspack: { + module: { + rules: [ + // Needed for .svg?raw imports used for embedding icons. + { + resourceQuery: /raw/, + type: "asset/source", + }, + // Needed for .html assets used for auth redirect pages for the brainmaps + // and bossDB data sources. Can be skipped if those data sources are + // excluded. + { + test: /\.html$/, + type: "asset/resource", + generator: { + // Filename must be preserved since exact redirect URLs must be allowlisted. + filename: "[name][ext]", + }, + }, + ], + }, + }, + }, + plugins: [], +}); diff --git a/examples/rsbuild/rsbuild-project-built/src/index.js b/examples/rsbuild/rsbuild-project-built/src/index.js new file mode 100644 index 0000000000..805818b627 --- /dev/null +++ b/examples/rsbuild/rsbuild-project-built/src/index.js @@ -0,0 +1,3 @@ +import "neuroglancer"; +import { setupDefaultViewer } from "neuroglancer/unstable/ui/default_viewer_setup.js"; +setupDefaultViewer(); diff --git a/examples/rsbuild/rsbuild-project-source/.gitignore b/examples/rsbuild/rsbuild-project-source/.gitignore new file mode 100644 index 0000000000..b0a5c349ca --- /dev/null +++ b/examples/rsbuild/rsbuild-project-source/.gitignore @@ -0,0 +1,2 @@ +/node_modules/ +/dist/ diff --git a/examples/rsbuild/rsbuild-project-source/README.md b/examples/rsbuild/rsbuild-project-source/README.md new file mode 100644 index 0000000000..be1275aabe --- /dev/null +++ b/examples/rsbuild/rsbuild-project-source/README.md @@ -0,0 +1 @@ +This demonstrates a dependent project that uses rsbuild for building. diff --git a/examples/rsbuild/rsbuild-project-source/package-lock.json b/examples/rsbuild/rsbuild-project-source/package-lock.json new file mode 100644 index 0000000000..26f3795879 --- /dev/null +++ b/examples/rsbuild/rsbuild-project-source/package-lock.json @@ -0,0 +1,10285 @@ +{ + "name": "neuroglancer-rsbuild-project-source", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "neuroglancer-rsbuild-project-source", + "version": "0.0.0", + "license": "Apache-2.0", + "dependencies": { + "neuroglancer": "file:../../.." + }, + "devDependencies": { + "@rsbuild/core": "^1.1.9" + } + }, + "../../..": { + "version": "2.40.1", + "license": "Apache-2.0", + "dependencies": { + "codemirror": "^5.61.1", + "core-js": "^3.40.0", + "crc-32": "^1.2.2", + "gl-matrix": "3.1.0", + "ikonate": "github:mikolajdobrucki/ikonate#a86b4107c6ec717e7877f880a930d1ccf0b59d89", + "lodash-es": "^4.17.21", + "nifti-reader-js": "^0.6.8", + "numcodecs": "^0.3.2" + }, + "devDependencies": { + "@eslint/js": "^9.18.0", + "@iodigital/vite-plugin-msw": "^2.0.0", + "@playwright/browser-chromium": "^1.49.1", + "@rspack/cli": "^1.1.8", + "@rspack/core": "^1.1.8", + "@types/codemirror": "5.60.15", + "@types/gl-matrix": "^2.4.5", + "@types/http-server": "^0.12.4", + "@types/jsdom": "^21.1.7", + "@types/lodash-es": "^4.17.12", + "@types/node": "^22.10.7", + "@types/nunjucks": "^3.2.6", + "@types/s3rver": "^3.7.4", + "@types/yargs": "^17.0.33", + "@vitest/browser": "^3.0.2", + "@vitest/ui": "^3.0.2", + "@vitest/web-worker": "^3.0.2", + "cookie": "^1.0.2", + "css-loader": "^7.1.2", + "esbuild": "^0.24.2", + "eslint": "^9.18.0", + "eslint-formatter-codeframe": "^7.32.1", + "eslint-import-resolver-typescript": "^3.7.0", + "eslint-plugin-import": "^2.31.0", + "eslint-plugin-oxlint": "^0.15.7", + "eslint-rspack-plugin": "^4.2.1", + "express": "^4.21.2", + "glob": "^11.0.1", + "http-server": "^14.1.1", + "jsdom": "^26.0.0", + "msw": "^2.7.0", + "nunjucks": "^3.2.4", + "oxlint": "^0.15.7", + "playwright": "^1.49.1", + "prettier": "3.4.2", + "s3rver": "^3.7.1", + "ts-checker-rspack-plugin": "^1.1.1", + "tsx": "^4.19.2", + "typescript": "^5.7.3", + "typescript-eslint": "^8.20.0", + "vitest": "^3.0.2", + "webpack-bundle-analyzer": "^4.10.2", + "webpack-merge": "^6.0.1", + "yargs": "^17.7.2", + "yauzl": "^3.2.0" + }, + "engines": { + "node": ">=22" + } + }, + "../../../node_modules/@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "../../../node_modules/@discoveryjs/json-ext": { + "version": "0.5.7", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, + "../../../node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/@esbuild/linux-x64": { + "version": "0.20.1", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "../../../node_modules/@eslint-community/regexpp": { + "version": "4.10.0", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "../../../node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "../../../node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.11", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "../../../node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "../../../node_modules/@eslint/js": { + "version": "8.56.0", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "../../../node_modules/@humanwhocodes/config-array": { + "version": "0.11.14", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "../../../node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { + "version": "1.1.11", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "../../../node_modules/@humanwhocodes/config-array/node_modules/minimatch": { + "version": "3.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "../../../node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "../../../node_modules/@humanwhocodes/object-schema": { + "version": "2.0.2", + "dev": true, + "license": "BSD-3-Clause" + }, + "../../../node_modules/@isaacs/cliui": { + "version": "8.0.2", + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "../../../node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "../../../node_modules/@jest/schemas": { + "version": "29.6.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "../../../node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "../../../node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=6.0.0" + } + }, + "../../../node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=6.0.0" + } + }, + "../../../node_modules/@jridgewell/source-map": { + "version": "0.3.5", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "../../../node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "../../../node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "../../../node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "../../../node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "../../../node_modules/@one-ini/wasm": { + "version": "0.1.1", + "license": "MIT" + }, + "../../../node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "../../../node_modules/@polka/url": { + "version": "1.0.0-next.24", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/@puppeteer/browsers": { + "version": "2.0.1", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "peer": true, + "dependencies": { + "debug": "4.3.4", + "extract-zip": "2.0.1", + "progress": "2.0.3", + "proxy-agent": "6.4.0", + "tar-fs": "3.0.5", + "unbzip2-stream": "1.4.3", + "yargs": "17.7.2" + }, + "bin": { + "browsers": "lib/cjs/main-cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "../../../node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.19.0.tgz", + "integrity": "sha512-JlPfZ/C7yn5S5p0yKk7uhHTTnFlvTgLetl2VxqE518QgyM7C9bSfFTYvB/Q/ftkq0RIPY4ySxTz+/wKJ/dXC0w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "../../../node_modules/@rollup/rollup-android-arm64": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.19.0.tgz", + "integrity": "sha512-RDxUSY8D1tWYfn00DDi5myxKgOk6RvWPxhmWexcICt/MEC6yEMr4HNCu1sXXYLw8iAsg0D44NuU+qNq7zVWCrw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "../../../node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.19.0.tgz", + "integrity": "sha512-emvKHL4B15x6nlNTBMtIaC9tLPRpeA5jMvRLXVbl/W9Ie7HhkrE7KQjvgS9uxgatL1HmHWDXk5TTS4IaNJxbAA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "../../../node_modules/@rollup/rollup-darwin-x64": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.19.0.tgz", + "integrity": "sha512-fO28cWA1dC57qCd+D0rfLC4VPbh6EOJXrreBmFLWPGI9dpMlER2YwSPZzSGfq11XgcEpPukPTfEVFtw2q2nYJg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "../../../node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.19.0.tgz", + "integrity": "sha512-2Rn36Ubxdv32NUcfm0wB1tgKqkQuft00PtM23VqLuCUR4N5jcNWDoV5iBC9jeGdgS38WK66ElncprqgMUOyomw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "../../../node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.19.0.tgz", + "integrity": "sha512-gJuzIVdq/X1ZA2bHeCGCISe0VWqCoNT8BvkQ+BfsixXwTOndhtLUpOg0A1Fcx/+eA6ei6rMBzlOz4JzmiDw7JQ==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "../../../node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.19.0.tgz", + "integrity": "sha512-0EkX2HYPkSADo9cfeGFoQ7R0/wTKb7q6DdwI4Yn/ULFE1wuRRCHybxpl2goQrx4c/yzK3I8OlgtBu4xvted0ug==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "../../../node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.19.0.tgz", + "integrity": "sha512-GlIQRj9px52ISomIOEUq/IojLZqzkvRpdP3cLgIE1wUWaiU5Takwlzpz002q0Nxxr1y2ZgxC2obWxjr13lvxNQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "../../../node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.19.0.tgz", + "integrity": "sha512-N6cFJzssruDLUOKfEKeovCKiHcdwVYOT1Hs6dovDQ61+Y9n3Ek4zXvtghPPelt6U0AH4aDGnDLb83uiJMkWYzQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "../../../node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.19.0.tgz", + "integrity": "sha512-2DnD3mkS2uuam/alF+I7M84koGwvn3ZVD7uG+LEWpyzo/bq8+kKnus2EVCkcvh6PlNB8QPNFOz6fWd5N8o1CYg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "../../../node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.19.0.tgz", + "integrity": "sha512-D6pkaF7OpE7lzlTOFCB2m3Ngzu2ykw40Nka9WmKGUOTS3xcIieHe82slQlNq69sVB04ch73thKYIWz/Ian8DUA==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "../../../node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.19.0.tgz", + "integrity": "sha512-HBndjQLP8OsdJNSxpNIN0einbDmRFg9+UQeZV1eiYupIRuZsDEoeGU43NQsS34Pp166DtwQOnpcbV/zQxM+rWA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "../../../node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.19.0.tgz", + "integrity": "sha512-HxfbvfCKJe/RMYJJn0a12eiOI9OOtAUF4G6ozrFUK95BNyoJaSiBjIOHjZskTUffUrB84IPKkFG9H9nEvJGW6A==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "../../../node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.19.0.tgz", + "integrity": "sha512-HxDMKIhmcguGTiP5TsLNolwBUK3nGGUEoV/BO9ldUBoMLBssvh4J0X8pf11i1fTV7WShWItB1bKAKjX4RQeYmg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "../../../node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.19.0.tgz", + "integrity": "sha512-xItlIAZZaiG/u0wooGzRsx11rokP4qyc/79LkAOdznGRAbOFc+SfEdfUOszG1odsHNgwippUJavag/+W/Etc6Q==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "../../../node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.19.0.tgz", + "integrity": "sha512-xNo5fV5ycvCCKqiZcpB65VMR11NJB+StnxHz20jdqRAktfdfzhgjTiJ2doTDQE/7dqGaV5I7ZGqKpgph6lCIag==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "../../../node_modules/@sinclair/typebox": { + "version": "0.27.8", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/@sindresorhus/is": { + "version": "5.6.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "../../../node_modules/@szmarczak/http-timer": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "defer-to-connect": "^2.0.1" + }, + "engines": { + "node": ">=14.16" + } + }, + "../../../node_modules/@tootallnate/once": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "../../../node_modules/@tootallnate/quickjs-emscripten": { + "version": "0.23.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/@types/codemirror": { + "version": "5.60.15", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/tern": "*" + } + }, + "../../../node_modules/@types/eslint": { + "version": "8.56.5", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "../../../node_modules/@types/eslint-scope": { + "version": "3.7.7", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "../../../node_modules/@types/estree": { + "version": "1.0.5", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/@types/gl-matrix": { + "version": "2.4.5", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/@types/http-cache-semantics": { + "version": "4.0.4", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/@types/json-schema": { + "version": "7.0.15", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/@types/json5": { + "version": "0.0.29", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/@types/lodash": { + "version": "4.14.202", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/@types/lodash-es": { + "version": "4.17.12", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/lodash": "*" + } + }, + "../../../node_modules/@types/node": { + "version": "20.11.20", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "../../../node_modules/@types/tern": { + "version": "0.23.9", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "*" + } + }, + "../../../node_modules/@types/which": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/@types/ws": { + "version": "8.5.10", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@types/node": "*" + } + }, + "../../../node_modules/@types/yargs": { + "version": "17.0.32", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "../../../node_modules/@types/yargs-parser": { + "version": "21.0.3", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/@types/yauzl": { + "version": "2.10.3", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@types/node": "*" + } + }, + "../../../node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "dev": true, + "license": "ISC" + }, + "../../../node_modules/@vitest/browser": { + "version": "1.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "1.3.1", + "magic-string": "^0.30.5", + "sirv": "^2.0.4" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "playwright": "*", + "vitest": "1.3.1", + "webdriverio": "*" + }, + "peerDependenciesMeta": { + "playwright": { + "optional": true + }, + "safaridriver": { + "optional": true + }, + "webdriverio": { + "optional": true + } + } + }, + "../../../node_modules/@vitest/expect": { + "version": "1.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "1.3.1", + "@vitest/utils": "1.3.1", + "chai": "^4.3.10" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "../../../node_modules/@vitest/runner": { + "version": "1.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "1.3.1", + "p-limit": "^5.0.0", + "pathe": "^1.1.1" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "../../../node_modules/@vitest/runner/node_modules/p-limit": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/@vitest/runner/node_modules/yocto-queue": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/@vitest/snapshot": { + "version": "1.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "magic-string": "^0.30.5", + "pathe": "^1.1.1", + "pretty-format": "^29.7.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "../../../node_modules/@vitest/spy": { + "version": "1.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyspy": "^2.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "../../../node_modules/@vitest/ui": { + "version": "1.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "1.3.1", + "fast-glob": "^3.3.2", + "fflate": "^0.8.1", + "flatted": "^3.2.9", + "pathe": "^1.1.1", + "picocolors": "^1.0.0", + "sirv": "^2.0.4" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "vitest": "1.3.1" + } + }, + "../../../node_modules/@vitest/utils": { + "version": "1.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "diff-sequences": "^29.6.3", + "estree-walker": "^3.0.3", + "loupe": "^2.3.7", + "pretty-format": "^29.7.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "../../../node_modules/@vitest/utils/node_modules/estree-walker": { + "version": "3.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "../../../node_modules/@wdio/config": { + "version": "8.32.3", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@wdio/logger": "8.28.0", + "@wdio/types": "8.32.2", + "@wdio/utils": "8.32.3", + "decamelize": "^6.0.0", + "deepmerge-ts": "^5.0.0", + "glob": "^10.2.2", + "import-meta-resolve": "^4.0.0" + }, + "engines": { + "node": "^16.13 || >=18" + } + }, + "../../../node_modules/@wdio/logger": { + "version": "8.28.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "chalk": "^5.1.2", + "loglevel": "^1.6.0", + "loglevel-plugin-prefix": "^0.8.4", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": "^16.13 || >=18" + } + }, + "../../../node_modules/@wdio/logger/node_modules/ansi-regex": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "../../../node_modules/@wdio/logger/node_modules/chalk": { + "version": "5.3.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "../../../node_modules/@wdio/logger/node_modules/strip-ansi": { + "version": "7.1.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "../../../node_modules/@wdio/protocols": { + "version": "8.32.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/@wdio/repl": { + "version": "8.24.12", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@types/node": "^20.1.0" + }, + "engines": { + "node": "^16.13 || >=18" + } + }, + "../../../node_modules/@wdio/types": { + "version": "8.32.2", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@types/node": "^20.1.0" + }, + "engines": { + "node": "^16.13 || >=18" + } + }, + "../../../node_modules/@wdio/utils": { + "version": "8.32.3", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@puppeteer/browsers": "^1.6.0", + "@wdio/logger": "8.28.0", + "@wdio/types": "8.32.2", + "decamelize": "^6.0.0", + "deepmerge-ts": "^5.1.0", + "edgedriver": "^5.3.5", + "geckodriver": "^4.3.1", + "get-port": "^7.0.0", + "import-meta-resolve": "^4.0.0", + "locate-app": "^2.1.0", + "safaridriver": "^0.1.0", + "split2": "^4.2.0", + "wait-port": "^1.0.4" + }, + "engines": { + "node": "^16.13 || >=18" + } + }, + "../../../node_modules/@webassemblyjs/ast": { + "version": "1.11.6", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" + } + }, + "../../../node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.6", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/@webassemblyjs/helper-api-error": { + "version": "1.11.6", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/@webassemblyjs/helper-buffer": { + "version": "1.11.6", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/@webassemblyjs/helper-numbers": { + "version": "1.11.6", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@xtuc/long": "4.2.2" + } + }, + "../../../node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.6", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.11.6", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6" + } + }, + "../../../node_modules/@webassemblyjs/ieee754": { + "version": "1.11.6", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "../../../node_modules/@webassemblyjs/leb128": { + "version": "1.11.6", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "peer": true, + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "../../../node_modules/@webassemblyjs/utf8": { + "version": "1.11.6", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/@webassemblyjs/wasm-edit": { + "version": "1.11.6", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6", + "@webassemblyjs/wasm-opt": "1.11.6", + "@webassemblyjs/wasm-parser": "1.11.6", + "@webassemblyjs/wast-printer": "1.11.6" + } + }, + "../../../node_modules/@webassemblyjs/wasm-gen": { + "version": "1.11.6", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "../../../node_modules/@webassemblyjs/wasm-opt": { + "version": "1.11.6", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6", + "@webassemblyjs/wasm-parser": "1.11.6" + } + }, + "../../../node_modules/@webassemblyjs/wasm-parser": { + "version": "1.11.6", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "../../../node_modules/@webassemblyjs/wast-printer": { + "version": "1.11.6", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@xtuc/long": "4.2.2" + } + }, + "../../../node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "dev": true, + "license": "BSD-3-Clause", + "optional": true, + "peer": true + }, + "../../../node_modules/@xtuc/long": { + "version": "4.2.2", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "peer": true + }, + "../../../node_modules/abab": { + "version": "2.0.6", + "dev": true, + "license": "BSD-3-Clause" + }, + "../../../node_modules/abbrev": { + "version": "2.0.0", + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "../../../node_modules/acorn": { + "version": "8.11.3", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "../../../node_modules/acorn-globals": { + "version": "6.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^7.1.1", + "acorn-walk": "^7.1.1" + } + }, + "../../../node_modules/acorn-globals/node_modules/acorn": { + "version": "7.4.1", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "../../../node_modules/acorn-import-assertions": { + "version": "1.9.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "peerDependencies": { + "acorn": "^8" + } + }, + "../../../node_modules/acorn-jsx": { + "version": "5.3.2", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "../../../node_modules/acorn-walk": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "../../../node_modules/agent-base": { + "version": "6.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "../../../node_modules/ajv": { + "version": "6.12.6", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "../../../node_modules/ajv-keywords": { + "version": "3.5.2", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "../../../node_modules/ansi-regex": { + "version": "5.0.1", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "../../../node_modules/ansi-styles": { + "version": "4.3.0", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "../../../node_modules/archiver": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "archiver-utils": "^4.0.1", + "async": "^3.2.4", + "buffer-crc32": "^0.2.1", + "readable-stream": "^3.6.0", + "readdir-glob": "^1.1.2", + "tar-stream": "^3.0.0", + "zip-stream": "^5.0.1" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "../../../node_modules/archiver-utils": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "glob": "^8.0.0", + "graceful-fs": "^4.2.0", + "lazystream": "^1.0.0", + "lodash": "^4.17.15", + "normalize-path": "^3.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "../../../node_modules/archiver-utils/node_modules/glob": { + "version": "8.1.0", + "dev": true, + "license": "ISC", + "optional": true, + "peer": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "../../../node_modules/archiver-utils/node_modules/minimatch": { + "version": "5.1.6", + "dev": true, + "license": "ISC", + "optional": true, + "peer": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "../../../node_modules/archiver-utils/node_modules/readable-stream": { + "version": "3.6.2", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "../../../node_modules/archiver/node_modules/readable-stream": { + "version": "3.6.2", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "../../../node_modules/argparse": { + "version": "2.0.1", + "dev": true, + "license": "Python-2.0" + }, + "../../../node_modules/aria-query": { + "version": "5.3.0", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "peer": true, + "dependencies": { + "dequal": "^2.0.3" + } + }, + "../../../node_modules/array-buffer-byte-length": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "is-array-buffer": "^3.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/array-equal": { + "version": "1.0.2", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/array-includes": { + "version": "3.1.7", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/array.prototype.findlastindex": { + "version": "1.2.3", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0", + "get-intrinsic": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/array.prototype.flat": { + "version": "1.3.2", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/array.prototype.flatmap": { + "version": "1.3.2", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/arraybuffer.prototype.slice": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", + "is-array-buffer": "^3.0.2", + "is-shared-array-buffer": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/asn1": { + "version": "0.2.6", + "license": "MIT", + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "../../../node_modules/assert-plus": { + "version": "1.0.0", + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "../../../node_modules/assertion-error": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "../../../node_modules/ast-types": { + "version": "0.13.4", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "../../../node_modules/async": { + "version": "3.2.5", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/async-limiter": { + "version": "1.0.1", + "license": "MIT" + }, + "../../../node_modules/asynckit": { + "version": "0.4.0", + "license": "MIT" + }, + "../../../node_modules/available-typed-arrays": { + "version": "1.0.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/aws-sign2": { + "version": "0.7.0", + "license": "Apache-2.0", + "engines": { + "node": "*" + } + }, + "../../../node_modules/aws4": { + "version": "1.12.0", + "license": "MIT" + }, + "../../../node_modules/b4a": { + "version": "1.6.4", + "dev": true, + "license": "ISC", + "optional": true, + "peer": true + }, + "../../../node_modules/balanced-match": { + "version": "1.0.2", + "license": "MIT" + }, + "../../../node_modules/bare-events": { + "version": "2.2.0", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "peer": true + }, + "../../../node_modules/bare-fs": { + "version": "2.1.5", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "peer": true, + "dependencies": { + "bare-events": "^2.0.0", + "bare-os": "^2.0.0", + "bare-path": "^2.0.0", + "streamx": "^2.13.0" + } + }, + "../../../node_modules/bare-os": { + "version": "2.2.0", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "peer": true + }, + "../../../node_modules/bare-path": { + "version": "2.1.0", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "peer": true, + "dependencies": { + "bare-os": "^2.1.0" + } + }, + "../../../node_modules/base64-js": { + "version": "1.5.1", + "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, + "peer": true + }, + "../../../node_modules/basic-ftp": { + "version": "5.0.4", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=10.0.0" + } + }, + "../../../node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "license": "BSD-3-Clause", + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, + "../../../node_modules/big-integer": { + "version": "1.6.52", + "dev": true, + "license": "Unlicense", + "optional": true, + "peer": true, + "engines": { + "node": ">=0.6" + } + }, + "../../../node_modules/binary": { + "version": "0.3.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "buffers": "~0.1.1", + "chainsaw": "~0.1.0" + } + }, + "../../../node_modules/bluebird": { + "version": "3.4.7", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/brace-expansion": { + "version": "2.0.1", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "../../../node_modules/braces": { + "version": "3.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "../../../node_modules/browser-process-hrtime": { + "version": "1.0.0", + "license": "BSD-2-Clause" + }, + "../../../node_modules/browserslist": { + "version": "4.23.0", + "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", + "optional": true, + "peer": true, + "dependencies": { + "caniuse-lite": "^1.0.30001587", + "electron-to-chromium": "^1.4.668", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.13" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "../../../node_modules/buffer-crc32": { + "version": "0.2.13", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "../../../node_modules/buffer-from": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/buffer-indexof-polyfill": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=0.10" + } + }, + "../../../node_modules/buffers": { + "version": "0.1.1", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=0.2.0" + } + }, + "../../../node_modules/cac": { + "version": "6.7.14", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "../../../node_modules/cacheable-lookup": { + "version": "7.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=14.16" + } + }, + "../../../node_modules/cacheable-request": { + "version": "10.2.14", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@types/http-cache-semantics": "^4.0.2", + "get-stream": "^6.0.1", + "http-cache-semantics": "^4.1.1", + "keyv": "^4.5.3", + "mimic-response": "^4.0.0", + "normalize-url": "^8.0.0", + "responselike": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + } + }, + "../../../node_modules/cacheable-request/node_modules/get-stream": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/call-bind": { + "version": "1.0.5", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.1", + "set-function-length": "^1.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/callsites": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "../../../node_modules/caniuse-lite": { + "version": "1.0.30001596", + "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", + "optional": true, + "peer": true + }, + "../../../node_modules/caseless": { + "version": "0.12.0", + "license": "Apache-2.0" + }, + "../../../node_modules/chai": { + "version": "4.4.1", + "dev": true, + "license": "MIT", + "dependencies": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.3", + "deep-eql": "^4.1.3", + "get-func-name": "^2.0.2", + "loupe": "^2.3.6", + "pathval": "^1.1.1", + "type-detect": "^4.0.8" + }, + "engines": { + "node": ">=4" + } + }, + "../../../node_modules/chainsaw": { + "version": "0.1.0", + "dev": true, + "license": "MIT/X11", + "optional": true, + "peer": true, + "dependencies": { + "traverse": ">=0.3.0 <0.4" + } + }, + "../../../node_modules/chalk": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "../../../node_modules/check-error": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "get-func-name": "^2.0.2" + }, + "engines": { + "node": "*" + } + }, + "../../../node_modules/chrome-trace-event": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=6.0" + } + }, + "../../../node_modules/chromium-bidi": { + "version": "0.4.16", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "peer": true, + "dependencies": { + "mitt": "3.0.0" + }, + "peerDependencies": { + "devtools-protocol": "*" + } + }, + "../../../node_modules/cliui": { + "version": "8.0.1", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/cliui/node_modules/emoji-regex": { + "version": "8.0.0", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/cliui/node_modules/string-width": { + "version": "4.2.3", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "../../../node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "../../../node_modules/clone-deep": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "../../../node_modules/clone-deep/node_modules/kind-of": { + "version": "6.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "../../../node_modules/codemirror": { + "version": "5.65.16", + "license": "MIT" + }, + "../../../node_modules/color-convert": { + "version": "2.0.1", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "../../../node_modules/color-name": { + "version": "1.1.4", + "license": "MIT" + }, + "../../../node_modules/combined-stream": { + "version": "1.0.8", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "../../../node_modules/commander": { + "version": "9.5.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": "^12.20.0 || >=14" + } + }, + "../../../node_modules/compress-commons": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "crc-32": "^1.2.0", + "crc32-stream": "^5.0.0", + "normalize-path": "^3.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "../../../node_modules/compress-commons/node_modules/readable-stream": { + "version": "3.6.2", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "../../../node_modules/concat-map": { + "version": "0.0.1", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/condense-newlines": { + "version": "0.2.1", + "license": "MIT", + "dependencies": { + "extend-shallow": "^2.0.1", + "is-whitespace": "^0.3.0", + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "../../../node_modules/config-chain": { + "version": "1.1.13", + "license": "MIT", + "dependencies": { + "ini": "^1.3.4", + "proto-list": "~1.2.1" + } + }, + "../../../node_modules/config-chain/node_modules/ini": { + "version": "1.3.8", + "license": "ISC" + }, + "../../../node_modules/core-util-is": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/crc-32": { + "version": "1.2.2", + "license": "Apache-2.0", + "bin": { + "crc32": "bin/crc32.njs" + }, + "engines": { + "node": ">=0.8" + } + }, + "../../../node_modules/crc32-stream": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "crc-32": "^1.2.0", + "readable-stream": "^3.4.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "../../../node_modules/crc32-stream/node_modules/readable-stream": { + "version": "3.6.2", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "../../../node_modules/cross-fetch": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "node-fetch": "^2.6.12" + } + }, + "../../../node_modules/cross-fetch/node_modules/node-fetch": { + "version": "2.7.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "../../../node_modules/cross-fetch/node_modules/tr46": { + "version": "0.0.3", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/cross-fetch/node_modules/webidl-conversions": { + "version": "3.0.1", + "dev": true, + "license": "BSD-2-Clause", + "optional": true, + "peer": true + }, + "../../../node_modules/cross-fetch/node_modules/whatwg-url": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "../../../node_modules/cross-spawn": { + "version": "7.0.3", + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "../../../node_modules/css-loader": { + "version": "6.10.0", + "dev": true, + "license": "MIT", + "dependencies": { + "icss-utils": "^5.1.0", + "postcss": "^8.4.33", + "postcss-modules-extract-imports": "^3.0.0", + "postcss-modules-local-by-default": "^4.0.4", + "postcss-modules-scope": "^3.1.1", + "postcss-modules-values": "^4.0.0", + "postcss-value-parser": "^4.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "../../../node_modules/css-shorthand-properties": { + "version": "1.1.1", + "dev": true, + "optional": true, + "peer": true + }, + "../../../node_modules/css-value": { + "version": "0.0.1", + "dev": true, + "optional": true, + "peer": true + }, + "../../../node_modules/cssesc": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "../../../node_modules/cssom": { + "version": "0.5.0", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/cssstyle": { + "version": "2.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "cssom": "~0.3.6" + }, + "engines": { + "node": ">=8" + } + }, + "../../../node_modules/cssstyle/node_modules/cssom": { + "version": "0.3.8", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/dashdash": { + "version": "1.14.1", + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "../../../node_modules/data-uri-to-buffer": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 12" + } + }, + "../../../node_modules/data-urls": { + "version": "3.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "abab": "^2.0.6", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^11.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/data-urls/node_modules/tr46": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/data-urls/node_modules/webidl-conversions": { + "version": "7.0.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/data-urls/node_modules/whatwg-mimetype": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/data-urls/node_modules/whatwg-url": { + "version": "11.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "tr46": "^3.0.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/debounce": { + "version": "1.2.1", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/debug": { + "version": "4.3.4", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "../../../node_modules/decamelize": { + "version": "6.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/decimal.js": { + "version": "10.4.3", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/decompress-response": { + "version": "6.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/decompress-response/node_modules/mimic-response": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/deep-eql": { + "version": "4.1.3", + "dev": true, + "license": "MIT", + "dependencies": { + "type-detect": "^4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "../../../node_modules/deep-is": { + "version": "0.1.4", + "license": "MIT" + }, + "../../../node_modules/deepmerge-ts": { + "version": "5.1.0", + "dev": true, + "license": "BSD-3-Clause", + "optional": true, + "peer": true, + "engines": { + "node": ">=16.0.0" + } + }, + "../../../node_modules/defer-to-connect": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=10" + } + }, + "../../../node_modules/define-data-property": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "../../../node_modules/define-properties": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/degenerator": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "ast-types": "^0.13.4", + "escodegen": "^2.1.0", + "esprima": "^4.0.1" + }, + "engines": { + "node": ">= 14" + } + }, + "../../../node_modules/delayed-stream": { + "version": "1.0.0", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "../../../node_modules/dequal": { + "version": "2.0.3", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, + "../../../node_modules/detect-libc": { + "version": "1.0.3", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "peer": true, + "bin": { + "detect-libc": "bin/detect-libc.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "../../../node_modules/devtools-protocol": { + "version": "0.0.1262051", + "dev": true, + "license": "BSD-3-Clause", + "optional": true, + "peer": true + }, + "../../../node_modules/diff-sequences": { + "version": "29.6.3", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "../../../node_modules/doctrine": { + "version": "3.0.0", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "../../../node_modules/domexception": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "webidl-conversions": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "../../../node_modules/domexception/node_modules/webidl-conversions": { + "version": "5.0.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=8" + } + }, + "../../../node_modules/duplexer": { + "version": "0.1.2", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/duplexer2": { + "version": "0.1.4", + "dev": true, + "license": "BSD-3-Clause", + "optional": true, + "peer": true, + "dependencies": { + "readable-stream": "^2.0.2" + } + }, + "../../../node_modules/eastasianwidth": { + "version": "0.2.0", + "license": "MIT" + }, + "../../../node_modules/ecc-jsbn": { + "version": "0.1.2", + "license": "MIT", + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "../../../node_modules/edge-paths": { + "version": "3.0.5", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@types/which": "^2.0.1", + "which": "^2.0.2" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/shirshak55" + } + }, + "../../../node_modules/edgedriver": { + "version": "5.3.10", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@wdio/logger": "^8.28.0", + "decamelize": "^6.0.0", + "edge-paths": "^3.0.5", + "node-fetch": "^3.3.2", + "unzipper": "^0.10.14", + "which": "^4.0.0" + }, + "bin": { + "edgedriver": "bin/edgedriver.js" + } + }, + "../../../node_modules/edgedriver/node_modules/isexe": { + "version": "3.1.1", + "dev": true, + "license": "ISC", + "optional": true, + "peer": true, + "engines": { + "node": ">=16" + } + }, + "../../../node_modules/edgedriver/node_modules/which": { + "version": "4.0.0", + "dev": true, + "license": "ISC", + "optional": true, + "peer": true, + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^16.13.0 || >=18.0.0" + } + }, + "../../../node_modules/editorconfig": { + "version": "1.0.4", + "license": "MIT", + "dependencies": { + "@one-ini/wasm": "0.1.1", + "commander": "^10.0.0", + "minimatch": "9.0.1", + "semver": "^7.5.3" + }, + "bin": { + "editorconfig": "bin/editorconfig" + }, + "engines": { + "node": ">=14" + } + }, + "../../../node_modules/editorconfig/node_modules/commander": { + "version": "10.0.1", + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "../../../node_modules/editorconfig/node_modules/minimatch": { + "version": "9.0.1", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "../../../node_modules/electron-to-chromium": { + "version": "1.4.699", + "dev": true, + "license": "ISC", + "optional": true, + "peer": true + }, + "../../../node_modules/emoji-regex": { + "version": "9.2.2", + "license": "MIT" + }, + "../../../node_modules/end-of-stream": { + "version": "1.4.4", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "once": "^1.4.0" + } + }, + "../../../node_modules/enhanced-resolve": { + "version": "5.15.0", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "../../../node_modules/es-abstract": { + "version": "1.22.3", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "arraybuffer.prototype.slice": "^1.0.2", + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.5", + "es-set-tostringtag": "^2.0.1", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.2", + "get-symbol-description": "^1.0.0", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0", + "internal-slot": "^1.0.5", + "is-array-buffer": "^3.0.2", + "is-callable": "^1.2.7", + "is-negative-zero": "^2.0.2", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.12", + "is-weakref": "^1.0.2", + "object-inspect": "^1.13.1", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.5.1", + "safe-array-concat": "^1.0.1", + "safe-regex-test": "^1.0.0", + "string.prototype.trim": "^1.2.8", + "string.prototype.trimend": "^1.0.7", + "string.prototype.trimstart": "^1.0.7", + "typed-array-buffer": "^1.0.0", + "typed-array-byte-length": "^1.0.0", + "typed-array-byte-offset": "^1.0.0", + "typed-array-length": "^1.0.4", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/es-module-lexer": { + "version": "1.4.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/es-set-tostringtag": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.2", + "has-tostringtag": "^1.0.0", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "../../../node_modules/es-shim-unscopables": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.0" + } + }, + "../../../node_modules/es-to-primitive": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/esbuild": { + "version": "0.20.1", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.20.1", + "@esbuild/android-arm": "0.20.1", + "@esbuild/android-arm64": "0.20.1", + "@esbuild/android-x64": "0.20.1", + "@esbuild/darwin-arm64": "0.20.1", + "@esbuild/darwin-x64": "0.20.1", + "@esbuild/freebsd-arm64": "0.20.1", + "@esbuild/freebsd-x64": "0.20.1", + "@esbuild/linux-arm": "0.20.1", + "@esbuild/linux-arm64": "0.20.1", + "@esbuild/linux-ia32": "0.20.1", + "@esbuild/linux-loong64": "0.20.1", + "@esbuild/linux-mips64el": "0.20.1", + "@esbuild/linux-ppc64": "0.20.1", + "@esbuild/linux-riscv64": "0.20.1", + "@esbuild/linux-s390x": "0.20.1", + "@esbuild/linux-x64": "0.20.1", + "@esbuild/netbsd-x64": "0.20.1", + "@esbuild/openbsd-x64": "0.20.1", + "@esbuild/sunos-x64": "0.20.1", + "@esbuild/win32-arm64": "0.20.1", + "@esbuild/win32-ia32": "0.20.1", + "@esbuild/win32-x64": "0.20.1" + } + }, + "../../../node_modules/esbuild/node_modules/@esbuild/aix-ppc64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.1.tgz", + "integrity": "sha512-m55cpeupQ2DbuRGQMMZDzbv9J9PgVelPjlcmM5kxHnrBdBx6REaEd7LamYV7Dm8N7rCyR/XwU6rVP8ploKtIkA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/esbuild/node_modules/@esbuild/android-arm": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.1.tgz", + "integrity": "sha512-4j0+G27/2ZXGWR5okcJi7pQYhmkVgb4D7UKwxcqrjhvp5TKWx3cUjgB1CGj1mfdmJBQ9VnUGgUhign+FPF2Zgw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/esbuild/node_modules/@esbuild/android-arm64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.1.tgz", + "integrity": "sha512-hCnXNF0HM6AjowP+Zou0ZJMWWa1VkD77BXe959zERgGJBBxB+sV+J9f/rcjeg2c5bsukD/n17RKWXGFCO5dD5A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/esbuild/node_modules/@esbuild/android-x64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.1.tgz", + "integrity": "sha512-MSfZMBoAsnhpS+2yMFYIQUPs8Z19ajwfuaSZx+tSl09xrHZCjbeXXMsUF/0oq7ojxYEpsSo4c0SfjxOYXRbpaA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/esbuild/node_modules/@esbuild/darwin-arm64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.1.tgz", + "integrity": "sha512-Ylk6rzgMD8klUklGPzS414UQLa5NPXZD5tf8JmQU8GQrj6BrFA/Ic9tb2zRe1kOZyCbGl+e8VMbDRazCEBqPvA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/esbuild/node_modules/@esbuild/darwin-x64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.1.tgz", + "integrity": "sha512-pFIfj7U2w5sMp52wTY1XVOdoxw+GDwy9FsK3OFz4BpMAjvZVs0dT1VXs8aQm22nhwoIWUmIRaE+4xow8xfIDZA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/esbuild/node_modules/@esbuild/freebsd-arm64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.1.tgz", + "integrity": "sha512-UyW1WZvHDuM4xDz0jWun4qtQFauNdXjXOtIy7SYdf7pbxSWWVlqhnR/T2TpX6LX5NI62spt0a3ldIIEkPM6RHw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/esbuild/node_modules/@esbuild/freebsd-x64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.1.tgz", + "integrity": "sha512-itPwCw5C+Jh/c624vcDd9kRCCZVpzpQn8dtwoYIt2TJF3S9xJLiRohnnNrKwREvcZYx0n8sCSbvGH349XkcQeg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/esbuild/node_modules/@esbuild/linux-arm": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.1.tgz", + "integrity": "sha512-LojC28v3+IhIbfQ+Vu4Ut5n3wKcgTu6POKIHN9Wpt0HnfgUGlBuyDDQR4jWZUZFyYLiz4RBBBmfU6sNfn6RhLw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/esbuild/node_modules/@esbuild/linux-arm64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.1.tgz", + "integrity": "sha512-cX8WdlF6Cnvw/DO9/X7XLH2J6CkBnz7Twjpk56cshk9sjYVcuh4sXQBy5bmTwzBjNVZze2yaV1vtcJS04LbN8w==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/esbuild/node_modules/@esbuild/linux-ia32": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.1.tgz", + "integrity": "sha512-4H/sQCy1mnnGkUt/xszaLlYJVTz3W9ep52xEefGtd6yXDQbz/5fZE5dFLUgsPdbUOQANcVUa5iO6g3nyy5BJiw==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/esbuild/node_modules/@esbuild/linux-loong64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.1.tgz", + "integrity": "sha512-c0jgtB+sRHCciVXlyjDcWb2FUuzlGVRwGXgI+3WqKOIuoo8AmZAddzeOHeYLtD+dmtHw3B4Xo9wAUdjlfW5yYA==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/esbuild/node_modules/@esbuild/linux-mips64el": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.1.tgz", + "integrity": "sha512-TgFyCfIxSujyuqdZKDZ3yTwWiGv+KnlOeXXitCQ+trDODJ+ZtGOzLkSWngynP0HZnTsDyBbPy7GWVXWaEl6lhA==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/esbuild/node_modules/@esbuild/linux-ppc64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.1.tgz", + "integrity": "sha512-b+yuD1IUeL+Y93PmFZDZFIElwbmFfIKLKlYI8M6tRyzE6u7oEP7onGk0vZRh8wfVGC2dZoy0EqX1V8qok4qHaw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/esbuild/node_modules/@esbuild/linux-riscv64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.1.tgz", + "integrity": "sha512-wpDlpE0oRKZwX+GfomcALcouqjjV8MIX8DyTrxfyCfXxoKQSDm45CZr9fanJ4F6ckD4yDEPT98SrjvLwIqUCgg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/esbuild/node_modules/@esbuild/linux-s390x": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.1.tgz", + "integrity": "sha512-5BepC2Au80EohQ2dBpyTquqGCES7++p7G+7lXe1bAIvMdXm4YYcEfZtQrP4gaoZ96Wv1Ute61CEHFU7h4FMueQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/esbuild/node_modules/@esbuild/netbsd-x64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.1.tgz", + "integrity": "sha512-4fL68JdrLV2nVW2AaWZBv3XEm3Ae3NZn/7qy2KGAt3dexAgSVT+Hc97JKSZnqezgMlv9x6KV0ZkZY7UO5cNLCg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/esbuild/node_modules/@esbuild/openbsd-x64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.1.tgz", + "integrity": "sha512-GhRuXlvRE+twf2ES+8REbeCb/zeikNqwD3+6S5y5/x+DYbAQUNl0HNBs4RQJqrechS4v4MruEr8ZtAin/hK5iw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/esbuild/node_modules/@esbuild/sunos-x64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.1.tgz", + "integrity": "sha512-ZnWEyCM0G1Ex6JtsygvC3KUUrlDXqOihw8RicRuQAzw+c4f1D66YlPNNV3rkjVW90zXVsHwZYWbJh3v+oQFM9Q==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/esbuild/node_modules/@esbuild/win32-arm64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.1.tgz", + "integrity": "sha512-QZ6gXue0vVQY2Oon9WyLFCdSuYbXSoxaZrPuJ4c20j6ICedfsDilNPYfHLlMH7vGfU5DQR0czHLmJvH4Nzis/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/esbuild/node_modules/@esbuild/win32-ia32": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.1.tgz", + "integrity": "sha512-HzcJa1NcSWTAU0MJIxOho8JftNp9YALui3o+Ny7hCh0v5f90nprly1U3Sj1Ldj/CvKKdvvFsCRvDkpsEMp4DNw==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/esbuild/node_modules/@esbuild/win32-x64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.1.tgz", + "integrity": "sha512-0MBh53o6XtI6ctDnRMeQ+xoCN8kD2qI1rY1KgF/xdWQwoFeKou7puvDfV8/Wv4Ctx2rRpET/gGdz3YlNtNACSA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/escalade": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "../../../node_modules/escape-string-regexp": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/escodegen": { + "version": "2.1.0", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "../../../node_modules/eslint": { + "version": "8.56.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.56.0", + "@humanwhocodes/config-array": "^0.11.13", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "../../../node_modules/eslint-import-resolver-node": { + "version": "0.3.9", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" + } + }, + "../../../node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "../../../node_modules/eslint-import-resolver-typescript": { + "version": "3.6.1", + "dev": true, + "license": "ISC", + "dependencies": { + "debug": "^4.3.4", + "enhanced-resolve": "^5.12.0", + "eslint-module-utils": "^2.7.4", + "fast-glob": "^3.3.1", + "get-tsconfig": "^4.5.0", + "is-core-module": "^2.11.0", + "is-glob": "^4.0.3" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts/projects/eslint-import-resolver-ts" + }, + "peerDependencies": { + "eslint": "*", + "eslint-plugin-import": "*" + } + }, + "../../../node_modules/eslint-module-utils": { + "version": "2.8.0", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.2.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "../../../node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "../../../node_modules/eslint-plugin-import": { + "version": "2.29.1", + "dev": true, + "license": "MIT", + "dependencies": { + "array-includes": "^3.1.7", + "array.prototype.findlastindex": "^1.2.3", + "array.prototype.flat": "^1.3.2", + "array.prototype.flatmap": "^1.3.2", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.8.0", + "hasown": "^2.0.0", + "is-core-module": "^2.13.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.7", + "object.groupby": "^1.0.1", + "object.values": "^1.1.7", + "semver": "^6.3.1", + "tsconfig-paths": "^3.15.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" + } + }, + "../../../node_modules/eslint-plugin-import/node_modules/brace-expansion": { + "version": "1.1.11", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "../../../node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "../../../node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "2.1.0", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "../../../node_modules/eslint-plugin-import/node_modules/minimatch": { + "version": "3.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "../../../node_modules/eslint-plugin-import/node_modules/semver": { + "version": "6.3.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "../../../node_modules/eslint-scope": { + "version": "7.2.2", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "../../../node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "../../../node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.11", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "../../../node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "../../../node_modules/espree": { + "version": "9.6.1", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "../../../node_modules/esprima": { + "version": "4.0.1", + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "../../../node_modules/esquery": { + "version": "1.5.0", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "../../../node_modules/esrecurse": { + "version": "4.3.0", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "../../../node_modules/estraverse": { + "version": "5.3.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "../../../node_modules/esutils": { + "version": "2.0.3", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "../../../node_modules/execa": { + "version": "8.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "../../../node_modules/execa/node_modules/mimic-fn": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/execa/node_modules/npm-run-path": { + "version": "5.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/execa/node_modules/onetime": { + "version": "6.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/execa/node_modules/path-key": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/extend": { + "version": "3.0.2", + "license": "MIT" + }, + "../../../node_modules/extend-shallow": { + "version": "2.0.1", + "license": "MIT", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "../../../node_modules/extract-zip": { + "version": "2.0.1", + "dev": true, + "license": "BSD-2-Clause", + "optional": true, + "peer": true, + "dependencies": { + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + }, + "bin": { + "extract-zip": "cli.js" + }, + "engines": { + "node": ">= 10.17.0" + }, + "optionalDependencies": { + "@types/yauzl": "^2.9.1" + } + }, + "../../../node_modules/extract-zip/node_modules/get-stream": { + "version": "5.2.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/extsprintf": { + "version": "1.3.0", + "engines": [ + "node >=0.6.0" + ], + "license": "MIT" + }, + "../../../node_modules/fast-deep-equal": { + "version": "3.1.3", + "license": "MIT" + }, + "../../../node_modules/fast-fifo": { + "version": "1.3.2", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/fast-glob": { + "version": "3.3.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "../../../node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "../../../node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "license": "MIT" + }, + "../../../node_modules/fast-levenshtein": { + "version": "2.0.6", + "license": "MIT" + }, + "../../../node_modules/fastq": { + "version": "1.17.0", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "../../../node_modules/fd-slicer": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "pend": "~1.2.0" + } + }, + "../../../node_modules/fetch-blob": { + "version": "3.2.0", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "paypal", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + }, + "engines": { + "node": "^12.20 || >= 14.13" + } + }, + "../../../node_modules/fflate": { + "version": "0.8.1", + "license": "MIT" + }, + "../../../node_modules/file-entry-cache": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "../../../node_modules/fill-range": { + "version": "7.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "../../../node_modules/find-up": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/flat": { + "version": "5.0.2", + "dev": true, + "license": "BSD-3-Clause", + "bin": { + "flat": "cli.js" + } + }, + "../../../node_modules/flat-cache": { + "version": "3.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "../../../node_modules/flatted": { + "version": "3.2.9", + "dev": true, + "license": "ISC" + }, + "../../../node_modules/for-each": { + "version": "0.3.3", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.1.3" + } + }, + "../../../node_modules/foreground-child": { + "version": "3.1.1", + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "../../../node_modules/forever-agent": { + "version": "0.6.1", + "license": "Apache-2.0", + "engines": { + "node": "*" + } + }, + "../../../node_modules/form-data": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "../../../node_modules/form-data-encoder": { + "version": "2.1.4", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 14.17" + } + }, + "../../../node_modules/formdata-polyfill": { + "version": "4.0.10", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "fetch-blob": "^3.1.2" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "../../../node_modules/fs-extra": { + "version": "11.2.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "../../../node_modules/fs-extra/node_modules/universalify": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "../../../node_modules/fs.realpath": { + "version": "1.0.0", + "dev": true, + "license": "ISC" + }, + "../../../node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "../../../node_modules/fstream": { + "version": "1.0.12", + "dev": true, + "license": "ISC", + "optional": true, + "peer": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + }, + "engines": { + "node": ">=0.6" + } + }, + "../../../node_modules/fstream/node_modules/brace-expansion": { + "version": "1.1.11", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "../../../node_modules/fstream/node_modules/glob": { + "version": "7.2.3", + "dev": true, + "license": "ISC", + "optional": true, + "peer": 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" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "../../../node_modules/fstream/node_modules/minimatch": { + "version": "3.1.2", + "dev": true, + "license": "ISC", + "optional": true, + "peer": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "../../../node_modules/fstream/node_modules/rimraf": { + "version": "2.7.1", + "dev": true, + "license": "ISC", + "optional": true, + "peer": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "../../../node_modules/function-bind": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/function.prototype.name": { + "version": "1.1.6", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/functions-have-names": { + "version": "1.2.3", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/geckodriver": { + "version": "4.3.3", + "dev": true, + "hasInstallScript": true, + "license": "MPL-2.0", + "optional": true, + "peer": true, + "dependencies": { + "@wdio/logger": "^8.28.0", + "decamelize": "^6.0.0", + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.4", + "node-fetch": "^3.3.2", + "tar-fs": "^3.0.5", + "unzipper": "^0.10.14", + "which": "^4.0.0" + }, + "bin": { + "geckodriver": "bin/geckodriver.js" + }, + "engines": { + "node": "^16.13 || >=18 || >=20" + } + }, + "../../../node_modules/geckodriver/node_modules/agent-base": { + "version": "7.1.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "../../../node_modules/geckodriver/node_modules/http-proxy-agent": { + "version": "7.0.2", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "../../../node_modules/geckodriver/node_modules/https-proxy-agent": { + "version": "7.0.4", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "../../../node_modules/geckodriver/node_modules/isexe": { + "version": "3.1.1", + "dev": true, + "license": "ISC", + "optional": true, + "peer": true, + "engines": { + "node": ">=16" + } + }, + "../../../node_modules/geckodriver/node_modules/which": { + "version": "4.0.0", + "dev": true, + "license": "ISC", + "optional": true, + "peer": true, + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^16.13.0 || >=18.0.0" + } + }, + "../../../node_modules/get-caller-file": { + "version": "2.0.5", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "../../../node_modules/get-func-name": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "../../../node_modules/get-intrinsic": { + "version": "1.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/get-port": { + "version": "7.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/get-stream": { + "version": "8.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/get-symbol-description": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/get-tsconfig": { + "version": "4.7.2", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, + "../../../node_modules/get-uri": { + "version": "6.0.3", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "basic-ftp": "^5.0.2", + "data-uri-to-buffer": "^6.0.2", + "debug": "^4.3.4", + "fs-extra": "^11.2.0" + }, + "engines": { + "node": ">= 14" + } + }, + "../../../node_modules/get-uri/node_modules/data-uri-to-buffer": { + "version": "6.0.2", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 14" + } + }, + "../../../node_modules/getpass": { + "version": "0.1.7", + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0" + } + }, + "../../../node_modules/gl-matrix": { + "version": "3.1.0", + "license": "MIT" + }, + "../../../node_modules/glob": { + "version": "10.3.10", + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.5", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "../../../node_modules/glob-parent": { + "version": "6.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "../../../node_modules/glob-to-regexp": { + "version": "0.4.1", + "dev": true, + "license": "BSD-2-Clause", + "optional": true, + "peer": true + }, + "../../../node_modules/globals": { + "version": "13.24.0", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/globals/node_modules/type-fest": { + "version": "0.20.2", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/globalthis": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/gopd": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/got": { + "version": "12.6.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@sindresorhus/is": "^5.2.0", + "@szmarczak/http-timer": "^5.0.1", + "cacheable-lookup": "^7.0.0", + "cacheable-request": "^10.2.8", + "decompress-response": "^6.0.0", + "form-data-encoder": "^2.1.2", + "get-stream": "^6.0.1", + "http2-wrapper": "^2.1.10", + "lowercase-keys": "^3.0.0", + "p-cancelable": "^3.0.0", + "responselike": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" + } + }, + "../../../node_modules/got/node_modules/get-stream": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/graceful-fs": { + "version": "4.2.11", + "dev": true, + "license": "ISC" + }, + "../../../node_modules/grapheme-splitter": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/graphemer": { + "version": "1.4.0", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/gzip-size": { + "version": "6.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "duplexer": "^0.1.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/har-schema": { + "version": "2.0.0", + "license": "ISC", + "engines": { + "node": ">=4" + } + }, + "../../../node_modules/har-validator": { + "version": "5.1.5", + "license": "MIT", + "dependencies": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "../../../node_modules/has-bigints": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "../../../node_modules/has-property-descriptors": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/has-proto": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/has-symbols": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/has-tostringtag": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/hasown": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "../../../node_modules/html-encoding-sniffer": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-encoding": "^1.0.5" + }, + "engines": { + "node": ">=10" + } + }, + "../../../node_modules/html-escaper": { + "version": "2.0.2", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/http-cache-semantics": { + "version": "4.1.1", + "dev": true, + "license": "BSD-2-Clause", + "optional": true, + "peer": true + }, + "../../../node_modules/http-proxy-agent": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "../../../node_modules/http-signature": { + "version": "1.2.0", + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + }, + "engines": { + "node": ">=0.8", + "npm": ">=1.3.7" + } + }, + "../../../node_modules/http2-wrapper": { + "version": "2.2.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.2.0" + }, + "engines": { + "node": ">=10.19.0" + } + }, + "../../../node_modules/https-proxy-agent": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "../../../node_modules/human-signals": { + "version": "5.0.0", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=16.17.0" + } + }, + "../../../node_modules/iconv-lite": { + "version": "0.4.24", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "../../../node_modules/icss-utils": { + "version": "5.1.0", + "dev": true, + "license": "ISC", + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "../../../node_modules/ieee754": { + "version": "1.2.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause", + "optional": true, + "peer": true + }, + "../../../node_modules/ignore": { + "version": "5.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "../../../node_modules/ikonate": { + "version": "1.1.1", + "license": "MIT", + "dependencies": { + "jsdom": "11.10.0", + "pretty": "^2.0.0", + "xmldom": "^0.1.27" + } + }, + "../../../node_modules/ikonate/node_modules/abab": { + "version": "1.0.4", + "license": "ISC" + }, + "../../../node_modules/ikonate/node_modules/acorn": { + "version": "5.7.4", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "../../../node_modules/ikonate/node_modules/acorn-globals": { + "version": "4.3.4", + "license": "MIT", + "dependencies": { + "acorn": "^6.0.1", + "acorn-walk": "^6.0.1" + } + }, + "../../../node_modules/ikonate/node_modules/acorn-globals/node_modules/acorn": { + "version": "6.4.2", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "../../../node_modules/ikonate/node_modules/acorn-walk": { + "version": "6.2.0", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "../../../node_modules/ikonate/node_modules/cssom": { + "version": "0.3.8", + "license": "MIT" + }, + "../../../node_modules/ikonate/node_modules/cssstyle": { + "version": "0.2.37", + "license": "MIT", + "dependencies": { + "cssom": "0.3.x" + } + }, + "../../../node_modules/ikonate/node_modules/data-urls": { + "version": "1.1.0", + "license": "MIT", + "dependencies": { + "abab": "^2.0.0", + "whatwg-mimetype": "^2.2.0", + "whatwg-url": "^7.0.0" + } + }, + "../../../node_modules/ikonate/node_modules/data-urls/node_modules/abab": { + "version": "2.0.6", + "license": "BSD-3-Clause" + }, + "../../../node_modules/ikonate/node_modules/data-urls/node_modules/whatwg-url": { + "version": "7.1.0", + "license": "MIT", + "dependencies": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + }, + "../../../node_modules/ikonate/node_modules/domexception": { + "version": "1.0.1", + "license": "MIT", + "dependencies": { + "webidl-conversions": "^4.0.2" + } + }, + "../../../node_modules/ikonate/node_modules/escodegen": { + "version": "1.14.3", + "license": "BSD-2-Clause", + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=4.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "../../../node_modules/ikonate/node_modules/estraverse": { + "version": "4.3.0", + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "../../../node_modules/ikonate/node_modules/html-encoding-sniffer": { + "version": "1.0.2", + "license": "MIT", + "dependencies": { + "whatwg-encoding": "^1.0.1" + } + }, + "../../../node_modules/ikonate/node_modules/jsdom": { + "version": "11.10.0", + "license": "MIT", + "dependencies": { + "abab": "^1.0.4", + "acorn": "^5.3.0", + "acorn-globals": "^4.1.0", + "array-equal": "^1.0.0", + "cssom": ">= 0.3.2 < 0.4.0", + "cssstyle": ">= 0.2.37 < 0.3.0", + "data-urls": "^1.0.0", + "domexception": "^1.0.0", + "escodegen": "^1.9.0", + "html-encoding-sniffer": "^1.0.2", + "left-pad": "^1.2.0", + "nwmatcher": "^1.4.3", + "parse5": "4.0.0", + "pn": "^1.1.0", + "request": "^2.83.0", + "request-promise-native": "^1.0.5", + "sax": "^1.2.4", + "symbol-tree": "^3.2.2", + "tough-cookie": "^2.3.3", + "w3c-hr-time": "^1.0.1", + "webidl-conversions": "^4.0.2", + "whatwg-encoding": "^1.0.3", + "whatwg-mimetype": "^2.1.0", + "whatwg-url": "^6.4.0", + "ws": "^4.0.0", + "xml-name-validator": "^3.0.0" + } + }, + "../../../node_modules/ikonate/node_modules/levn": { + "version": "0.3.0", + "license": "MIT", + "dependencies": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "../../../node_modules/ikonate/node_modules/optionator": { + "version": "0.8.3", + "license": "MIT", + "dependencies": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "../../../node_modules/ikonate/node_modules/parse5": { + "version": "4.0.0", + "license": "MIT" + }, + "../../../node_modules/ikonate/node_modules/prelude-ls": { + "version": "1.1.2", + "engines": { + "node": ">= 0.8.0" + } + }, + "../../../node_modules/ikonate/node_modules/safe-buffer": { + "version": "5.1.2", + "license": "MIT" + }, + "../../../node_modules/ikonate/node_modules/tough-cookie": { + "version": "2.5.0", + "license": "BSD-3-Clause", + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "../../../node_modules/ikonate/node_modules/tr46": { + "version": "1.0.1", + "license": "MIT", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "../../../node_modules/ikonate/node_modules/type-check": { + "version": "0.3.2", + "license": "MIT", + "dependencies": { + "prelude-ls": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "../../../node_modules/ikonate/node_modules/webidl-conversions": { + "version": "4.0.2", + "license": "BSD-2-Clause" + }, + "../../../node_modules/ikonate/node_modules/whatwg-url": { + "version": "6.5.0", + "license": "MIT", + "dependencies": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + }, + "../../../node_modules/ikonate/node_modules/ws": { + "version": "4.1.0", + "license": "MIT", + "dependencies": { + "async-limiter": "~1.0.0", + "safe-buffer": "~5.1.0" + } + }, + "../../../node_modules/import-fresh": { + "version": "3.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/import-meta-resolve": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "../../../node_modules/imurmurhash": { + "version": "0.1.4", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "../../../node_modules/inflight": { + "version": "1.0.6", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "../../../node_modules/inherits": { + "version": "2.0.4", + "dev": true, + "license": "ISC" + }, + "../../../node_modules/internal-slot": { + "version": "1.0.6", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.2", + "hasown": "^2.0.0", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "../../../node_modules/ip-address": { + "version": "9.0.5", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "jsbn": "1.1.0", + "sprintf-js": "^1.1.3" + }, + "engines": { + "node": ">= 12" + } + }, + "../../../node_modules/ip-address/node_modules/jsbn": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/is-array-buffer": { + "version": "3.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.0", + "is-typed-array": "^1.1.10" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/is-bigint": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/is-boolean-object": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/is-buffer": { + "version": "1.1.6", + "license": "MIT" + }, + "../../../node_modules/is-callable": { + "version": "1.2.7", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/is-core-module": { + "version": "2.13.1", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/is-date-object": { + "version": "1.0.5", + "dev": true, + "license": "MIT", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/is-extendable": { + "version": "0.1.1", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "../../../node_modules/is-extglob": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "../../../node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "../../../node_modules/is-glob": { + "version": "4.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "../../../node_modules/is-negative-zero": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/is-number": { + "version": "7.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "../../../node_modules/is-number-object": { + "version": "1.0.7", + "dev": true, + "license": "MIT", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/is-path-inside": { + "version": "3.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "../../../node_modules/is-plain-obj": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/is-plain-object": { + "version": "2.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "../../../node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/is-regex": { + "version": "1.1.4", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/is-shared-array-buffer": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/is-stream": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/is-string": { + "version": "1.0.7", + "dev": true, + "license": "MIT", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/is-symbol": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/is-typed-array": { + "version": "1.1.12", + "dev": true, + "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.11" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/is-typedarray": { + "version": "1.0.0", + "license": "MIT" + }, + "../../../node_modules/is-weakref": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/is-whitespace": { + "version": "0.3.0", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "../../../node_modules/isarray": { + "version": "2.0.5", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/isexe": { + "version": "2.0.0", + "license": "ISC" + }, + "../../../node_modules/isobject": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "../../../node_modules/isstream": { + "version": "0.1.2", + "license": "MIT" + }, + "../../../node_modules/jackspeak": { + "version": "2.3.6", + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "../../../node_modules/jest-worker": { + "version": "27.5.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "../../../node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "../../../node_modules/js-beautify": { + "version": "1.14.11", + "license": "MIT", + "dependencies": { + "config-chain": "^1.1.13", + "editorconfig": "^1.0.3", + "glob": "^10.3.3", + "nopt": "^7.2.0" + }, + "bin": { + "css-beautify": "js/bin/css-beautify.js", + "html-beautify": "js/bin/html-beautify.js", + "js-beautify": "js/bin/js-beautify.js" + }, + "engines": { + "node": ">=14" + } + }, + "../../../node_modules/js-yaml": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "../../../node_modules/jsbn": { + "version": "0.1.1", + "license": "MIT" + }, + "../../../node_modules/jsdom": { + "version": "17.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "abab": "^2.0.5", + "acorn": "^8.4.1", + "acorn-globals": "^6.0.0", + "cssom": "^0.5.0", + "cssstyle": "^2.3.0", + "data-urls": "^3.0.0", + "decimal.js": "^10.3.1", + "domexception": "^2.0.1", + "escodegen": "^2.0.0", + "form-data": "^4.0.0", + "html-encoding-sniffer": "^2.0.1", + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "^5.0.0", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.0", + "parse5": "6.0.1", + "saxes": "^5.0.1", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.0.0", + "w3c-hr-time": "^1.0.2", + "w3c-xmlserializer": "^2.0.0", + "webidl-conversions": "^6.1.0", + "whatwg-encoding": "^1.0.5", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^9.0.0", + "ws": "^8.0.0", + "xml-name-validator": "^3.0.0" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "canvas": "^2.5.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "../../../node_modules/json-buffer": { + "version": "3.0.1", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/json-schema": { + "version": "0.4.0", + "license": "(AFL-2.1 OR BSD-3-Clause)" + }, + "../../../node_modules/json-schema-traverse": { + "version": "0.4.1", + "license": "MIT" + }, + "../../../node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/json-stringify-safe": { + "version": "5.0.1", + "license": "ISC" + }, + "../../../node_modules/jsonc-parser": { + "version": "3.2.1", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/jsonfile": { + "version": "6.1.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "../../../node_modules/jsonfile/node_modules/universalify": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "../../../node_modules/jsprim": { + "version": "1.4.2", + "license": "MIT", + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "../../../node_modules/keyv": { + "version": "4.5.4", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "../../../node_modules/kind-of": { + "version": "3.2.2", + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "../../../node_modules/ky": { + "version": "0.33.3", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sindresorhus/ky?sponsor=1" + } + }, + "../../../node_modules/lazystream": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "readable-stream": "^2.0.5" + }, + "engines": { + "node": ">= 0.6.3" + } + }, + "../../../node_modules/left-pad": { + "version": "1.3.0", + "license": "WTFPL" + }, + "../../../node_modules/levn": { + "version": "0.4.1", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "../../../node_modules/lightningcss": { + "version": "1.23.0", + "dev": true, + "license": "MPL-2.0", + "optional": true, + "peer": true, + "dependencies": { + "detect-libc": "^1.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-darwin-arm64": "1.23.0", + "lightningcss-darwin-x64": "1.23.0", + "lightningcss-freebsd-x64": "1.23.0", + "lightningcss-linux-arm-gnueabihf": "1.23.0", + "lightningcss-linux-arm64-gnu": "1.23.0", + "lightningcss-linux-arm64-musl": "1.23.0", + "lightningcss-linux-x64-gnu": "1.23.0", + "lightningcss-linux-x64-musl": "1.23.0", + "lightningcss-win32-x64-msvc": "1.23.0" + } + }, + "../../../node_modules/lightningcss-linux-x64-gnu": { + "version": "1.23.0", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "../../../node_modules/lightningcss-linux-x64-musl": { + "version": "1.23.0", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "../../../node_modules/listenercount": { + "version": "1.0.1", + "dev": true, + "license": "ISC", + "optional": true, + "peer": true + }, + "../../../node_modules/loader-runner": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=6.11.5" + } + }, + "../../../node_modules/local-pkg": { + "version": "0.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "mlly": "^1.4.2", + "pkg-types": "^1.0.3" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "../../../node_modules/locate-app": { + "version": "2.2.20", + "dev": true, + "license": "SEE LICENSE IN LICENSE", + "optional": true, + "peer": true, + "dependencies": { + "n12": "1.8.23", + "type-fest": "2.13.0", + "userhome": "1.0.0" + } + }, + "../../../node_modules/locate-app/node_modules/type-fest": { + "version": "2.13.0", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "optional": true, + "peer": true, + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/locate-path": { + "version": "6.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/lodash": { + "version": "4.17.21", + "license": "MIT" + }, + "../../../node_modules/lodash-es": { + "version": "4.17.21", + "license": "MIT" + }, + "../../../node_modules/lodash.clonedeep": { + "version": "4.5.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/lodash.merge": { + "version": "4.6.2", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/lodash.sortby": { + "version": "4.7.0", + "license": "MIT" + }, + "../../../node_modules/lodash.zip": { + "version": "4.2.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/loglevel": { + "version": "1.9.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 0.6.0" + }, + "funding": { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/loglevel" + } + }, + "../../../node_modules/loglevel-plugin-prefix": { + "version": "0.8.4", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/loupe": { + "version": "2.3.7", + "dev": true, + "license": "MIT", + "dependencies": { + "get-func-name": "^2.0.1" + } + }, + "../../../node_modules/lowercase-keys": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/lru-cache": { + "version": "10.2.0", + "license": "ISC", + "engines": { + "node": "14 || >=16.14" + } + }, + "../../../node_modules/magic-string": { + "version": "0.30.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15" + }, + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/merge-stream": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/merge2": { + "version": "1.4.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "../../../node_modules/micromatch": { + "version": "4.0.5", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "../../../node_modules/mime-db": { + "version": "1.52.0", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "../../../node_modules/mime-types": { + "version": "2.1.35", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "../../../node_modules/mimic-response": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/minimatch": { + "version": "9.0.3", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "../../../node_modules/minimist": { + "version": "1.2.8", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/minipass": { + "version": "7.0.4", + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "../../../node_modules/mitt": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/mkdirp": { + "version": "0.5.6", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "../../../node_modules/mlly": { + "version": "1.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.11.3", + "pathe": "^1.1.2", + "pkg-types": "^1.0.3", + "ufo": "^1.3.2" + } + }, + "../../../node_modules/mrmime": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "../../../node_modules/ms": { + "version": "2.1.2", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/n12": { + "version": "1.8.23", + "dev": true, + "license": "SEE LICENSE IN LICENSE", + "optional": true, + "peer": true + }, + "../../../node_modules/nanoid": { + "version": "3.3.7", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "../../../node_modules/natural-compare": { + "version": "1.4.0", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/neo-async": { + "version": "2.6.2", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/netmask": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 0.4.0" + } + }, + "../../../node_modules/nifti-reader-js": { + "version": "0.6.8", + "license": "MIT", + "dependencies": { + "fflate": "*" + } + }, + "../../../node_modules/node-domexception": { + "version": "1.0.0", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=10.5.0" + } + }, + "../../../node_modules/node-fetch": { + "version": "3.3.2", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" + } + }, + "../../../node_modules/node-releases": { + "version": "2.0.14", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/nopt": { + "version": "7.2.0", + "license": "ISC", + "dependencies": { + "abbrev": "^2.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "../../../node_modules/normalize-path": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "../../../node_modules/normalize-url": { + "version": "8.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/numcodecs": { + "version": "0.3.1", + "license": "MIT", + "dependencies": { + "fflate": "^0.8.0" + } + }, + "../../../node_modules/nwmatcher": { + "version": "1.4.4", + "license": "MIT" + }, + "../../../node_modules/nwsapi": { + "version": "2.2.7", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/oauth-sign": { + "version": "0.9.0", + "license": "Apache-2.0", + "engines": { + "node": "*" + } + }, + "../../../node_modules/object-inspect": { + "version": "1.13.1", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/object-keys": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "../../../node_modules/object.assign": { + "version": "4.1.5", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/object.fromentries": { + "version": "2.0.7", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/object.groupby": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1" + } + }, + "../../../node_modules/object.values": { + "version": "1.1.7", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/once": { + "version": "1.4.0", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "../../../node_modules/opener": { + "version": "1.5.2", + "dev": true, + "license": "(WTFPL OR MIT)", + "bin": { + "opener": "bin/opener-bin.js" + } + }, + "../../../node_modules/optionator": { + "version": "0.9.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@aashutoshrathi/word-wrap": "^1.2.3", + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "../../../node_modules/p-cancelable": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=12.20" + } + }, + "../../../node_modules/p-limit": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/p-locate": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/pac-proxy-agent": { + "version": "7.0.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@tootallnate/quickjs-emscripten": "^0.23.0", + "agent-base": "^7.0.2", + "debug": "^4.3.4", + "get-uri": "^6.0.1", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.2", + "pac-resolver": "^7.0.0", + "socks-proxy-agent": "^8.0.2" + }, + "engines": { + "node": ">= 14" + } + }, + "../../../node_modules/pac-proxy-agent/node_modules/agent-base": { + "version": "7.1.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "../../../node_modules/pac-proxy-agent/node_modules/http-proxy-agent": { + "version": "7.0.2", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "../../../node_modules/pac-proxy-agent/node_modules/https-proxy-agent": { + "version": "7.0.4", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "../../../node_modules/pac-resolver": { + "version": "7.0.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "degenerator": "^5.0.0", + "netmask": "^2.0.2" + }, + "engines": { + "node": ">= 14" + } + }, + "../../../node_modules/parent-module": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "../../../node_modules/parse5": { + "version": "6.0.1", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/path-exists": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "../../../node_modules/path-is-absolute": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "../../../node_modules/path-key": { + "version": "3.1.1", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "../../../node_modules/path-parse": { + "version": "1.0.7", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/path-scurry": { + "version": "1.10.1", + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^9.1.1 || ^10.0.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "../../../node_modules/pathe": { + "version": "1.1.2", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/pathval": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "../../../node_modules/pend": { + "version": "1.2.0", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/performance-now": { + "version": "2.1.0", + "license": "MIT" + }, + "../../../node_modules/picocolors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "dev": true + }, + "../../../node_modules/picomatch": { + "version": "2.3.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "../../../node_modules/pkg-types": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "jsonc-parser": "^3.2.0", + "mlly": "^1.2.0", + "pathe": "^1.1.0" + } + }, + "../../../node_modules/pn": { + "version": "1.1.0", + "license": "MIT" + }, + "../../../node_modules/postcss": { + "version": "8.4.39", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz", + "integrity": "sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==", + "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.7", + "picocolors": "^1.0.1", + "source-map-js": "^1.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "../../../node_modules/postcss-modules-extract-imports": { + "version": "3.0.0", + "dev": true, + "license": "ISC", + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "../../../node_modules/postcss-modules-local-by-default": { + "version": "4.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "icss-utils": "^5.0.0", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.1.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "../../../node_modules/postcss-modules-scope": { + "version": "3.1.1", + "dev": true, + "license": "ISC", + "dependencies": { + "postcss-selector-parser": "^6.0.4" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "../../../node_modules/postcss-modules-values": { + "version": "4.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "icss-utils": "^5.0.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "../../../node_modules/postcss-selector-parser": { + "version": "6.0.15", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "../../../node_modules/postcss-value-parser": { + "version": "4.2.0", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/prelude-ls": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "../../../node_modules/prettier": { + "version": "3.2.5", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "../../../node_modules/pretty": { + "version": "2.0.0", + "license": "MIT", + "dependencies": { + "condense-newlines": "^0.2.1", + "extend-shallow": "^2.0.1", + "js-beautify": "^1.6.12" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "../../../node_modules/pretty-format": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "../../../node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "../../../node_modules/process-nextick-args": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/progress": { + "version": "2.0.3", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=0.4.0" + } + }, + "../../../node_modules/proto-list": { + "version": "1.2.4", + "license": "ISC" + }, + "../../../node_modules/proxy-agent": { + "version": "6.4.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "agent-base": "^7.0.2", + "debug": "^4.3.4", + "http-proxy-agent": "^7.0.1", + "https-proxy-agent": "^7.0.3", + "lru-cache": "^7.14.1", + "pac-proxy-agent": "^7.0.1", + "proxy-from-env": "^1.1.0", + "socks-proxy-agent": "^8.0.2" + }, + "engines": { + "node": ">= 14" + } + }, + "../../../node_modules/proxy-agent/node_modules/agent-base": { + "version": "7.1.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "../../../node_modules/proxy-agent/node_modules/http-proxy-agent": { + "version": "7.0.2", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "../../../node_modules/proxy-agent/node_modules/https-proxy-agent": { + "version": "7.0.4", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "../../../node_modules/proxy-agent/node_modules/lru-cache": { + "version": "7.18.3", + "dev": true, + "license": "ISC", + "optional": true, + "peer": true, + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/proxy-from-env": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/psl": { + "version": "1.9.0", + "license": "MIT" + }, + "../../../node_modules/pump": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "../../../node_modules/punycode": { + "version": "2.3.1", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "../../../node_modules/puppeteer-core": { + "version": "20.9.0", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "peer": true, + "dependencies": { + "@puppeteer/browsers": "1.4.6", + "chromium-bidi": "0.4.16", + "cross-fetch": "4.0.0", + "debug": "4.3.4", + "devtools-protocol": "0.0.1147663", + "ws": "8.13.0" + }, + "engines": { + "node": ">=16.3.0" + }, + "peerDependencies": { + "typescript": ">= 4.7.4" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "../../../node_modules/puppeteer-core/node_modules/devtools-protocol": { + "version": "0.0.1147663", + "dev": true, + "license": "BSD-3-Clause", + "optional": true, + "peer": true + }, + "../../../node_modules/puppeteer-core/node_modules/ws": { + "version": "8.13.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "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_modules/qs": { + "version": "6.5.3", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.6" + } + }, + "../../../node_modules/query-selector-shadow-dom": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/querystringify": { + "version": "2.2.0", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/queue-microtask": { + "version": "1.2.3", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "../../../node_modules/queue-tick": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/quick-lru": { + "version": "5.1.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/randombytes": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "../../../node_modules/react-is": { + "version": "18.2.0", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/readable-stream": { + "version": "2.3.8", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "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" + } + }, + "../../../node_modules/readable-stream/node_modules/isarray": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/readable-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/readdir-glob": { + "version": "1.1.3", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "peer": true, + "dependencies": { + "minimatch": "^5.1.0" + } + }, + "../../../node_modules/readdir-glob/node_modules/minimatch": { + "version": "5.1.6", + "dev": true, + "license": "ISC", + "optional": true, + "peer": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "../../../node_modules/regexp.prototype.flags": { + "version": "1.5.1", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "set-function-name": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/request": { + "version": "2.88.2", + "license": "Apache-2.0", + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "../../../node_modules/request-promise-core": { + "version": "1.1.4", + "license": "ISC", + "dependencies": { + "lodash": "^4.17.19" + }, + "engines": { + "node": ">=0.10.0" + }, + "peerDependencies": { + "request": "^2.34" + } + }, + "../../../node_modules/request-promise-native": { + "version": "1.0.9", + "license": "ISC", + "dependencies": { + "request-promise-core": "1.1.4", + "stealthy-require": "^1.1.1", + "tough-cookie": "^2.3.3" + }, + "engines": { + "node": ">=0.12.0" + }, + "peerDependencies": { + "request": "^2.34" + } + }, + "../../../node_modules/request-promise-native/node_modules/tough-cookie": { + "version": "2.5.0", + "license": "BSD-3-Clause", + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "../../../node_modules/request/node_modules/form-data": { + "version": "2.3.3", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "../../../node_modules/request/node_modules/tough-cookie": { + "version": "2.5.0", + "license": "BSD-3-Clause", + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "../../../node_modules/require-directory": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "../../../node_modules/requires-port": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/resolve": { + "version": "1.22.8", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/resolve-alpn": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/resolve-from": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "../../../node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, + "../../../node_modules/responselike": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "lowercase-keys": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/resq": { + "version": "1.11.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "fast-deep-equal": "^2.0.1" + } + }, + "../../../node_modules/resq/node_modules/fast-deep-equal": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/reusify": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "../../../node_modules/rgb2hex": { + "version": "0.2.5", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/rimraf": { + "version": "3.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "../../../node_modules/rimraf/node_modules/brace-expansion": { + "version": "1.1.11", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "../../../node_modules/rimraf/node_modules/glob": { + "version": "7.2.3", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "../../../node_modules/rimraf/node_modules/minimatch": { + "version": "3.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "../../../node_modules/rollup": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.19.0.tgz", + "integrity": "sha512-5r7EYSQIowHsK4eTZ0Y81qpZuJz+MUuYeqmmYmRMl1nwhdmbiYqt5jwzf6u7wyOzJgYqtCRMtVRKOtHANBz7rA==", + "dev": true, + "dependencies": { + "@types/estree": "1.0.5" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.19.0", + "@rollup/rollup-android-arm64": "4.19.0", + "@rollup/rollup-darwin-arm64": "4.19.0", + "@rollup/rollup-darwin-x64": "4.19.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.19.0", + "@rollup/rollup-linux-arm-musleabihf": "4.19.0", + "@rollup/rollup-linux-arm64-gnu": "4.19.0", + "@rollup/rollup-linux-arm64-musl": "4.19.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.19.0", + "@rollup/rollup-linux-riscv64-gnu": "4.19.0", + "@rollup/rollup-linux-s390x-gnu": "4.19.0", + "@rollup/rollup-linux-x64-gnu": "4.19.0", + "@rollup/rollup-linux-x64-musl": "4.19.0", + "@rollup/rollup-win32-arm64-msvc": "4.19.0", + "@rollup/rollup-win32-ia32-msvc": "4.19.0", + "@rollup/rollup-win32-x64-msvc": "4.19.0", + "fsevents": "~2.3.2" + } + }, + "../../../node_modules/run-parallel": { + "version": "1.2.0", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "../../../node_modules/safaridriver": { + "version": "0.1.2", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/safe-array-concat": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.5", + "get-intrinsic": "^1.2.2", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/safe-buffer": { + "version": "5.2.1", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "../../../node_modules/safe-regex-test": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.5", + "get-intrinsic": "^1.2.2", + "is-regex": "^1.1.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/safer-buffer": { + "version": "2.1.2", + "license": "MIT" + }, + "../../../node_modules/sax": { + "version": "1.3.0", + "license": "ISC" + }, + "../../../node_modules/saxes": { + "version": "5.0.1", + "dev": true, + "license": "ISC", + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=10" + } + }, + "../../../node_modules/schema-utils": { + "version": "3.3.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "../../../node_modules/semver": { + "version": "7.5.4", + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "../../../node_modules/semver/node_modules/lru-cache": { + "version": "6.0.0", + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "../../../node_modules/serialize-error": { + "version": "11.0.3", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "type-fest": "^2.12.2" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/serialize-javascript": { + "version": "6.0.2", + "dev": true, + "license": "BSD-3-Clause", + "optional": true, + "peer": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "../../../node_modules/set-function-length": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.1", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.2", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "../../../node_modules/set-function-name": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.0.1", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "../../../node_modules/setimmediate": { + "version": "1.0.5", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/shallow-clone": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "../../../node_modules/shallow-clone/node_modules/kind-of": { + "version": "6.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "../../../node_modules/shebang-command": { + "version": "2.0.0", + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "../../../node_modules/shebang-regex": { + "version": "3.0.0", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "../../../node_modules/side-channel": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/siginfo": { + "version": "2.0.0", + "dev": true, + "license": "ISC" + }, + "../../../node_modules/signal-exit": { + "version": "4.1.0", + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "../../../node_modules/sirv": { + "version": "2.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@polka/url": "^1.0.0-next.24", + "mrmime": "^2.0.0", + "totalist": "^3.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "../../../node_modules/smart-buffer": { + "version": "4.2.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "../../../node_modules/socks": { + "version": "2.7.3", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "ip-address": "^9.0.5", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" + } + }, + "../../../node_modules/socks-proxy-agent": { + "version": "8.0.2", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "agent-base": "^7.0.2", + "debug": "^4.3.4", + "socks": "^2.7.1" + }, + "engines": { + "node": ">= 14" + } + }, + "../../../node_modules/socks-proxy-agent/node_modules/agent-base": { + "version": "7.1.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "../../../node_modules/source-map": { + "version": "0.6.1", + "license": "BSD-3-Clause", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "../../../node_modules/source-map-js": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "../../../node_modules/source-map-support": { + "version": "0.5.21", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "../../../node_modules/split2": { + "version": "4.2.0", + "dev": true, + "license": "ISC", + "optional": true, + "peer": true, + "engines": { + "node": ">= 10.x" + } + }, + "../../../node_modules/sprintf-js": { + "version": "1.1.3", + "dev": true, + "license": "BSD-3-Clause", + "optional": true, + "peer": true + }, + "../../../node_modules/sshpk": { + "version": "1.18.0", + "license": "MIT", + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "../../../node_modules/stackback": { + "version": "0.0.2", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/std-env": { + "version": "3.7.0", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/stealthy-require": { + "version": "1.1.1", + "license": "ISC", + "engines": { + "node": ">=0.10.0" + } + }, + "../../../node_modules/streamx": { + "version": "2.15.6", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "fast-fifo": "^1.1.0", + "queue-tick": "^1.0.1" + } + }, + "../../../node_modules/string_decoder": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "../../../node_modules/string_decoder/node_modules/safe-buffer": { + "version": "5.1.2", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/string-width": { + "version": "5.1.2", + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "../../../node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "license": "MIT" + }, + "../../../node_modules/string-width/node_modules/ansi-regex": { + "version": "6.0.1", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "../../../node_modules/string-width/node_modules/strip-ansi": { + "version": "7.1.0", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "../../../node_modules/string.prototype.trim": { + "version": "1.2.8", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/string.prototype.trimend": { + "version": "1.0.7", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/string.prototype.trimstart": { + "version": "1.0.7", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/strip-ansi": { + "version": "6.0.1", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "../../../node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "../../../node_modules/strip-bom": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "../../../node_modules/strip-final-newline": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/strip-json-comments": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/strip-literal": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "js-tokens": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "../../../node_modules/strip-literal/node_modules/js-tokens": { + "version": "8.0.3", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "../../../node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/symbol-tree": { + "version": "3.2.4", + "license": "MIT" + }, + "../../../node_modules/tapable": { + "version": "2.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "../../../node_modules/tar-fs": { + "version": "3.0.5", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "pump": "^3.0.0", + "tar-stream": "^3.1.5" + }, + "optionalDependencies": { + "bare-fs": "^2.1.1", + "bare-path": "^2.1.0" + } + }, + "../../../node_modules/tar-stream": { + "version": "3.1.7", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "b4a": "^1.6.4", + "fast-fifo": "^1.2.0", + "streamx": "^2.15.0" + } + }, + "../../../node_modules/terser": { + "version": "5.29.1", + "dev": true, + "license": "BSD-2-Clause", + "optional": true, + "peer": true, + "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" + }, + "engines": { + "node": ">=10" + } + }, + "../../../node_modules/terser-webpack-plugin": { + "version": "5.3.10", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.20", + "jest-worker": "^27.4.5", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.1", + "terser": "^5.26.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "../../../node_modules/terser/node_modules/commander": { + "version": "2.20.3", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/text-table": { + "version": "0.2.0", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/through": { + "version": "2.3.8", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/tinybench": { + "version": "2.6.0", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/tinypool": { + "version": "0.8.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "../../../node_modules/tinyspy": { + "version": "2.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "../../../node_modules/to-regex-range": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "../../../node_modules/totalist": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "../../../node_modules/tough-cookie": { + "version": "4.1.3", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.2.0", + "url-parse": "^1.5.3" + }, + "engines": { + "node": ">=6" + } + }, + "../../../node_modules/tr46": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "../../../node_modules/traverse": { + "version": "0.3.9", + "dev": true, + "license": "MIT/X11", + "optional": true, + "peer": true + }, + "../../../node_modules/tsconfig-paths": { + "version": "3.15.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "../../../node_modules/tsconfig-paths/node_modules/json5": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "../../../node_modules/tslib": { + "version": "2.6.2", + "dev": true, + "license": "0BSD", + "optional": true, + "peer": true + }, + "../../../node_modules/tsx": { + "version": "4.7.1", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "~0.19.10", + "get-tsconfig": "^4.7.2" + }, + "bin": { + "tsx": "dist/cli.mjs" + }, + "engines": { + "node": ">=18.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + } + }, + "../../../node_modules/tsx/node_modules/@esbuild/aix-ppc64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz", + "integrity": "sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/tsx/node_modules/@esbuild/android-arm": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.12.tgz", + "integrity": "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/tsx/node_modules/@esbuild/android-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz", + "integrity": "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/tsx/node_modules/@esbuild/android-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.12.tgz", + "integrity": "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/tsx/node_modules/@esbuild/darwin-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz", + "integrity": "sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/tsx/node_modules/@esbuild/darwin-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz", + "integrity": "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/tsx/node_modules/@esbuild/freebsd-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz", + "integrity": "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/tsx/node_modules/@esbuild/freebsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz", + "integrity": "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/tsx/node_modules/@esbuild/linux-arm": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz", + "integrity": "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/tsx/node_modules/@esbuild/linux-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz", + "integrity": "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/tsx/node_modules/@esbuild/linux-ia32": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz", + "integrity": "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/tsx/node_modules/@esbuild/linux-loong64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz", + "integrity": "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/tsx/node_modules/@esbuild/linux-mips64el": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz", + "integrity": "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/tsx/node_modules/@esbuild/linux-ppc64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz", + "integrity": "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/tsx/node_modules/@esbuild/linux-riscv64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz", + "integrity": "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/tsx/node_modules/@esbuild/linux-s390x": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz", + "integrity": "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/tsx/node_modules/@esbuild/linux-x64": { + "version": "0.19.12", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/tsx/node_modules/@esbuild/netbsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz", + "integrity": "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/tsx/node_modules/@esbuild/openbsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz", + "integrity": "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/tsx/node_modules/@esbuild/sunos-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz", + "integrity": "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/tsx/node_modules/@esbuild/win32-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz", + "integrity": "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/tsx/node_modules/@esbuild/win32-ia32": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz", + "integrity": "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/tsx/node_modules/@esbuild/win32-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz", + "integrity": "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/tsx/node_modules/esbuild": { + "version": "0.19.12", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.19.12", + "@esbuild/android-arm": "0.19.12", + "@esbuild/android-arm64": "0.19.12", + "@esbuild/android-x64": "0.19.12", + "@esbuild/darwin-arm64": "0.19.12", + "@esbuild/darwin-x64": "0.19.12", + "@esbuild/freebsd-arm64": "0.19.12", + "@esbuild/freebsd-x64": "0.19.12", + "@esbuild/linux-arm": "0.19.12", + "@esbuild/linux-arm64": "0.19.12", + "@esbuild/linux-ia32": "0.19.12", + "@esbuild/linux-loong64": "0.19.12", + "@esbuild/linux-mips64el": "0.19.12", + "@esbuild/linux-ppc64": "0.19.12", + "@esbuild/linux-riscv64": "0.19.12", + "@esbuild/linux-s390x": "0.19.12", + "@esbuild/linux-x64": "0.19.12", + "@esbuild/netbsd-x64": "0.19.12", + "@esbuild/openbsd-x64": "0.19.12", + "@esbuild/sunos-x64": "0.19.12", + "@esbuild/win32-arm64": "0.19.12", + "@esbuild/win32-ia32": "0.19.12", + "@esbuild/win32-x64": "0.19.12" + } + }, + "../../../node_modules/tunnel-agent": { + "version": "0.6.0", + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "../../../node_modules/tweetnacl": { + "version": "0.14.5", + "license": "Unlicense" + }, + "../../../node_modules/type-check": { + "version": "0.4.0", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "../../../node_modules/type-detect": { + "version": "4.0.8", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "../../../node_modules/type-fest": { + "version": "2.19.0", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "optional": true, + "peer": true, + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/typed-array-buffer": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + } + }, + "../../../node_modules/typed-array-byte-length": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "has-proto": "^1.0.1", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/typed-array-byte-offset": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "has-proto": "^1.0.1", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/typed-array-length": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "is-typed-array": "^1.1.9" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/typescript": { + "version": "5.3.3", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "../../../node_modules/ufo": { + "version": "1.3.2", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/unbox-primitive": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/unbzip2-stream": { + "version": "1.4.3", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "buffer": "^5.2.1", + "through": "^2.3.8" + } + }, + "../../../node_modules/unbzip2-stream/node_modules/buffer": { + "version": "5.7.1", + "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, + "peer": true, + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "../../../node_modules/undici-types": { + "version": "5.26.5", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/universalify": { + "version": "0.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, + "../../../node_modules/unzipper": { + "version": "0.10.14", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "big-integer": "^1.6.17", + "binary": "~0.3.0", + "bluebird": "~3.4.1", + "buffer-indexof-polyfill": "~1.0.0", + "duplexer2": "~0.1.4", + "fstream": "^1.0.12", + "graceful-fs": "^4.2.2", + "listenercount": "~1.0.1", + "readable-stream": "~2.3.6", + "setimmediate": "~1.0.4" + } + }, + "../../../node_modules/update-browserslist-db": { + "version": "1.0.13", + "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", + "optional": true, + "peer": true, + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "../../../node_modules/uri-js": { + "version": "4.4.1", + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "../../../node_modules/url-parse": { + "version": "1.5.10", + "dev": true, + "license": "MIT", + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, + "../../../node_modules/userhome": { + "version": "1.0.0", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "../../../node_modules/util-deprecate": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/uuid": { + "version": "3.4.0", + "license": "MIT", + "bin": { + "uuid": "bin/uuid" + } + }, + "../../../node_modules/verror": { + "version": "1.10.0", + "engines": [ + "node >=0.6.0" + ], + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "../../../node_modules/verror/node_modules/core-util-is": { + "version": "1.0.2", + "license": "MIT" + }, + "../../../node_modules/vite": { + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.4.tgz", + "integrity": "sha512-Cw+7zL3ZG9/NZBB8C+8QbQZmR54GwqIz+WMI4b3JgdYJvX+ny9AjJXqkGQlDXSXRP9rP0B4tbciRMOVEKulVOA==", + "dev": true, + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.39", + "rollup": "^4.13.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "../../../node_modules/vite-node": { + "version": "1.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "cac": "^6.7.14", + "debug": "^4.3.4", + "pathe": "^1.1.1", + "picocolors": "^1.0.0", + "vite": "^5.0.0" + }, + "bin": { + "vite-node": "vite-node.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "../../../node_modules/vite/node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/vite/node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "../../../node_modules/vitest": { + "version": "1.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/expect": "1.3.1", + "@vitest/runner": "1.3.1", + "@vitest/snapshot": "1.3.1", + "@vitest/spy": "1.3.1", + "@vitest/utils": "1.3.1", + "acorn-walk": "^8.3.2", + "chai": "^4.3.10", + "debug": "^4.3.4", + "execa": "^8.0.1", + "local-pkg": "^0.5.0", + "magic-string": "^0.30.5", + "pathe": "^1.1.1", + "picocolors": "^1.0.0", + "std-env": "^3.5.0", + "strip-literal": "^2.0.0", + "tinybench": "^2.5.1", + "tinypool": "^0.8.2", + "vite": "^5.0.0", + "vite-node": "1.3.1", + "why-is-node-running": "^2.2.2" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@types/node": "^18.0.0 || >=20.0.0", + "@vitest/browser": "1.3.1", + "@vitest/ui": "1.3.1", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } + } + }, + "../../../node_modules/vitest/node_modules/acorn-walk": { + "version": "8.3.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "../../../node_modules/w3c-hr-time": { + "version": "1.0.2", + "license": "MIT", + "dependencies": { + "browser-process-hrtime": "^1.0.0" + } + }, + "../../../node_modules/w3c-xmlserializer": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "xml-name-validator": "^3.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "../../../node_modules/wait-port": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "chalk": "^4.1.2", + "commander": "^9.3.0", + "debug": "^4.3.4" + }, + "bin": { + "wait-port": "bin/wait-port.js" + }, + "engines": { + "node": ">=10" + } + }, + "../../../node_modules/watchpack": { + "version": "2.4.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "../../../node_modules/web-streams-polyfill": { + "version": "3.3.3", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 8" + } + }, + "../../../node_modules/webdriver": { + "version": "8.32.3", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@types/node": "^20.1.0", + "@types/ws": "^8.5.3", + "@wdio/config": "8.32.3", + "@wdio/logger": "8.28.0", + "@wdio/protocols": "8.32.0", + "@wdio/types": "8.32.2", + "@wdio/utils": "8.32.3", + "deepmerge-ts": "^5.1.0", + "got": "^12.6.1", + "ky": "^0.33.0", + "ws": "^8.8.0" + }, + "engines": { + "node": "^16.13 || >=18" + } + }, + "../../../node_modules/webdriverio": { + "version": "8.32.3", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@types/node": "^20.1.0", + "@wdio/config": "8.32.3", + "@wdio/logger": "8.28.0", + "@wdio/protocols": "8.32.0", + "@wdio/repl": "8.24.12", + "@wdio/types": "8.32.2", + "@wdio/utils": "8.32.3", + "archiver": "^6.0.0", + "aria-query": "^5.0.0", + "css-shorthand-properties": "^1.1.1", + "css-value": "^0.0.1", + "devtools-protocol": "^0.0.1262051", + "grapheme-splitter": "^1.0.2", + "import-meta-resolve": "^4.0.0", + "is-plain-obj": "^4.1.0", + "lodash.clonedeep": "^4.5.0", + "lodash.zip": "^4.2.0", + "minimatch": "^9.0.0", + "puppeteer-core": "^20.9.0", + "query-selector-shadow-dom": "^1.0.0", + "resq": "^1.9.1", + "rgb2hex": "0.2.5", + "serialize-error": "^11.0.1", + "webdriver": "8.32.3" + }, + "engines": { + "node": "^16.13 || >=18" + }, + "peerDependencies": { + "devtools": "^8.14.0" + }, + "peerDependenciesMeta": { + "devtools": { + "optional": true + } + } + }, + "../../../node_modules/webidl-conversions": { + "version": "6.1.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=10.4" + } + }, + "../../../node_modules/webpack": { + "version": "5.90.3", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@types/eslint-scope": "^3.7.3", + "@types/estree": "^1.0.5", + "@webassemblyjs/ast": "^1.11.5", + "@webassemblyjs/wasm-edit": "^1.11.5", + "@webassemblyjs/wasm-parser": "^1.11.5", + "acorn": "^8.7.1", + "acorn-import-assertions": "^1.9.0", + "browserslist": "^4.21.10", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.15.0", + "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.9", + "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": "^3.2.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.10", + "watchpack": "^2.4.0", + "webpack-sources": "^3.2.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "../../../node_modules/webpack-bundle-analyzer": { + "version": "4.10.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@discoveryjs/json-ext": "0.5.7", + "acorn": "^8.0.4", + "acorn-walk": "^8.0.0", + "commander": "^7.2.0", + "debounce": "^1.2.1", + "escape-string-regexp": "^4.0.0", + "gzip-size": "^6.0.0", + "html-escaper": "^2.0.2", + "is-plain-object": "^5.0.0", + "opener": "^1.5.2", + "picocolors": "^1.0.0", + "sirv": "^2.0.3", + "ws": "^7.3.1" + }, + "bin": { + "webpack-bundle-analyzer": "lib/bin/analyzer.js" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "../../../node_modules/webpack-bundle-analyzer/node_modules/acorn-walk": { + "version": "8.3.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "../../../node_modules/webpack-bundle-analyzer/node_modules/commander": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "../../../node_modules/webpack-bundle-analyzer/node_modules/is-plain-object": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "../../../node_modules/webpack-bundle-analyzer/node_modules/ws": { + "version": "7.5.9", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "../../../node_modules/webpack-merge": { + "version": "5.10.0", + "dev": true, + "license": "MIT", + "dependencies": { + "clone-deep": "^4.0.1", + "flat": "^5.0.2", + "wildcard": "^2.0.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "../../../node_modules/webpack/node_modules/eslint-scope": { + "version": "5.1.1", + "dev": true, + "license": "BSD-2-Clause", + "optional": true, + "peer": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "../../../node_modules/webpack/node_modules/estraverse": { + "version": "4.3.0", + "dev": true, + "license": "BSD-2-Clause", + "optional": true, + "peer": true, + "engines": { + "node": ">=4.0" + } + }, + "../../../node_modules/webpack/node_modules/events": { + "version": "3.3.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=0.8.x" + } + }, + "../../../node_modules/webpack/node_modules/webpack-sources": { + "version": "3.2.3", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=10.13.0" + } + }, + "../../../node_modules/whatwg-encoding": { + "version": "1.0.5", + "license": "MIT", + "dependencies": { + "iconv-lite": "0.4.24" + } + }, + "../../../node_modules/whatwg-mimetype": { + "version": "2.3.0", + "license": "MIT" + }, + "../../../node_modules/whatwg-url": { + "version": "9.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "tr46": "^2.1.0", + "webidl-conversions": "^6.1.0" + }, + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/which": { + "version": "2.0.2", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "../../../node_modules/which-boxed-primitive": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/which-typed-array": { + "version": "1.1.13", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.4", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/why-is-node-running": { + "version": "2.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "../../../node_modules/wildcard": { + "version": "2.0.1", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/word-wrap": { + "version": "1.2.5", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "../../../node_modules/wrap-ansi": { + "version": "8.1.0", + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "../../../node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "../../../node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "license": "MIT" + }, + "../../../node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "../../../node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "6.0.1", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "../../../node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "../../../node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "7.1.0", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "../../../node_modules/wrappy": { + "version": "1.0.2", + "dev": true, + "license": "ISC" + }, + "../../../node_modules/ws": { + "version": "8.16.0", + "dev": true, + "license": "MIT", + "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_modules/xml-name-validator": { + "version": "3.0.0", + "license": "Apache-2.0" + }, + "../../../node_modules/xmlchars": { + "version": "2.2.0", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/xmldom": { + "version": "0.1.31", + "license": "(LGPL-2.0 or MIT)", + "engines": { + "node": ">=0.1" + } + }, + "../../../node_modules/y18n": { + "version": "5.0.8", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "../../../node_modules/yallist": { + "version": "4.0.0", + "license": "ISC" + }, + "../../../node_modules/yargs": { + "version": "17.7.2", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/yargs-parser": { + "version": "21.1.1", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/yargs/node_modules/emoji-regex": { + "version": "8.0.0", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/yargs/node_modules/string-width": { + "version": "4.2.3", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "../../../node_modules/yauzl": { + "version": "2.10.0", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, + "../../../node_modules/yocto-queue": { + "version": "0.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/zip-stream": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "archiver-utils": "^4.0.1", + "compress-commons": "^5.0.1", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "../../../node_modules/zip-stream/node_modules/readable-stream": { + "version": "3.6.2", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@module-federation/runtime": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@module-federation/runtime/-/runtime-0.5.1.tgz", + "integrity": "sha512-xgiMUWwGLWDrvZc9JibuEbXIbhXg6z2oUkemogSvQ4LKvrl/n0kbqP1Blk669mXzyWbqtSp6PpvNdwaE1aN5xQ==", + "dev": true, + "dependencies": { + "@module-federation/sdk": "0.5.1" + } + }, + "node_modules/@module-federation/runtime-tools": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@module-federation/runtime-tools/-/runtime-tools-0.5.1.tgz", + "integrity": "sha512-nfBedkoZ3/SWyO0hnmaxuz0R0iGPSikHZOAZ0N/dVSQaIzlffUo35B5nlC2wgWIc0JdMZfkwkjZRrnuuDIJbzg==", + "dev": true, + "dependencies": { + "@module-federation/runtime": "0.5.1", + "@module-federation/webpack-bundler-runtime": "0.5.1" + } + }, + "node_modules/@module-federation/sdk": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@module-federation/sdk/-/sdk-0.5.1.tgz", + "integrity": "sha512-exvchtjNURJJkpqjQ3/opdbfeT2wPKvrbnGnyRkrwW5o3FH1LaST1tkiNviT6OXTexGaVc2DahbdniQHVtQ7pA==", + "dev": true + }, + "node_modules/@module-federation/webpack-bundler-runtime": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@module-federation/webpack-bundler-runtime/-/webpack-bundler-runtime-0.5.1.tgz", + "integrity": "sha512-mMhRFH0k2VjwHt3Jol9JkUsmI/4XlrAoBG3E0o7HoyoPYv1UFOWyqAflfANcUPgbYpvqmyLzDcO+3IT36LXnrA==", + "dev": true, + "dependencies": { + "@module-federation/runtime": "0.5.1", + "@module-federation/sdk": "0.5.1" + } + }, + "node_modules/@rsbuild/core": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@rsbuild/core/-/core-1.1.9.tgz", + "integrity": "sha512-mHZveEwlTtW9nxWa+T0xUm6ssm+HkDYZ0NENLfWMUmsL0LjMJrpQzRlbD+p5+9Uf+KXUo3Dbtv0ScA+p7cuGTg==", + "dev": true, + "dependencies": { + "@rspack/core": "~1.1.5", + "@rspack/lite-tapable": "~1.0.1", + "@swc/helpers": "^0.5.15", + "core-js": "~3.39.0" + }, + "bin": { + "rsbuild": "bin/rsbuild.js" + }, + "engines": { + "node": ">=16.7.0" + } + }, + "node_modules/@rspack/binding": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rspack/binding/-/binding-1.1.5.tgz", + "integrity": "sha512-RsSkgi56Q5XUXut0qweLSE1C4Ogcm7g/ueKoOgsbHAYVKrCs9/dTFlPHWSIAaI7QWh0GWEePR/MM2O2HIu+1rw==", + "dev": true, + "optionalDependencies": { + "@rspack/binding-darwin-arm64": "1.1.5", + "@rspack/binding-darwin-x64": "1.1.5", + "@rspack/binding-linux-arm64-gnu": "1.1.5", + "@rspack/binding-linux-arm64-musl": "1.1.5", + "@rspack/binding-linux-x64-gnu": "1.1.5", + "@rspack/binding-linux-x64-musl": "1.1.5", + "@rspack/binding-win32-arm64-msvc": "1.1.5", + "@rspack/binding-win32-ia32-msvc": "1.1.5", + "@rspack/binding-win32-x64-msvc": "1.1.5" + } + }, + "node_modules/@rspack/binding-darwin-arm64": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rspack/binding-darwin-arm64/-/binding-darwin-arm64-1.1.5.tgz", + "integrity": "sha512-eEynmyPPl+OGYQ9LRFwiQosyRfcca3OQB73akqY4mqDRl39OyiBjq7347DLHJysgbm9z+B1bsiLuh2xc6mdclQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rspack/binding-darwin-x64": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rspack/binding-darwin-x64/-/binding-darwin-x64-1.1.5.tgz", + "integrity": "sha512-I6HPRgogewU5v1OKe3noEzq2U1FCEYAbW+smy+lPvpTW+3X6PlVMzTT4oelhB0EXDQ+KxjXH9KpOKON1hg/JGg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rspack/binding-linux-arm64-gnu": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rspack/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.1.5.tgz", + "integrity": "sha512-LQnqucNa6Dr6y3By+/M2ARO4jDR3AM+PuCsHgzlYT0RDRLS+Ow3f50WbNBf7eI/DhrEA0aucYL3sz1ljguB3EA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rspack/binding-linux-arm64-musl": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rspack/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.1.5.tgz", + "integrity": "sha512-b9L/9HJxrWY4cezPWqgj28I9Xe2XxwLHu8x0CMGobwF2XKR0QQVLAst38RW/EusJ8TURdyvNEOuRZlWEIJuYOw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rspack/binding-linux-x64-gnu": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rspack/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.1.5.tgz", + "integrity": "sha512-0az52ZXTg/ErCGC1v/oFLWByKAiXvng4euv+prwMWF6p1pA7lfLRLzdibDFO4KgC16Zlfcg3hqs7YikLng4x+w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rspack/binding-linux-x64-musl": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rspack/binding-linux-x64-musl/-/binding-linux-x64-musl-1.1.5.tgz", + "integrity": "sha512-EF/LJTtCTkuti2gJnCyvXHC5Q2L5M4+RXm5kj9Bfu/t0Zmmfe6Jd5QUsifgogioeL0ZsH/Pou5QiiVcOFcqFKQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rspack/binding-win32-arm64-msvc": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rspack/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.1.5.tgz", + "integrity": "sha512-VEqhK6HwIHby6gtOkxIx66SkqYndiaP1ddZ3X39RLE40TY3KlNgfG/SzbN9J5Qb+8jjq3ogV8n50+wLEGkhiWw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rspack/binding-win32-ia32-msvc": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rspack/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-1.1.5.tgz", + "integrity": "sha512-Yi2BwYehc5/sRVgI7zTGYJKjnV8UszAJt/stWdFHaq82chHiuuF/tQd1WcBUq0Iin9ylBMo16mRJAuFkFmJ74Q==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rspack/binding-win32-x64-msvc": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rspack/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.1.5.tgz", + "integrity": "sha512-4UArXYqJO1Ni7TmCw1T11JnrwfpoThDdiQ9k1P1voBWK3bDahPEBOptk9ZPu2+ZuRX8hFrvumRKkLY3oy7fTMw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rspack/core": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rspack/core/-/core-1.1.5.tgz", + "integrity": "sha512-/FmxDeMuW8fJkhz8fHuCu7OiJHFKW78xclEu7LkEujWl4PqJgdWjUL/6FWIj50spRwj6PRfuc31hFSL4hbNfCA==", + "dev": true, + "dependencies": { + "@module-federation/runtime-tools": "0.5.1", + "@rspack/binding": "1.1.5", + "@rspack/lite-tapable": "1.0.1", + "caniuse-lite": "^1.0.30001616" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@swc/helpers": ">=0.5.1" + }, + "peerDependenciesMeta": { + "@swc/helpers": { + "optional": true + } + } + }, + "node_modules/@rspack/lite-tapable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@rspack/lite-tapable/-/lite-tapable-1.0.1.tgz", + "integrity": "sha512-VynGOEsVw2s8TAlLf/uESfrgfrq2+rcXB1muPJYBWbsm1Oa6r5qVQhjA5ggM6z/coYPrsVMgovl3Ff7Q7OCp1w==", + "dev": true, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@swc/helpers": { + "version": "0.5.15", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz", + "integrity": "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==", + "dev": true, + "dependencies": { + "tslib": "^2.8.0" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001687", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001687.tgz", + "integrity": "sha512-0S/FDhf4ZiqrTUiQ39dKeUjYRjkv7lOZU1Dgif2rIqrTzX/1wV2hfKu9TOm1IHkdSijfLswxTFzl/cvir+SLSQ==", + "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/core-js": { + "version": "3.39.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.39.0.tgz", + "integrity": "sha512-raM0ew0/jJUqkJ0E6e8UDtl+y/7ktFivgWvqw8dNSQeNWoSDLvQ1H/RN3aPXB9tBd4/FhyR4RDPGhsNIMsAn7g==", + "dev": true, + "hasInstallScript": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/neuroglancer": { + "resolved": "../../..", + "link": true + }, + "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==", + "dev": true + } + } +} diff --git a/examples/rsbuild/rsbuild-project-source/package.json b/examples/rsbuild/rsbuild-project-source/package.json new file mode 100644 index 0000000000..ae76056a7f --- /dev/null +++ b/examples/rsbuild/rsbuild-project-source/package.json @@ -0,0 +1,23 @@ +{ + "name": "neuroglancer-rsbuild-project-source", + "version": "0.0.0", + "private": true, + "description": "Test of an rsbuild project that depends on Neuroglancer.", + "scripts": { + "build": "rsbuild build", + "dev-server": "rsbuild dev" + }, + "dependencies": { + "neuroglancer": "file:../../.." + }, + "browserslist": [ + "last 2 Chrome versions", + "last 2 Firefox versions", + "last 2 Safari versions" + ], + "license": "Apache-2.0", + "devDependencies": { + "@rsbuild/core": "^1.1.9" + }, + "type": "module" +} diff --git a/examples/rsbuild/rsbuild-project-source/rsbuild.config.ts b/examples/rsbuild/rsbuild-project-source/rsbuild.config.ts new file mode 100644 index 0000000000..459ddfc6d6 --- /dev/null +++ b/examples/rsbuild/rsbuild-project-source/rsbuild.config.ts @@ -0,0 +1,58 @@ +import { defineConfig } from "@rsbuild/core"; + +export default defineConfig({ + html: { + title: "rsbuild neuroglancer test", + scriptLoading: "module", + mountId: "neuroglancer-container", + }, + output: { + assetPrefix: "./", + distPath: { + js: "", + jsAsync: "", + wasm: "", + css: "", + }, + }, + tools: { + rspack: { + module: { + rules: [ + // Needed to support Neuroglancer TypeScript sources when using + // Neuroglancer source package directly. + { + test: /\.tsx?$/, + loader: "builtin:swc-loader", + options: { + jsc: { + parser: { + syntax: "typescript", + decorators: true, + }, + }, + }, + type: "javascript/auto", + }, + // Needed for .svg?raw imports used for embedding icons. + { + resourceQuery: /raw/, + type: "asset/source", + }, + // Needed for .html assets used for auth redirect pages for the brainmaps + // and bossDB data sources. Can be skipped if those data sources are + // excluded. + { + test: /\.html$/, + type: "asset/resource", + generator: { + // Filename must be preserved since exact redirect URLs must be allowlisted. + filename: "[name][ext]", + }, + }, + ], + }, + }, + }, + plugins: [], +}); diff --git a/examples/rsbuild/rsbuild-project-source/src/index.js b/examples/rsbuild/rsbuild-project-source/src/index.js new file mode 100644 index 0000000000..805818b627 --- /dev/null +++ b/examples/rsbuild/rsbuild-project-source/src/index.js @@ -0,0 +1,3 @@ +import "neuroglancer"; +import { setupDefaultViewer } from "neuroglancer/unstable/ui/default_viewer_setup.js"; +setupDefaultViewer(); diff --git a/examples/rspack/rspack-project-built/.gitignore b/examples/rspack/rspack-project-built/.gitignore new file mode 100644 index 0000000000..b0a5c349ca --- /dev/null +++ b/examples/rspack/rspack-project-built/.gitignore @@ -0,0 +1,2 @@ +/node_modules/ +/dist/ diff --git a/examples/rspack/rspack-project-built/README.md b/examples/rspack/rspack-project-built/README.md new file mode 100644 index 0000000000..4d92187a2f --- /dev/null +++ b/examples/rspack/rspack-project-built/README.md @@ -0,0 +1 @@ +This demonstrates a dependent project that uses webpack for bundling. diff --git a/examples/rspack/rspack-project-built/package-lock.json b/examples/rspack/rspack-project-built/package-lock.json new file mode 100644 index 0000000000..b434075015 --- /dev/null +++ b/examples/rspack/rspack-project-built/package-lock.json @@ -0,0 +1,4346 @@ +{ + "name": "neuroglancer-rspack-project-built", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "neuroglancer-rspack-project-built", + "version": "0.0.0", + "license": "Apache-2.0", + "dependencies": { + "neuroglancer": "file:../../../dist/package" + }, + "devDependencies": { + "@rspack/cli": "^1.1.5", + "@rspack/core": "^1.1.5" + } + }, + "../../../dist/package": { + "name": "neuroglancer", + "version": "2.40.1", + "license": "Apache-2.0", + "dependencies": { + "codemirror": "^5.61.1", + "core-js": "^3.40.0", + "crc-32": "^1.2.2", + "gl-matrix": "3.1.0", + "ikonate": "github:mikolajdobrucki/ikonate#a86b4107c6ec717e7877f880a930d1ccf0b59d89", + "lodash-es": "^4.17.21", + "nifti-reader-js": "^0.6.8", + "numcodecs": "^0.3.2" + }, + "engines": { + "node": ">=22" + } + }, + "node_modules/@discoveryjs/json-ext": { + "version": "0.5.7", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.3", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.5", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.22", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "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.0.4", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-1.0.4.tgz", + "integrity": "sha512-aOcSN4MeAtFROysrbqG137b7gaDDSmVrl5mpo6sT/w+kcXpWnzhMjmY/Fh/sDx26NBxyIE7MB1seqLeCAzy9Sg==", + "dev": true, + "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" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/util": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-1.2.0.tgz", + "integrity": "sha512-4B8B+3vFsY4eo33DMKyJPlQ3sBMpPFUZK2dr3O3rXrOGKKbYG44J0XSFkDo1VOQiri5HFEhIeVvItjR2xcazmg==", + "dev": true, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@leichtgewicht/ip-codec": { + "version": "2.0.4", + "dev": true, + "license": "MIT" + }, + "node_modules/@module-federation/runtime": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@module-federation/runtime/-/runtime-0.5.1.tgz", + "integrity": "sha512-xgiMUWwGLWDrvZc9JibuEbXIbhXg6z2oUkemogSvQ4LKvrl/n0kbqP1Blk669mXzyWbqtSp6PpvNdwaE1aN5xQ==", + "dev": true, + "dependencies": { + "@module-federation/sdk": "0.5.1" + } + }, + "node_modules/@module-federation/runtime-tools": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@module-federation/runtime-tools/-/runtime-tools-0.5.1.tgz", + "integrity": "sha512-nfBedkoZ3/SWyO0hnmaxuz0R0iGPSikHZOAZ0N/dVSQaIzlffUo35B5nlC2wgWIc0JdMZfkwkjZRrnuuDIJbzg==", + "dev": true, + "dependencies": { + "@module-federation/runtime": "0.5.1", + "@module-federation/webpack-bundler-runtime": "0.5.1" + } + }, + "node_modules/@module-federation/sdk": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@module-federation/sdk/-/sdk-0.5.1.tgz", + "integrity": "sha512-exvchtjNURJJkpqjQ3/opdbfeT2wPKvrbnGnyRkrwW5o3FH1LaST1tkiNviT6OXTexGaVc2DahbdniQHVtQ7pA==", + "dev": true + }, + "node_modules/@module-federation/webpack-bundler-runtime": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@module-federation/webpack-bundler-runtime/-/webpack-bundler-runtime-0.5.1.tgz", + "integrity": "sha512-mMhRFH0k2VjwHt3Jol9JkUsmI/4XlrAoBG3E0o7HoyoPYv1UFOWyqAflfANcUPgbYpvqmyLzDcO+3IT36LXnrA==", + "dev": true, + "dependencies": { + "@module-federation/runtime": "0.5.1", + "@module-federation/sdk": "0.5.1" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@polka/url": { + "version": "1.0.0-next.28", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.28.tgz", + "integrity": "sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw==", + "dev": true + }, + "node_modules/@rspack/binding": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@rspack/binding/-/binding-1.1.6.tgz", + "integrity": "sha512-vfeBEgGOYVwqj5cQjGyvdfrr/BEihAHlyIsobL98FZjTF0uig+bj2yJUH5Ib5F0BpIUKVG3Pw0IjlUBqcVpZsQ==", + "dev": true, + "optionalDependencies": { + "@rspack/binding-darwin-arm64": "1.1.6", + "@rspack/binding-darwin-x64": "1.1.6", + "@rspack/binding-linux-arm64-gnu": "1.1.6", + "@rspack/binding-linux-arm64-musl": "1.1.6", + "@rspack/binding-linux-x64-gnu": "1.1.6", + "@rspack/binding-linux-x64-musl": "1.1.6", + "@rspack/binding-win32-arm64-msvc": "1.1.6", + "@rspack/binding-win32-ia32-msvc": "1.1.6", + "@rspack/binding-win32-x64-msvc": "1.1.6" + } + }, + "node_modules/@rspack/binding-darwin-arm64": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@rspack/binding-darwin-arm64/-/binding-darwin-arm64-1.1.6.tgz", + "integrity": "sha512-x9dxm2yyiMuL1FBwvWNNMs2/mEUJmRoSRgYb8pblR7HDaTRORrjBFCqhaYlGyAqtQaeUy7o2VAQlE0BavIiFYA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rspack/binding-darwin-x64": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@rspack/binding-darwin-x64/-/binding-darwin-x64-1.1.6.tgz", + "integrity": "sha512-o0seilveftGiDjy3VPxug20HmAgYyQbNEuagR3i93/t/PT/eWXHnik+C1jjwqcivZL1Zllqvy4tbZw393aROEQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rspack/binding-linux-arm64-gnu": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@rspack/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.1.6.tgz", + "integrity": "sha512-4atnoknJx/c3KaQElsMIxHMpPf2jcRRdWsH/SdqJIRSrkWWakMK9Yv4TFwH680I4HDTMf1XLboMVScHzW8e+Mg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rspack/binding-linux-arm64-musl": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@rspack/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.1.6.tgz", + "integrity": "sha512-7QMtwUtgFpt3/Y3/X18fSyN+kk4H8ZnZ8tDzQskVWc/j2AQYShZq56XQYqrhClzwujcCVAHauIQ2eiuJ2ASGag==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rspack/binding-linux-x64-gnu": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@rspack/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.1.6.tgz", + "integrity": "sha512-MTjDEfPn4TwHoqs5d5Fck06kmXiTHZctGIcRVfrpg0RK0r1NLEHN+oosavRZ9c9H70f34+NmcHk+/qvV4c8lWg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rspack/binding-linux-x64-musl": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@rspack/binding-linux-x64-musl/-/binding-linux-x64-musl-1.1.6.tgz", + "integrity": "sha512-LqDw7PTVr/4ZuGA0izgDQfamfr72USFHltR1Qhy2YVC3JmDmhG/pQi13LHcOLVaGH1xoeyCmEPNJpVizzDxSjg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rspack/binding-win32-arm64-msvc": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@rspack/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.1.6.tgz", + "integrity": "sha512-RHApLM93YN0WdHpS35u2cm7VCqZ8Yg3CrNRL16VJtyT9e6MBqeScoe4XIgIWKPm7edFyedYAjLX0wQOApwfjkg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rspack/binding-win32-ia32-msvc": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@rspack/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-1.1.6.tgz", + "integrity": "sha512-Y6lx4q0eJawRfMPBo/AclTJAPTZ325DSPFBQJB3TnWh9Z2X7P7pQcYc8PHDmfDuYRIdg5WRsQRvVxihSvF7v8w==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rspack/binding-win32-x64-msvc": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@rspack/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.1.6.tgz", + "integrity": "sha512-UuCsfhC/yNuU7xLASOxNXcmsXi2ZvBX14GkxvcdChw6q7IIGNYUKXo1zgR8C1PE/6qDSxmLxbRMS+71d0H3HQg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rspack/cli": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@rspack/cli/-/cli-1.1.6.tgz", + "integrity": "sha512-404JTAadncCp81sDa7nGZdsT7r1Ry8fALR8Wkp9VMTUhWEFlbDGQvOTyali24pfyJxJTdsarSabmNhbDO5okJw==", + "dev": true, + "dependencies": { + "@discoveryjs/json-ext": "^0.5.7", + "@rspack/dev-server": "1.0.9", + "colorette": "2.0.19", + "exit-hook": "^4.0.0", + "interpret": "^3.1.1", + "rechoir": "^0.8.0", + "semver": "^7.6.2", + "webpack-bundle-analyzer": "4.6.1", + "yargs": "17.6.2" + }, + "bin": { + "rspack": "bin/rspack.js" + }, + "peerDependencies": { + "@rspack/core": "^1.0.0-alpha || ^1.x" + } + }, + "node_modules/@rspack/cli/node_modules/colorette": { + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz", + "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==", + "dev": true + }, + "node_modules/@rspack/core": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@rspack/core/-/core-1.1.6.tgz", + "integrity": "sha512-q0VLphOF5VW2FEG7Vbdq3Ke4I74FbELE/8xmKghSalFtULLZ44SoSz8lyotfMim9GXIRFhDokAaH8WICmPxG+g==", + "dev": true, + "dependencies": { + "@module-federation/runtime-tools": "0.5.1", + "@rspack/binding": "1.1.6", + "@rspack/lite-tapable": "1.0.1", + "caniuse-lite": "^1.0.30001616" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@swc/helpers": ">=0.5.1" + }, + "peerDependenciesMeta": { + "@swc/helpers": { + "optional": true + } + } + }, + "node_modules/@rspack/dev-server": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@rspack/dev-server/-/dev-server-1.0.9.tgz", + "integrity": "sha512-VF+apLFfl5LWIhVbfkJ5ccU0Atl5mi+sGTkx+XtE1tbUmMJkde0nm/4+eaQCud7oGl+ZCzt4kW14uuzLSiEGDw==", + "dev": true, + "dependencies": { + "chokidar": "^3.6.0", + "connect-history-api-fallback": "^2.0.0", + "express": "^4.19.2", + "http-proxy-middleware": "^2.0.6", + "mime-types": "^2.1.35", + "p-retry": "4.6.2", + "webpack-dev-middleware": "^7.4.2", + "webpack-dev-server": "5.0.4", + "ws": "^8.16.0" + }, + "peerDependencies": { + "@rspack/core": "*" + } + }, + "node_modules/@rspack/dev-server/node_modules/@types/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==", + "dev": true + }, + "node_modules/@rspack/dev-server/node_modules/p-retry": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", + "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", + "dev": true, + "dependencies": { + "@types/retry": "0.12.0", + "retry": "^0.13.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@rspack/lite-tapable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@rspack/lite-tapable/-/lite-tapable-1.0.1.tgz", + "integrity": "sha512-VynGOEsVw2s8TAlLf/uESfrgfrq2+rcXB1muPJYBWbsm1Oa6r5qVQhjA5ggM6z/coYPrsVMgovl3Ff7Q7OCp1w==", + "dev": true, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/bonjour": { + "version": "3.5.13", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect-history-api-fallback": { + "version": "1.5.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/express-serve-static-core": "*", + "@types/node": "*" + } + }, + "node_modules/@types/eslint": { + "version": "8.56.2", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.7", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.5", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/@types/express": { + "version": "4.17.21", + "dev": true, + "license": "MIT", + "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.17.42", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/http-errors": { + "version": "2.0.4", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/http-proxy": { + "version": "1.17.14", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/mime": { + "version": "1.3.5", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "20.11.10", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/node-forge": { + "version": "1.3.11", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/qs": { + "version": "6.9.11", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/retry": { + "version": "0.12.2", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/send": { + "version": "0.17.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-index": { + "version": "1.9.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/express": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/http-errors": "*", + "@types/mime": "*", + "@types/node": "*" + } + }, + "node_modules/@types/sockjs": { + "version": "0.3.36", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/ws": { + "version": "8.5.10", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", + "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", + "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", + "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", + "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.12.1" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", + "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", + "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", + "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-opt": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1", + "@webassemblyjs/wast-printer": "1.12.1" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", + "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", + "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", + "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", + "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@xtuc/long": "4.2.2" + } + }, + "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, + "optional": true, + "peer": 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, + "optional": true, + "peer": true + }, + "node_modules/accepts": { + "version": "1.3.8", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.11.3", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-import-attributes": { + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", + "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", + "dev": true, + "optional": true, + "peer": true, + "peerDependencies": { + "acorn": "^8" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", + "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", + "dev": true, + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-formats/node_modules/ajv": { + "version": "8.12.0", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats/node_modules/json-schema-traverse": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ajv-keywords": { + "version": "3.5.2", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/ansi-html-community": { + "version": "0.0.8", + "dev": true, + "engines": [ + "node >= 0.8.0" + ], + "license": "Apache-2.0", + "bin": { + "ansi-html": "bin/ansi-html" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "6.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "dev": true, + "license": "MIT" + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/batch": { + "version": "0.6.1", + "dev": true, + "license": "MIT" + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "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==", + "dev": true, + "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/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/bonjour-service": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "multicast-dns": "^7.2.5" + } + }, + "node_modules/brace-expansion": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.22.3", + "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", + "optional": true, + "peer": true, + "dependencies": { + "caniuse-lite": "^1.0.30001580", + "electron-to-chromium": "^1.4.648", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.13" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/bundle-name": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "run-applescript": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bytes": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "dev": true, + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.1.tgz", + "integrity": "sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001687", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001687.tgz", + "integrity": "sha512-0S/FDhf4ZiqrTUiQ39dKeUjYRjkv7lOZU1Dgif2rIqrTzX/1wV2hfKu9TOm1IHkdSijfLswxTFzl/cvir+SLSQ==", + "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==", + "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" + } + }, + "node_modules/chalk/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/chalk/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "dev": true, + "license": "MIT", + "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" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chrome-trace-event": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=6.0" + } + }, + "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/cliui/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/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==", + "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==", + "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/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==", + "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/color-convert": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/colorette": { + "version": "2.0.20", + "dev": true, + "license": "MIT" + }, + "node_modules/commander": { + "version": "2.20.3", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/compressible": { + "version": "2.0.18", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": ">= 1.43.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/compression": { + "version": "1.7.4", + "dev": true, + "license": "MIT", + "dependencies": { + "accepts": "~1.3.5", + "bytes": "3.0.0", + "compressible": "~2.0.16", + "debug": "2.6.9", + "on-headers": "~1.0.2", + "safe-buffer": "5.1.2", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/compression/node_modules/safe-buffer": { + "version": "5.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/connect-history-api-fallback": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "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, + "engines": { + "node": ">= 0.6" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "dev": true, + "license": "MIT" + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "dev": true, + "license": "MIT" + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "2.6.9", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/default-browser": { + "version": "5.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "bundle-name": "^4.1.0", + "default-browser-id": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser-id": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-gateway": { + "version": "6.0.3", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "execa": "^5.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-lazy-prop": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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": ">= 0.8" + } + }, + "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.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/detect-node": { + "version": "2.1.0", + "dev": true, + "license": "MIT" + }, + "node_modules/dns-packet": { + "version": "5.6.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@leichtgewicht/ip-codec": "^2.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.0.tgz", + "integrity": "sha512-9+Sj30DIu+4KvHqMfLUGLFYL2PkURSYMVXJyXe92nFRvlYq5hBjLEhblKB+vkd/WVlUYMWigiY07T91Fkk0+4A==", + "dev": true, + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/duplexer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", + "dev": true + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ee-first": { + "version": "1.1.1", + "dev": true, + "license": "MIT" + }, + "node_modules/electron-to-chromium": { + "version": "1.4.649", + "dev": true, + "license": "ISC", + "optional": true, + "peer": true + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "dev": true, + "license": "MIT" + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/enhanced-resolve": { + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", + "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "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": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "1.4.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/escalade": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "dev": true, + "license": "MIT" + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "dev": true, + "license": "BSD-2-Clause", + "optional": true, + "peer": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "dev": true, + "license": "BSD-2-Clause", + "optional": true, + "peer": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "dev": true, + "license": "BSD-2-Clause", + "optional": true, + "peer": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "dev": true, + "license": "BSD-2-Clause", + "optional": true, + "peer": true, + "engines": { + "node": ">=4.0" + } + }, + "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, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "dev": true, + "license": "MIT" + }, + "node_modules/events": { + "version": "3.3.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/exit-hook": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-4.0.0.tgz", + "integrity": "sha512-Fqs7ChZm72y40wKjOFXBKg7nJZvQJmewP5/7LtePDdnah/+FH9Hp5sgMujSCMPXlxOAW2//1jrW9pnsY7o20vQ==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/express": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", + "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", + "dev": true, + "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", + "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", + "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" + }, + "engines": { + "node": ">= 0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/fast-uri": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.1.tgz", + "integrity": "sha512-MWipKbbYiYI0UC7cl8m/i/IWTqfC8YXsqjzybjddLsFjStroQzsHXkc73JutMvBiXmOvapk+axIl79ig5t55Bw==", + "dev": true + }, + "node_modules/faye-websocket": { + "version": "0.11.4", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "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==", + "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" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.5", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/foreground-child": { + "version": "3.1.1", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/foreground-child/node_modules/signal-exit": { + "version": "4.1.0", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.5.tgz", + "integrity": "sha512-Y4+pKa7XeRUPWFNvOOYHkRYrfzW07oraURSvjDmRVOJ748OrVmeXtpE4+GCEHncjCjkTxPNRt8kEbxDhsn6VTg==", + "dev": true, + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "dunder-proto": "^1.0.0", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/glob": { + "version": "10.3.10", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.5", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "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, + "optional": true, + "peer": true + }, + "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, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "dev": true, + "license": "ISC" + }, + "node_modules/gzip-size": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", + "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==", + "dev": true, + "dependencies": { + "duplexer": "^0.1.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/handle-thing": { + "version": "2.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hpack.js": { + "version": "2.1.6", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" + } + }, + "node_modules/hpack.js/node_modules/readable-stream": { + "version": "2.3.8", + "dev": true, + "license": "MIT", + "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" + } + }, + "node_modules/hpack.js/node_modules/safe-buffer": { + "version": "5.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/hpack.js/node_modules/string_decoder": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/html-entities": { + "version": "2.4.0", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/mdevils" + }, + { + "type": "patreon", + "url": "https://patreon.com/mdevils" + } + ], + "license": "MIT" + }, + "node_modules/http-deceiver": { + "version": "1.2.7", + "dev": true, + "license": "MIT" + }, + "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==", + "dev": true, + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-parser-js": { + "version": "0.5.8", + "dev": true, + "license": "MIT" + }, + "node_modules/http-proxy": { + "version": "1.18.1", + "dev": true, + "license": "MIT", + "dependencies": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/http-proxy-middleware": { + "version": "2.0.6", + "dev": true, + "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" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "@types/express": "^4.17.13" + }, + "peerDependenciesMeta": { + "@types/express": { + "optional": true + } + } + }, + "node_modules/human-signals": { + "version": "2.1.0", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/hyperdyperid": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/hyperdyperid/-/hyperdyperid-1.2.0.tgz", + "integrity": "sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A==", + "dev": true, + "engines": { + "node": ">=10.18" + } + }, + "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": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "dev": true, + "license": "ISC" + }, + "node_modules/interpret": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/ipaddr.js": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-core-module": { + "version": "2.13.1", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-docker": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-inside-container": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-network-error": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-plain-obj": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-wsl": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "is-inside-container": "^1.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/jackspeak": { + "version": "2.3.6", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jest-worker": { + "version": "27.5.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/launch-editor": { + "version": "2.6.1", + "dev": true, + "license": "MIT", + "dependencies": { + "picocolors": "^1.0.0", + "shell-quote": "^1.8.1" + } + }, + "node_modules/loader-runner": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=6.11.5" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "dev": true, + "license": "MIT" + }, + "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": ">= 0.6" + } + }, + "node_modules/memfs": { + "version": "4.9.3", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.9.3.tgz", + "integrity": "sha512-bsYSSnirtYTWi1+OPMFb0M048evMKyUYe0EbtuGQgq6BVQM1g1W8/KIUJCCvjgI/El0j6Q4WsmMiBwLUBSw8LA==", + "dev": true, + "dependencies": { + "@jsonjoy.com/json-pack": "^1.0.3", + "@jsonjoy.com/util": "^1.1.2", + "tree-dump": "^1.0.1", + "tslib": "^2.0.0" + }, + "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==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/methods": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "dev": true, + "license": "ISC" + }, + "node_modules/minimatch": { + "version": "9.0.3", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minipass": { + "version": "7.0.4", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/mrmime": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-1.0.1.tgz", + "integrity": "sha512-hzzEagAgDyoU1Q6yg5uI+AorQgdvMCur3FcKf7NhMKWsaYg+RnbTyHRa/9IlLF9rf455MOCtcqqrQQ83pPP7Uw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/multicast-dns": { + "version": "7.2.5", + "dev": true, + "license": "MIT", + "dependencies": { + "dns-packet": "^5.2.2", + "thunky": "^1.0.2" + }, + "bin": { + "multicast-dns": "cli.js" + } + }, + "node_modules/negotiator": { + "version": "0.6.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/neuroglancer": { + "resolved": "../../../dist/package", + "link": true + }, + "node_modules/node-forge": { + "version": "1.3.1", + "dev": true, + "license": "(BSD-3-Clause OR GPL-2.0)", + "engines": { + "node": ">= 6.13.0" + } + }, + "node_modules/node-releases": { + "version": "2.0.14", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/object-inspect": { + "version": "1.13.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz", + "integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/obuf": { + "version": "1.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/on-finished": { + "version": "2.4.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/on-headers": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/open": { + "version": "10.0.3", + "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" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/opener": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", + "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", + "dev": true, + "bin": { + "opener": "bin/opener-bin.js" + } + }, + "node_modules/p-retry": { + "version": "6.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/retry": "0.12.2", + "is-network-error": "^1.0.0", + "retry": "^0.13.1" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "dev": true, + "license": "MIT" + }, + "node_modules/path-scurry": { + "version": "1.10.1", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^9.1.1 || ^10.0.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.2.0", + "dev": true, + "license": "ISC", + "engines": { + "node": "14 || >=16.14" + } + }, + "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==", + "dev": true + }, + "node_modules/picocolors": { + "version": "1.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "dev": true, + "license": "MIT", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/proxy-addr/node_modules/ipaddr.js": { + "version": "1.9.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/qs": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "dev": true, + "dependencies": { + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "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==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/raw-body/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": ">= 0.8" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/rechoir": { + "version": "0.8.0", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve": "^1.20.0" + }, + "engines": { + "node": ">= 10.13.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==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/resolve": { + "version": "1.22.8", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/retry": { + "version": "0.13.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/rimraf": { + "version": "5.0.5", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^10.3.7" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/run-applescript": { + "version": "7.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "node_modules/schema-utils": { + "version": "3.3.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/select-hose": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/selfsigned": { + "version": "2.4.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node-forge": "^1.3.0", + "node-forge": "^1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/send": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", + "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" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/send/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/serialize-javascript": { + "version": "6.0.2", + "dev": true, + "license": "BSD-3-Clause", + "optional": true, + "peer": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/serve-index": { + "version": "1.9.1", + "dev": true, + "license": "MIT", + "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" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/serve-index/node_modules/depd": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/http-errors": { + "version": "1.6.3", + "dev": true, + "license": "MIT", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/inherits": { + "version": "2.0.3", + "dev": true, + "license": "ISC" + }, + "node_modules/serve-index/node_modules/setprototypeof": { + "version": "1.1.0", + "dev": true, + "license": "ISC" + }, + "node_modules/serve-index/node_modules/statuses": { + "version": "1.5.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "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==", + "dev": true, + "dependencies": { + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.19.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/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", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/shell-quote": { + "version": "1.8.1", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "dev": true, + "license": "ISC" + }, + "node_modules/sirv": { + "version": "1.0.19", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-1.0.19.tgz", + "integrity": "sha512-JuLThK3TnZG1TAKDwNIqNq6QA2afLOCcm+iE8D1Kj3GA40pSPsxQjjJl0J8X3tsR7T+CP1GavpzLwYkgVLWrZQ==", + "dev": true, + "dependencies": { + "@polka/url": "^1.0.0-next.20", + "mrmime": "^1.0.0", + "totalist": "^1.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/sockjs": { + "version": "0.3.24", + "dev": true, + "license": "MIT", + "dependencies": { + "faye-websocket": "^0.11.3", + "uuid": "^8.3.2", + "websocket-driver": "^0.7.4" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "dev": true, + "license": "BSD-3-Clause", + "optional": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/spdy": { + "version": "4.0.2", + "dev": true, + "license": "MIT", + "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" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/spdy-transport": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "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_modules/spdy-transport/node_modules/debug": { + "version": "4.3.4", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/spdy-transport/node_modules/ms": { + "version": "2.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/spdy/node_modules/debug": { + "version": "4.3.4", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/spdy/node_modules/ms": { + "version": "2.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "5.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/string-width/node_modules/ansi-regex": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/string-width/node_modules/strip-ansi": { + "version": "7.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/supports-color": { + "version": "8.1.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tapable": { + "version": "2.2.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/terser": { + "version": "5.27.0", + "dev": true, + "license": "BSD-2-Clause", + "optional": true, + "peer": true, + "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" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.3.10", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.20", + "jest-worker": "^27.4.5", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.1", + "terser": "^5.26.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/thingies": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/thingies/-/thingies-1.21.0.tgz", + "integrity": "sha512-hsqsJsFMsV+aD4s3CWKk85ep/3I9XzYV/IXaSouJMYIoDlgyi11cBhsqYe9/geRfB0YIikBQg6raRaM+nIMP9g==", + "dev": true, + "engines": { + "node": ">=10.18" + }, + "peerDependencies": { + "tslib": "^2" + } + }, + "node_modules/thunky": { + "version": "1.1.0", + "dev": true, + "license": "MIT" + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.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==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/totalist": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-1.1.0.tgz", + "integrity": "sha512-gduQwd1rOdDMGxFG1gEvhV88Oirdo2p+KjoYFU7k2g+i7n6AFFbDQ5kMPUsW0pNbfQsB/cwXvT1i4Bue0s9g5g==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/tree-dump": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/tree-dump/-/tree-dump-1.0.2.tgz", + "integrity": "sha512-dpev9ABuLWdEubk+cIaI9cHwRNNDjkBBLXTwI4UCUFdQ5xXKqNXoK4FEciw/vxf+NQ7Cb7sGUyeUtORvHIdRXQ==", + "dev": true, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/tslib": { + "version": "2.6.2", + "dev": true, + "license": "0BSD" + }, + "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": ">= 0.6" + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "dev": true, + "license": "MIT" + }, + "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, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.0.13", + "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", + "optional": true, + "peer": true, + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "8.3.2", + "dev": true, + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/watchpack": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.1.tgz", + "integrity": "sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/wbuf": { + "version": "1.7.3", + "dev": true, + "license": "MIT", + "dependencies": { + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/webpack": { + "version": "5.93.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.93.0.tgz", + "integrity": "sha512-Y0m5oEY1LRuwly578VqluorkXbvXKh7U3rLoQCEO04M97ScRr44afGVkI0FQFsXzysk5OgFAxjZAb9rsGQVihA==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@types/eslint-scope": "^3.7.3", + "@types/estree": "^1.0.5", + "@webassemblyjs/ast": "^1.12.1", + "@webassemblyjs/wasm-edit": "^1.12.1", + "@webassemblyjs/wasm-parser": "^1.12.1", + "acorn": "^8.7.1", + "acorn-import-attributes": "^1.9.5", + "browserslist": "^4.21.10", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.17.0", + "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": "^3.2.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.10", + "watchpack": "^2.4.1", + "webpack-sources": "^3.2.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-bundle-analyzer": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.6.1.tgz", + "integrity": "sha512-oKz9Oz9j3rUciLNfpGFjOb49/jEpXNmWdVH8Ls//zNcnLlQdTGXQQMsBbb/gR7Zl8WNLxVCq+0Hqbx3zv6twBw==", + "dev": true, + "dependencies": { + "acorn": "^8.0.4", + "acorn-walk": "^8.0.0", + "chalk": "^4.1.0", + "commander": "^7.2.0", + "gzip-size": "^6.0.0", + "lodash": "^4.17.20", + "opener": "^1.5.2", + "sirv": "^1.0.7", + "ws": "^7.3.1" + }, + "bin": { + "webpack-bundle-analyzer": "lib/bin/analyzer.js" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/webpack-bundle-analyzer/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/webpack-bundle-analyzer/node_modules/ws": { + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", + "dev": true, + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/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==", + "dev": true, + "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" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + } + } + }, + "node_modules/webpack-dev-middleware/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/webpack-dev-middleware/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/webpack-dev-middleware/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/webpack-dev-middleware/node_modules/schema-utils": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/webpack-dev-server": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-5.0.4.tgz", + "integrity": "sha512-dljXhUgx3HqKP2d8J/fUMvhxGhzjeNVarDLcbO/EWMSgRizDkxHQDZQaLFL5VJY9tRBj2Gz+rvCEYYvhbqPHNA==", + "dev": true, + "dependencies": { + "@types/bonjour": "^3.5.13", + "@types/connect-history-api-fallback": "^1.5.4", + "@types/express": "^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", + "default-gateway": "^6.0.3", + "express": "^4.17.3", + "graceful-fs": "^4.2.6", + "html-entities": "^2.4.0", + "http-proxy-middleware": "^2.0.3", + "ipaddr.js": "^2.1.0", + "launch-editor": "^2.6.1", + "open": "^10.0.3", + "p-retry": "^6.2.0", + "rimraf": "^5.0.5", + "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.1.0", + "ws": "^8.16.0" + }, + "bin": { + "webpack-dev-server": "bin/webpack-dev-server.js" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + }, + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-dev-server/node_modules/ajv": { + "version": "8.12.0", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/webpack-dev-server/node_modules/ajv-keywords": { + "version": "5.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/webpack-dev-server/node_modules/json-schema-traverse": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/webpack-dev-server/node_modules/schema-utils": { + "version": "4.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/webpack-sources": { + "version": "3.2.3", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/websocket-driver": { + "version": "0.7.4", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "7.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/ws": { + "version": "8.16.0", + "dev": true, + "license": "MIT", + "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_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs": { + "version": "17.6.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz", + "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==", + "dev": true, + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "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/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" + } + } + } +} diff --git a/examples/rspack/rspack-project-built/package.json b/examples/rspack/rspack-project-built/package.json new file mode 100644 index 0000000000..37c4e18ffb --- /dev/null +++ b/examples/rspack/rspack-project-built/package.json @@ -0,0 +1,24 @@ +{ + "name": "neuroglancer-rspack-project-built", + "version": "0.0.0", + "private": true, + "description": "Test of an rspack-bundled project that depends on Neuroglancer.", + "scripts": { + "build": "rspack build", + "dev-server": "rspack serve" + }, + "dependencies": { + "neuroglancer": "file:../../../dist/package" + }, + "browserslist": [ + "last 2 Chrome versions", + "last 2 Firefox versions", + "last 2 Safari versions" + ], + "license": "Apache-2.0", + "devDependencies": { + "@rspack/cli": "^1.1.5", + "@rspack/core": "^1.1.5" + }, + "type": "module" +} diff --git a/examples/rspack/rspack-project-built/rspack.config.js b/examples/rspack/rspack-project-built/rspack.config.js new file mode 100644 index 0000000000..2dac5e39cf --- /dev/null +++ b/examples/rspack/rspack-project-built/rspack.config.js @@ -0,0 +1,46 @@ +import rspack from "@rspack/core"; + +export default { + mode: "development", + performance: { + // Avoid unhelpful warnings due to large bundles. + maxAssetSize: 3 * 1024 * 1024, + maxEntrypointSize: 3 * 1024 * 1024, + }, + module: { + rules: [ + // Needed for .svg?raw imports used for embedding icons. + { + resourceQuery: /raw/, + type: "asset/source", + }, + // Needed for .html assets used for auth redirect pages for the brainmaps + // and bossDB data sources. Can be skipped if those data sources are + // excluded. + { + test: /\.html$/, + type: "asset/resource", + generator: { + // Filename must be preserved since exact redirect URLs must be allowlisted. + filename: "[name][ext]", + }, + }, + ], + }, + devServer: { + client: { + overlay: { + // Prevent intrusive notification spam. + runtimeErrors: false, + }, + }, + }, + plugins: [ + new rspack.HtmlRspackPlugin({ + title: "Neuroglancer webpack test", + }), + ], + experiments: { + css: true, + }, +}; diff --git a/examples/rspack/rspack-project-built/src/index.js b/examples/rspack/rspack-project-built/src/index.js new file mode 100644 index 0000000000..805818b627 --- /dev/null +++ b/examples/rspack/rspack-project-built/src/index.js @@ -0,0 +1,3 @@ +import "neuroglancer"; +import { setupDefaultViewer } from "neuroglancer/unstable/ui/default_viewer_setup.js"; +setupDefaultViewer(); diff --git a/examples/rspack/rspack-project-source/.gitignore b/examples/rspack/rspack-project-source/.gitignore new file mode 100644 index 0000000000..b0a5c349ca --- /dev/null +++ b/examples/rspack/rspack-project-source/.gitignore @@ -0,0 +1,2 @@ +/node_modules/ +/dist/ diff --git a/examples/rspack/rspack-project-source/package-lock.json b/examples/rspack/rspack-project-source/package-lock.json new file mode 100644 index 0000000000..e801f0dde5 --- /dev/null +++ b/examples/rspack/rspack-project-source/package-lock.json @@ -0,0 +1,14170 @@ +{ + "name": "neuroglancer-rspack-project-source", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "neuroglancer-rspack-project-source", + "version": "0.0.0", + "license": "Apache-2.0", + "dependencies": { + "neuroglancer": "file:../../.." + }, + "devDependencies": { + "@rspack/cli": "^1.1.5", + "@rspack/core": "^1.1.5" + } + }, + "../../..": { + "version": "2.40.1", + "license": "Apache-2.0", + "dependencies": { + "codemirror": "^5.61.1", + "core-js": "^3.40.0", + "crc-32": "^1.2.2", + "gl-matrix": "3.1.0", + "ikonate": "github:mikolajdobrucki/ikonate#a86b4107c6ec717e7877f880a930d1ccf0b59d89", + "lodash-es": "^4.17.21", + "nifti-reader-js": "^0.6.8", + "numcodecs": "^0.3.2" + }, + "devDependencies": { + "@eslint/js": "^9.18.0", + "@iodigital/vite-plugin-msw": "^2.0.0", + "@playwright/browser-chromium": "^1.49.1", + "@rspack/cli": "^1.1.8", + "@rspack/core": "^1.1.8", + "@types/codemirror": "5.60.15", + "@types/gl-matrix": "^2.4.5", + "@types/http-server": "^0.12.4", + "@types/jsdom": "^21.1.7", + "@types/lodash-es": "^4.17.12", + "@types/node": "^22.10.7", + "@types/nunjucks": "^3.2.6", + "@types/s3rver": "^3.7.4", + "@types/yargs": "^17.0.33", + "@vitest/browser": "^3.0.2", + "@vitest/ui": "^3.0.2", + "@vitest/web-worker": "^3.0.2", + "cookie": "^1.0.2", + "css-loader": "^7.1.2", + "esbuild": "^0.24.2", + "eslint": "^9.18.0", + "eslint-formatter-codeframe": "^7.32.1", + "eslint-import-resolver-typescript": "^3.7.0", + "eslint-plugin-import": "^2.31.0", + "eslint-plugin-oxlint": "^0.15.7", + "eslint-rspack-plugin": "^4.2.1", + "express": "^4.21.2", + "glob": "^11.0.1", + "http-server": "^14.1.1", + "jsdom": "^26.0.0", + "msw": "^2.7.0", + "nunjucks": "^3.2.4", + "oxlint": "^0.15.7", + "playwright": "^1.49.1", + "prettier": "3.4.2", + "s3rver": "^3.7.1", + "ts-checker-rspack-plugin": "^1.1.1", + "tsx": "^4.19.2", + "typescript": "^5.7.3", + "typescript-eslint": "^8.20.0", + "vitest": "^3.0.2", + "webpack-bundle-analyzer": "^4.10.2", + "webpack-merge": "^6.0.1", + "yargs": "^17.7.2", + "yauzl": "^3.2.0" + }, + "engines": { + "node": ">=22" + } + }, + "../../../node_modules/@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "../../../node_modules/@discoveryjs/json-ext": { + "version": "0.5.7", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, + "../../../node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/@esbuild/linux-x64": { + "version": "0.20.1", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "../../../node_modules/@eslint-community/regexpp": { + "version": "4.10.0", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "../../../node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "../../../node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.11", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "../../../node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "../../../node_modules/@eslint/js": { + "version": "8.56.0", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "../../../node_modules/@humanwhocodes/config-array": { + "version": "0.11.14", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "../../../node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { + "version": "1.1.11", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "../../../node_modules/@humanwhocodes/config-array/node_modules/minimatch": { + "version": "3.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "../../../node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "../../../node_modules/@humanwhocodes/object-schema": { + "version": "2.0.2", + "dev": true, + "license": "BSD-3-Clause" + }, + "../../../node_modules/@isaacs/cliui": { + "version": "8.0.2", + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "../../../node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "../../../node_modules/@jest/schemas": { + "version": "29.6.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "../../../node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "../../../node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=6.0.0" + } + }, + "../../../node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=6.0.0" + } + }, + "../../../node_modules/@jridgewell/source-map": { + "version": "0.3.5", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "../../../node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "../../../node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "../../../node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "../../../node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "../../../node_modules/@one-ini/wasm": { + "version": "0.1.1", + "license": "MIT" + }, + "../../../node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "../../../node_modules/@polka/url": { + "version": "1.0.0-next.24", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/@puppeteer/browsers": { + "version": "2.0.1", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "peer": true, + "dependencies": { + "debug": "4.3.4", + "extract-zip": "2.0.1", + "progress": "2.0.3", + "proxy-agent": "6.4.0", + "tar-fs": "3.0.5", + "unbzip2-stream": "1.4.3", + "yargs": "17.7.2" + }, + "bin": { + "browsers": "lib/cjs/main-cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "../../../node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.19.0.tgz", + "integrity": "sha512-JlPfZ/C7yn5S5p0yKk7uhHTTnFlvTgLetl2VxqE518QgyM7C9bSfFTYvB/Q/ftkq0RIPY4ySxTz+/wKJ/dXC0w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "../../../node_modules/@rollup/rollup-android-arm64": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.19.0.tgz", + "integrity": "sha512-RDxUSY8D1tWYfn00DDi5myxKgOk6RvWPxhmWexcICt/MEC6yEMr4HNCu1sXXYLw8iAsg0D44NuU+qNq7zVWCrw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "../../../node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.19.0.tgz", + "integrity": "sha512-emvKHL4B15x6nlNTBMtIaC9tLPRpeA5jMvRLXVbl/W9Ie7HhkrE7KQjvgS9uxgatL1HmHWDXk5TTS4IaNJxbAA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "../../../node_modules/@rollup/rollup-darwin-x64": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.19.0.tgz", + "integrity": "sha512-fO28cWA1dC57qCd+D0rfLC4VPbh6EOJXrreBmFLWPGI9dpMlER2YwSPZzSGfq11XgcEpPukPTfEVFtw2q2nYJg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "../../../node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.19.0.tgz", + "integrity": "sha512-2Rn36Ubxdv32NUcfm0wB1tgKqkQuft00PtM23VqLuCUR4N5jcNWDoV5iBC9jeGdgS38WK66ElncprqgMUOyomw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "../../../node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.19.0.tgz", + "integrity": "sha512-gJuzIVdq/X1ZA2bHeCGCISe0VWqCoNT8BvkQ+BfsixXwTOndhtLUpOg0A1Fcx/+eA6ei6rMBzlOz4JzmiDw7JQ==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "../../../node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.19.0.tgz", + "integrity": "sha512-0EkX2HYPkSADo9cfeGFoQ7R0/wTKb7q6DdwI4Yn/ULFE1wuRRCHybxpl2goQrx4c/yzK3I8OlgtBu4xvted0ug==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "../../../node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.19.0.tgz", + "integrity": "sha512-GlIQRj9px52ISomIOEUq/IojLZqzkvRpdP3cLgIE1wUWaiU5Takwlzpz002q0Nxxr1y2ZgxC2obWxjr13lvxNQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "../../../node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.19.0.tgz", + "integrity": "sha512-N6cFJzssruDLUOKfEKeovCKiHcdwVYOT1Hs6dovDQ61+Y9n3Ek4zXvtghPPelt6U0AH4aDGnDLb83uiJMkWYzQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "../../../node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.19.0.tgz", + "integrity": "sha512-2DnD3mkS2uuam/alF+I7M84koGwvn3ZVD7uG+LEWpyzo/bq8+kKnus2EVCkcvh6PlNB8QPNFOz6fWd5N8o1CYg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "../../../node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.19.0.tgz", + "integrity": "sha512-D6pkaF7OpE7lzlTOFCB2m3Ngzu2ykw40Nka9WmKGUOTS3xcIieHe82slQlNq69sVB04ch73thKYIWz/Ian8DUA==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "../../../node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.19.0.tgz", + "integrity": "sha512-HBndjQLP8OsdJNSxpNIN0einbDmRFg9+UQeZV1eiYupIRuZsDEoeGU43NQsS34Pp166DtwQOnpcbV/zQxM+rWA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "../../../node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.19.0.tgz", + "integrity": "sha512-HxfbvfCKJe/RMYJJn0a12eiOI9OOtAUF4G6ozrFUK95BNyoJaSiBjIOHjZskTUffUrB84IPKkFG9H9nEvJGW6A==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "../../../node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.19.0.tgz", + "integrity": "sha512-HxDMKIhmcguGTiP5TsLNolwBUK3nGGUEoV/BO9ldUBoMLBssvh4J0X8pf11i1fTV7WShWItB1bKAKjX4RQeYmg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "../../../node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.19.0.tgz", + "integrity": "sha512-xItlIAZZaiG/u0wooGzRsx11rokP4qyc/79LkAOdznGRAbOFc+SfEdfUOszG1odsHNgwippUJavag/+W/Etc6Q==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "../../../node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.19.0.tgz", + "integrity": "sha512-xNo5fV5ycvCCKqiZcpB65VMR11NJB+StnxHz20jdqRAktfdfzhgjTiJ2doTDQE/7dqGaV5I7ZGqKpgph6lCIag==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "../../../node_modules/@sinclair/typebox": { + "version": "0.27.8", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/@sindresorhus/is": { + "version": "5.6.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "../../../node_modules/@szmarczak/http-timer": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "defer-to-connect": "^2.0.1" + }, + "engines": { + "node": ">=14.16" + } + }, + "../../../node_modules/@tootallnate/once": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "../../../node_modules/@tootallnate/quickjs-emscripten": { + "version": "0.23.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/@types/codemirror": { + "version": "5.60.15", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/tern": "*" + } + }, + "../../../node_modules/@types/eslint": { + "version": "8.56.5", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "../../../node_modules/@types/eslint-scope": { + "version": "3.7.7", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "../../../node_modules/@types/estree": { + "version": "1.0.5", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/@types/gl-matrix": { + "version": "2.4.5", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/@types/http-cache-semantics": { + "version": "4.0.4", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/@types/json-schema": { + "version": "7.0.15", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/@types/json5": { + "version": "0.0.29", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/@types/lodash": { + "version": "4.14.202", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/@types/lodash-es": { + "version": "4.17.12", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/lodash": "*" + } + }, + "../../../node_modules/@types/node": { + "version": "20.11.20", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "../../../node_modules/@types/tern": { + "version": "0.23.9", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "*" + } + }, + "../../../node_modules/@types/which": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/@types/ws": { + "version": "8.5.10", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@types/node": "*" + } + }, + "../../../node_modules/@types/yargs": { + "version": "17.0.32", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "../../../node_modules/@types/yargs-parser": { + "version": "21.0.3", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/@types/yauzl": { + "version": "2.10.3", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@types/node": "*" + } + }, + "../../../node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "dev": true, + "license": "ISC" + }, + "../../../node_modules/@vitest/browser": { + "version": "1.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "1.3.1", + "magic-string": "^0.30.5", + "sirv": "^2.0.4" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "playwright": "*", + "vitest": "1.3.1", + "webdriverio": "*" + }, + "peerDependenciesMeta": { + "playwright": { + "optional": true + }, + "safaridriver": { + "optional": true + }, + "webdriverio": { + "optional": true + } + } + }, + "../../../node_modules/@vitest/expect": { + "version": "1.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "1.3.1", + "@vitest/utils": "1.3.1", + "chai": "^4.3.10" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "../../../node_modules/@vitest/runner": { + "version": "1.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "1.3.1", + "p-limit": "^5.0.0", + "pathe": "^1.1.1" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "../../../node_modules/@vitest/runner/node_modules/p-limit": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/@vitest/runner/node_modules/yocto-queue": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/@vitest/snapshot": { + "version": "1.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "magic-string": "^0.30.5", + "pathe": "^1.1.1", + "pretty-format": "^29.7.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "../../../node_modules/@vitest/spy": { + "version": "1.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyspy": "^2.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "../../../node_modules/@vitest/ui": { + "version": "1.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "1.3.1", + "fast-glob": "^3.3.2", + "fflate": "^0.8.1", + "flatted": "^3.2.9", + "pathe": "^1.1.1", + "picocolors": "^1.0.0", + "sirv": "^2.0.4" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "vitest": "1.3.1" + } + }, + "../../../node_modules/@vitest/utils": { + "version": "1.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "diff-sequences": "^29.6.3", + "estree-walker": "^3.0.3", + "loupe": "^2.3.7", + "pretty-format": "^29.7.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "../../../node_modules/@vitest/utils/node_modules/estree-walker": { + "version": "3.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "../../../node_modules/@wdio/config": { + "version": "8.32.3", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@wdio/logger": "8.28.0", + "@wdio/types": "8.32.2", + "@wdio/utils": "8.32.3", + "decamelize": "^6.0.0", + "deepmerge-ts": "^5.0.0", + "glob": "^10.2.2", + "import-meta-resolve": "^4.0.0" + }, + "engines": { + "node": "^16.13 || >=18" + } + }, + "../../../node_modules/@wdio/logger": { + "version": "8.28.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "chalk": "^5.1.2", + "loglevel": "^1.6.0", + "loglevel-plugin-prefix": "^0.8.4", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": "^16.13 || >=18" + } + }, + "../../../node_modules/@wdio/logger/node_modules/ansi-regex": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "../../../node_modules/@wdio/logger/node_modules/chalk": { + "version": "5.3.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "../../../node_modules/@wdio/logger/node_modules/strip-ansi": { + "version": "7.1.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "../../../node_modules/@wdio/protocols": { + "version": "8.32.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/@wdio/repl": { + "version": "8.24.12", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@types/node": "^20.1.0" + }, + "engines": { + "node": "^16.13 || >=18" + } + }, + "../../../node_modules/@wdio/types": { + "version": "8.32.2", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@types/node": "^20.1.0" + }, + "engines": { + "node": "^16.13 || >=18" + } + }, + "../../../node_modules/@wdio/utils": { + "version": "8.32.3", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@puppeteer/browsers": "^1.6.0", + "@wdio/logger": "8.28.0", + "@wdio/types": "8.32.2", + "decamelize": "^6.0.0", + "deepmerge-ts": "^5.1.0", + "edgedriver": "^5.3.5", + "geckodriver": "^4.3.1", + "get-port": "^7.0.0", + "import-meta-resolve": "^4.0.0", + "locate-app": "^2.1.0", + "safaridriver": "^0.1.0", + "split2": "^4.2.0", + "wait-port": "^1.0.4" + }, + "engines": { + "node": "^16.13 || >=18" + } + }, + "../../../node_modules/@webassemblyjs/ast": { + "version": "1.11.6", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" + } + }, + "../../../node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.6", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/@webassemblyjs/helper-api-error": { + "version": "1.11.6", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/@webassemblyjs/helper-buffer": { + "version": "1.11.6", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/@webassemblyjs/helper-numbers": { + "version": "1.11.6", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@xtuc/long": "4.2.2" + } + }, + "../../../node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.6", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.11.6", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6" + } + }, + "../../../node_modules/@webassemblyjs/ieee754": { + "version": "1.11.6", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "../../../node_modules/@webassemblyjs/leb128": { + "version": "1.11.6", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "peer": true, + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "../../../node_modules/@webassemblyjs/utf8": { + "version": "1.11.6", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/@webassemblyjs/wasm-edit": { + "version": "1.11.6", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6", + "@webassemblyjs/wasm-opt": "1.11.6", + "@webassemblyjs/wasm-parser": "1.11.6", + "@webassemblyjs/wast-printer": "1.11.6" + } + }, + "../../../node_modules/@webassemblyjs/wasm-gen": { + "version": "1.11.6", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "../../../node_modules/@webassemblyjs/wasm-opt": { + "version": "1.11.6", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6", + "@webassemblyjs/wasm-parser": "1.11.6" + } + }, + "../../../node_modules/@webassemblyjs/wasm-parser": { + "version": "1.11.6", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "../../../node_modules/@webassemblyjs/wast-printer": { + "version": "1.11.6", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@xtuc/long": "4.2.2" + } + }, + "../../../node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "dev": true, + "license": "BSD-3-Clause", + "optional": true, + "peer": true + }, + "../../../node_modules/@xtuc/long": { + "version": "4.2.2", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "peer": true + }, + "../../../node_modules/abab": { + "version": "2.0.6", + "dev": true, + "license": "BSD-3-Clause" + }, + "../../../node_modules/abbrev": { + "version": "2.0.0", + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "../../../node_modules/acorn": { + "version": "8.11.3", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "../../../node_modules/acorn-globals": { + "version": "6.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^7.1.1", + "acorn-walk": "^7.1.1" + } + }, + "../../../node_modules/acorn-globals/node_modules/acorn": { + "version": "7.4.1", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "../../../node_modules/acorn-import-assertions": { + "version": "1.9.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "peerDependencies": { + "acorn": "^8" + } + }, + "../../../node_modules/acorn-jsx": { + "version": "5.3.2", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "../../../node_modules/acorn-walk": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "../../../node_modules/agent-base": { + "version": "6.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "../../../node_modules/ajv": { + "version": "6.12.6", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "../../../node_modules/ajv-keywords": { + "version": "3.5.2", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "../../../node_modules/ansi-regex": { + "version": "5.0.1", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "../../../node_modules/ansi-styles": { + "version": "4.3.0", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "../../../node_modules/archiver": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "archiver-utils": "^4.0.1", + "async": "^3.2.4", + "buffer-crc32": "^0.2.1", + "readable-stream": "^3.6.0", + "readdir-glob": "^1.1.2", + "tar-stream": "^3.0.0", + "zip-stream": "^5.0.1" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "../../../node_modules/archiver-utils": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "glob": "^8.0.0", + "graceful-fs": "^4.2.0", + "lazystream": "^1.0.0", + "lodash": "^4.17.15", + "normalize-path": "^3.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "../../../node_modules/archiver-utils/node_modules/glob": { + "version": "8.1.0", + "dev": true, + "license": "ISC", + "optional": true, + "peer": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "../../../node_modules/archiver-utils/node_modules/minimatch": { + "version": "5.1.6", + "dev": true, + "license": "ISC", + "optional": true, + "peer": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "../../../node_modules/archiver-utils/node_modules/readable-stream": { + "version": "3.6.2", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "../../../node_modules/archiver/node_modules/readable-stream": { + "version": "3.6.2", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "../../../node_modules/argparse": { + "version": "2.0.1", + "dev": true, + "license": "Python-2.0" + }, + "../../../node_modules/aria-query": { + "version": "5.3.0", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "peer": true, + "dependencies": { + "dequal": "^2.0.3" + } + }, + "../../../node_modules/array-buffer-byte-length": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "is-array-buffer": "^3.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/array-equal": { + "version": "1.0.2", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/array-includes": { + "version": "3.1.7", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/array.prototype.findlastindex": { + "version": "1.2.3", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0", + "get-intrinsic": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/array.prototype.flat": { + "version": "1.3.2", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/array.prototype.flatmap": { + "version": "1.3.2", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/arraybuffer.prototype.slice": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", + "is-array-buffer": "^3.0.2", + "is-shared-array-buffer": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/asn1": { + "version": "0.2.6", + "license": "MIT", + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "../../../node_modules/assert-plus": { + "version": "1.0.0", + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "../../../node_modules/assertion-error": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "../../../node_modules/ast-types": { + "version": "0.13.4", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "../../../node_modules/async": { + "version": "3.2.5", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/async-limiter": { + "version": "1.0.1", + "license": "MIT" + }, + "../../../node_modules/asynckit": { + "version": "0.4.0", + "license": "MIT" + }, + "../../../node_modules/available-typed-arrays": { + "version": "1.0.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/aws-sign2": { + "version": "0.7.0", + "license": "Apache-2.0", + "engines": { + "node": "*" + } + }, + "../../../node_modules/aws4": { + "version": "1.12.0", + "license": "MIT" + }, + "../../../node_modules/b4a": { + "version": "1.6.4", + "dev": true, + "license": "ISC", + "optional": true, + "peer": true + }, + "../../../node_modules/balanced-match": { + "version": "1.0.2", + "license": "MIT" + }, + "../../../node_modules/bare-events": { + "version": "2.2.0", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "peer": true + }, + "../../../node_modules/bare-fs": { + "version": "2.1.5", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "peer": true, + "dependencies": { + "bare-events": "^2.0.0", + "bare-os": "^2.0.0", + "bare-path": "^2.0.0", + "streamx": "^2.13.0" + } + }, + "../../../node_modules/bare-os": { + "version": "2.2.0", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "peer": true + }, + "../../../node_modules/bare-path": { + "version": "2.1.0", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "peer": true, + "dependencies": { + "bare-os": "^2.1.0" + } + }, + "../../../node_modules/base64-js": { + "version": "1.5.1", + "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, + "peer": true + }, + "../../../node_modules/basic-ftp": { + "version": "5.0.4", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=10.0.0" + } + }, + "../../../node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "license": "BSD-3-Clause", + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, + "../../../node_modules/big-integer": { + "version": "1.6.52", + "dev": true, + "license": "Unlicense", + "optional": true, + "peer": true, + "engines": { + "node": ">=0.6" + } + }, + "../../../node_modules/binary": { + "version": "0.3.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "buffers": "~0.1.1", + "chainsaw": "~0.1.0" + } + }, + "../../../node_modules/bluebird": { + "version": "3.4.7", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/brace-expansion": { + "version": "2.0.1", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "../../../node_modules/braces": { + "version": "3.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "../../../node_modules/browser-process-hrtime": { + "version": "1.0.0", + "license": "BSD-2-Clause" + }, + "../../../node_modules/browserslist": { + "version": "4.23.0", + "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", + "optional": true, + "peer": true, + "dependencies": { + "caniuse-lite": "^1.0.30001587", + "electron-to-chromium": "^1.4.668", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.13" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "../../../node_modules/buffer-crc32": { + "version": "0.2.13", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "../../../node_modules/buffer-from": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/buffer-indexof-polyfill": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=0.10" + } + }, + "../../../node_modules/buffers": { + "version": "0.1.1", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=0.2.0" + } + }, + "../../../node_modules/cac": { + "version": "6.7.14", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "../../../node_modules/cacheable-lookup": { + "version": "7.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=14.16" + } + }, + "../../../node_modules/cacheable-request": { + "version": "10.2.14", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@types/http-cache-semantics": "^4.0.2", + "get-stream": "^6.0.1", + "http-cache-semantics": "^4.1.1", + "keyv": "^4.5.3", + "mimic-response": "^4.0.0", + "normalize-url": "^8.0.0", + "responselike": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + } + }, + "../../../node_modules/cacheable-request/node_modules/get-stream": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/call-bind": { + "version": "1.0.5", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.1", + "set-function-length": "^1.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/callsites": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "../../../node_modules/caniuse-lite": { + "version": "1.0.30001596", + "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", + "optional": true, + "peer": true + }, + "../../../node_modules/caseless": { + "version": "0.12.0", + "license": "Apache-2.0" + }, + "../../../node_modules/chai": { + "version": "4.4.1", + "dev": true, + "license": "MIT", + "dependencies": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.3", + "deep-eql": "^4.1.3", + "get-func-name": "^2.0.2", + "loupe": "^2.3.6", + "pathval": "^1.1.1", + "type-detect": "^4.0.8" + }, + "engines": { + "node": ">=4" + } + }, + "../../../node_modules/chainsaw": { + "version": "0.1.0", + "dev": true, + "license": "MIT/X11", + "optional": true, + "peer": true, + "dependencies": { + "traverse": ">=0.3.0 <0.4" + } + }, + "../../../node_modules/chalk": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "../../../node_modules/check-error": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "get-func-name": "^2.0.2" + }, + "engines": { + "node": "*" + } + }, + "../../../node_modules/chrome-trace-event": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=6.0" + } + }, + "../../../node_modules/chromium-bidi": { + "version": "0.4.16", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "peer": true, + "dependencies": { + "mitt": "3.0.0" + }, + "peerDependencies": { + "devtools-protocol": "*" + } + }, + "../../../node_modules/cliui": { + "version": "8.0.1", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/cliui/node_modules/emoji-regex": { + "version": "8.0.0", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/cliui/node_modules/string-width": { + "version": "4.2.3", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "../../../node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "../../../node_modules/clone-deep": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "../../../node_modules/clone-deep/node_modules/kind-of": { + "version": "6.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "../../../node_modules/codemirror": { + "version": "5.65.16", + "license": "MIT" + }, + "../../../node_modules/color-convert": { + "version": "2.0.1", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "../../../node_modules/color-name": { + "version": "1.1.4", + "license": "MIT" + }, + "../../../node_modules/combined-stream": { + "version": "1.0.8", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "../../../node_modules/commander": { + "version": "9.5.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": "^12.20.0 || >=14" + } + }, + "../../../node_modules/compress-commons": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "crc-32": "^1.2.0", + "crc32-stream": "^5.0.0", + "normalize-path": "^3.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "../../../node_modules/compress-commons/node_modules/readable-stream": { + "version": "3.6.2", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "../../../node_modules/concat-map": { + "version": "0.0.1", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/condense-newlines": { + "version": "0.2.1", + "license": "MIT", + "dependencies": { + "extend-shallow": "^2.0.1", + "is-whitespace": "^0.3.0", + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "../../../node_modules/config-chain": { + "version": "1.1.13", + "license": "MIT", + "dependencies": { + "ini": "^1.3.4", + "proto-list": "~1.2.1" + } + }, + "../../../node_modules/config-chain/node_modules/ini": { + "version": "1.3.8", + "license": "ISC" + }, + "../../../node_modules/core-util-is": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/crc-32": { + "version": "1.2.2", + "license": "Apache-2.0", + "bin": { + "crc32": "bin/crc32.njs" + }, + "engines": { + "node": ">=0.8" + } + }, + "../../../node_modules/crc32-stream": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "crc-32": "^1.2.0", + "readable-stream": "^3.4.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "../../../node_modules/crc32-stream/node_modules/readable-stream": { + "version": "3.6.2", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "../../../node_modules/cross-fetch": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "node-fetch": "^2.6.12" + } + }, + "../../../node_modules/cross-fetch/node_modules/node-fetch": { + "version": "2.7.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "../../../node_modules/cross-fetch/node_modules/tr46": { + "version": "0.0.3", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/cross-fetch/node_modules/webidl-conversions": { + "version": "3.0.1", + "dev": true, + "license": "BSD-2-Clause", + "optional": true, + "peer": true + }, + "../../../node_modules/cross-fetch/node_modules/whatwg-url": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "../../../node_modules/cross-spawn": { + "version": "7.0.3", + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "../../../node_modules/css-loader": { + "version": "6.10.0", + "dev": true, + "license": "MIT", + "dependencies": { + "icss-utils": "^5.1.0", + "postcss": "^8.4.33", + "postcss-modules-extract-imports": "^3.0.0", + "postcss-modules-local-by-default": "^4.0.4", + "postcss-modules-scope": "^3.1.1", + "postcss-modules-values": "^4.0.0", + "postcss-value-parser": "^4.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "../../../node_modules/css-shorthand-properties": { + "version": "1.1.1", + "dev": true, + "optional": true, + "peer": true + }, + "../../../node_modules/css-value": { + "version": "0.0.1", + "dev": true, + "optional": true, + "peer": true + }, + "../../../node_modules/cssesc": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "../../../node_modules/cssom": { + "version": "0.5.0", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/cssstyle": { + "version": "2.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "cssom": "~0.3.6" + }, + "engines": { + "node": ">=8" + } + }, + "../../../node_modules/cssstyle/node_modules/cssom": { + "version": "0.3.8", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/dashdash": { + "version": "1.14.1", + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "../../../node_modules/data-uri-to-buffer": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 12" + } + }, + "../../../node_modules/data-urls": { + "version": "3.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "abab": "^2.0.6", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^11.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/data-urls/node_modules/tr46": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/data-urls/node_modules/webidl-conversions": { + "version": "7.0.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/data-urls/node_modules/whatwg-mimetype": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/data-urls/node_modules/whatwg-url": { + "version": "11.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "tr46": "^3.0.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/debounce": { + "version": "1.2.1", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/debug": { + "version": "4.3.4", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "../../../node_modules/decamelize": { + "version": "6.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/decimal.js": { + "version": "10.4.3", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/decompress-response": { + "version": "6.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/decompress-response/node_modules/mimic-response": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/deep-eql": { + "version": "4.1.3", + "dev": true, + "license": "MIT", + "dependencies": { + "type-detect": "^4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "../../../node_modules/deep-is": { + "version": "0.1.4", + "license": "MIT" + }, + "../../../node_modules/deepmerge-ts": { + "version": "5.1.0", + "dev": true, + "license": "BSD-3-Clause", + "optional": true, + "peer": true, + "engines": { + "node": ">=16.0.0" + } + }, + "../../../node_modules/defer-to-connect": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=10" + } + }, + "../../../node_modules/define-data-property": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "../../../node_modules/define-properties": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/degenerator": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "ast-types": "^0.13.4", + "escodegen": "^2.1.0", + "esprima": "^4.0.1" + }, + "engines": { + "node": ">= 14" + } + }, + "../../../node_modules/delayed-stream": { + "version": "1.0.0", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "../../../node_modules/dequal": { + "version": "2.0.3", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, + "../../../node_modules/detect-libc": { + "version": "1.0.3", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "peer": true, + "bin": { + "detect-libc": "bin/detect-libc.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "../../../node_modules/devtools-protocol": { + "version": "0.0.1262051", + "dev": true, + "license": "BSD-3-Clause", + "optional": true, + "peer": true + }, + "../../../node_modules/diff-sequences": { + "version": "29.6.3", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "../../../node_modules/doctrine": { + "version": "3.0.0", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "../../../node_modules/domexception": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "webidl-conversions": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "../../../node_modules/domexception/node_modules/webidl-conversions": { + "version": "5.0.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=8" + } + }, + "../../../node_modules/duplexer": { + "version": "0.1.2", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/duplexer2": { + "version": "0.1.4", + "dev": true, + "license": "BSD-3-Clause", + "optional": true, + "peer": true, + "dependencies": { + "readable-stream": "^2.0.2" + } + }, + "../../../node_modules/eastasianwidth": { + "version": "0.2.0", + "license": "MIT" + }, + "../../../node_modules/ecc-jsbn": { + "version": "0.1.2", + "license": "MIT", + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "../../../node_modules/edge-paths": { + "version": "3.0.5", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@types/which": "^2.0.1", + "which": "^2.0.2" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/shirshak55" + } + }, + "../../../node_modules/edgedriver": { + "version": "5.3.10", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@wdio/logger": "^8.28.0", + "decamelize": "^6.0.0", + "edge-paths": "^3.0.5", + "node-fetch": "^3.3.2", + "unzipper": "^0.10.14", + "which": "^4.0.0" + }, + "bin": { + "edgedriver": "bin/edgedriver.js" + } + }, + "../../../node_modules/edgedriver/node_modules/isexe": { + "version": "3.1.1", + "dev": true, + "license": "ISC", + "optional": true, + "peer": true, + "engines": { + "node": ">=16" + } + }, + "../../../node_modules/edgedriver/node_modules/which": { + "version": "4.0.0", + "dev": true, + "license": "ISC", + "optional": true, + "peer": true, + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^16.13.0 || >=18.0.0" + } + }, + "../../../node_modules/editorconfig": { + "version": "1.0.4", + "license": "MIT", + "dependencies": { + "@one-ini/wasm": "0.1.1", + "commander": "^10.0.0", + "minimatch": "9.0.1", + "semver": "^7.5.3" + }, + "bin": { + "editorconfig": "bin/editorconfig" + }, + "engines": { + "node": ">=14" + } + }, + "../../../node_modules/editorconfig/node_modules/commander": { + "version": "10.0.1", + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "../../../node_modules/editorconfig/node_modules/minimatch": { + "version": "9.0.1", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "../../../node_modules/electron-to-chromium": { + "version": "1.4.699", + "dev": true, + "license": "ISC", + "optional": true, + "peer": true + }, + "../../../node_modules/emoji-regex": { + "version": "9.2.2", + "license": "MIT" + }, + "../../../node_modules/end-of-stream": { + "version": "1.4.4", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "once": "^1.4.0" + } + }, + "../../../node_modules/enhanced-resolve": { + "version": "5.15.0", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "../../../node_modules/es-abstract": { + "version": "1.22.3", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "arraybuffer.prototype.slice": "^1.0.2", + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.5", + "es-set-tostringtag": "^2.0.1", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.2", + "get-symbol-description": "^1.0.0", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0", + "internal-slot": "^1.0.5", + "is-array-buffer": "^3.0.2", + "is-callable": "^1.2.7", + "is-negative-zero": "^2.0.2", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.12", + "is-weakref": "^1.0.2", + "object-inspect": "^1.13.1", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.5.1", + "safe-array-concat": "^1.0.1", + "safe-regex-test": "^1.0.0", + "string.prototype.trim": "^1.2.8", + "string.prototype.trimend": "^1.0.7", + "string.prototype.trimstart": "^1.0.7", + "typed-array-buffer": "^1.0.0", + "typed-array-byte-length": "^1.0.0", + "typed-array-byte-offset": "^1.0.0", + "typed-array-length": "^1.0.4", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/es-module-lexer": { + "version": "1.4.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/es-set-tostringtag": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.2", + "has-tostringtag": "^1.0.0", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "../../../node_modules/es-shim-unscopables": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.0" + } + }, + "../../../node_modules/es-to-primitive": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/esbuild": { + "version": "0.20.1", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.20.1", + "@esbuild/android-arm": "0.20.1", + "@esbuild/android-arm64": "0.20.1", + "@esbuild/android-x64": "0.20.1", + "@esbuild/darwin-arm64": "0.20.1", + "@esbuild/darwin-x64": "0.20.1", + "@esbuild/freebsd-arm64": "0.20.1", + "@esbuild/freebsd-x64": "0.20.1", + "@esbuild/linux-arm": "0.20.1", + "@esbuild/linux-arm64": "0.20.1", + "@esbuild/linux-ia32": "0.20.1", + "@esbuild/linux-loong64": "0.20.1", + "@esbuild/linux-mips64el": "0.20.1", + "@esbuild/linux-ppc64": "0.20.1", + "@esbuild/linux-riscv64": "0.20.1", + "@esbuild/linux-s390x": "0.20.1", + "@esbuild/linux-x64": "0.20.1", + "@esbuild/netbsd-x64": "0.20.1", + "@esbuild/openbsd-x64": "0.20.1", + "@esbuild/sunos-x64": "0.20.1", + "@esbuild/win32-arm64": "0.20.1", + "@esbuild/win32-ia32": "0.20.1", + "@esbuild/win32-x64": "0.20.1" + } + }, + "../../../node_modules/esbuild/node_modules/@esbuild/aix-ppc64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.1.tgz", + "integrity": "sha512-m55cpeupQ2DbuRGQMMZDzbv9J9PgVelPjlcmM5kxHnrBdBx6REaEd7LamYV7Dm8N7rCyR/XwU6rVP8ploKtIkA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/esbuild/node_modules/@esbuild/android-arm": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.1.tgz", + "integrity": "sha512-4j0+G27/2ZXGWR5okcJi7pQYhmkVgb4D7UKwxcqrjhvp5TKWx3cUjgB1CGj1mfdmJBQ9VnUGgUhign+FPF2Zgw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/esbuild/node_modules/@esbuild/android-arm64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.1.tgz", + "integrity": "sha512-hCnXNF0HM6AjowP+Zou0ZJMWWa1VkD77BXe959zERgGJBBxB+sV+J9f/rcjeg2c5bsukD/n17RKWXGFCO5dD5A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/esbuild/node_modules/@esbuild/android-x64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.1.tgz", + "integrity": "sha512-MSfZMBoAsnhpS+2yMFYIQUPs8Z19ajwfuaSZx+tSl09xrHZCjbeXXMsUF/0oq7ojxYEpsSo4c0SfjxOYXRbpaA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/esbuild/node_modules/@esbuild/darwin-arm64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.1.tgz", + "integrity": "sha512-Ylk6rzgMD8klUklGPzS414UQLa5NPXZD5tf8JmQU8GQrj6BrFA/Ic9tb2zRe1kOZyCbGl+e8VMbDRazCEBqPvA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/esbuild/node_modules/@esbuild/darwin-x64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.1.tgz", + "integrity": "sha512-pFIfj7U2w5sMp52wTY1XVOdoxw+GDwy9FsK3OFz4BpMAjvZVs0dT1VXs8aQm22nhwoIWUmIRaE+4xow8xfIDZA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/esbuild/node_modules/@esbuild/freebsd-arm64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.1.tgz", + "integrity": "sha512-UyW1WZvHDuM4xDz0jWun4qtQFauNdXjXOtIy7SYdf7pbxSWWVlqhnR/T2TpX6LX5NI62spt0a3ldIIEkPM6RHw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/esbuild/node_modules/@esbuild/freebsd-x64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.1.tgz", + "integrity": "sha512-itPwCw5C+Jh/c624vcDd9kRCCZVpzpQn8dtwoYIt2TJF3S9xJLiRohnnNrKwREvcZYx0n8sCSbvGH349XkcQeg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/esbuild/node_modules/@esbuild/linux-arm": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.1.tgz", + "integrity": "sha512-LojC28v3+IhIbfQ+Vu4Ut5n3wKcgTu6POKIHN9Wpt0HnfgUGlBuyDDQR4jWZUZFyYLiz4RBBBmfU6sNfn6RhLw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/esbuild/node_modules/@esbuild/linux-arm64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.1.tgz", + "integrity": "sha512-cX8WdlF6Cnvw/DO9/X7XLH2J6CkBnz7Twjpk56cshk9sjYVcuh4sXQBy5bmTwzBjNVZze2yaV1vtcJS04LbN8w==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/esbuild/node_modules/@esbuild/linux-ia32": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.1.tgz", + "integrity": "sha512-4H/sQCy1mnnGkUt/xszaLlYJVTz3W9ep52xEefGtd6yXDQbz/5fZE5dFLUgsPdbUOQANcVUa5iO6g3nyy5BJiw==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/esbuild/node_modules/@esbuild/linux-loong64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.1.tgz", + "integrity": "sha512-c0jgtB+sRHCciVXlyjDcWb2FUuzlGVRwGXgI+3WqKOIuoo8AmZAddzeOHeYLtD+dmtHw3B4Xo9wAUdjlfW5yYA==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/esbuild/node_modules/@esbuild/linux-mips64el": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.1.tgz", + "integrity": "sha512-TgFyCfIxSujyuqdZKDZ3yTwWiGv+KnlOeXXitCQ+trDODJ+ZtGOzLkSWngynP0HZnTsDyBbPy7GWVXWaEl6lhA==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/esbuild/node_modules/@esbuild/linux-ppc64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.1.tgz", + "integrity": "sha512-b+yuD1IUeL+Y93PmFZDZFIElwbmFfIKLKlYI8M6tRyzE6u7oEP7onGk0vZRh8wfVGC2dZoy0EqX1V8qok4qHaw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/esbuild/node_modules/@esbuild/linux-riscv64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.1.tgz", + "integrity": "sha512-wpDlpE0oRKZwX+GfomcALcouqjjV8MIX8DyTrxfyCfXxoKQSDm45CZr9fanJ4F6ckD4yDEPT98SrjvLwIqUCgg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/esbuild/node_modules/@esbuild/linux-s390x": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.1.tgz", + "integrity": "sha512-5BepC2Au80EohQ2dBpyTquqGCES7++p7G+7lXe1bAIvMdXm4YYcEfZtQrP4gaoZ96Wv1Ute61CEHFU7h4FMueQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/esbuild/node_modules/@esbuild/netbsd-x64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.1.tgz", + "integrity": "sha512-4fL68JdrLV2nVW2AaWZBv3XEm3Ae3NZn/7qy2KGAt3dexAgSVT+Hc97JKSZnqezgMlv9x6KV0ZkZY7UO5cNLCg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/esbuild/node_modules/@esbuild/openbsd-x64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.1.tgz", + "integrity": "sha512-GhRuXlvRE+twf2ES+8REbeCb/zeikNqwD3+6S5y5/x+DYbAQUNl0HNBs4RQJqrechS4v4MruEr8ZtAin/hK5iw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/esbuild/node_modules/@esbuild/sunos-x64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.1.tgz", + "integrity": "sha512-ZnWEyCM0G1Ex6JtsygvC3KUUrlDXqOihw8RicRuQAzw+c4f1D66YlPNNV3rkjVW90zXVsHwZYWbJh3v+oQFM9Q==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/esbuild/node_modules/@esbuild/win32-arm64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.1.tgz", + "integrity": "sha512-QZ6gXue0vVQY2Oon9WyLFCdSuYbXSoxaZrPuJ4c20j6ICedfsDilNPYfHLlMH7vGfU5DQR0czHLmJvH4Nzis/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/esbuild/node_modules/@esbuild/win32-ia32": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.1.tgz", + "integrity": "sha512-HzcJa1NcSWTAU0MJIxOho8JftNp9YALui3o+Ny7hCh0v5f90nprly1U3Sj1Ldj/CvKKdvvFsCRvDkpsEMp4DNw==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/esbuild/node_modules/@esbuild/win32-x64": { + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.1.tgz", + "integrity": "sha512-0MBh53o6XtI6ctDnRMeQ+xoCN8kD2qI1rY1KgF/xdWQwoFeKou7puvDfV8/Wv4Ctx2rRpET/gGdz3YlNtNACSA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/escalade": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "../../../node_modules/escape-string-regexp": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/escodegen": { + "version": "2.1.0", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "../../../node_modules/eslint": { + "version": "8.56.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.56.0", + "@humanwhocodes/config-array": "^0.11.13", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "../../../node_modules/eslint-import-resolver-node": { + "version": "0.3.9", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" + } + }, + "../../../node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "../../../node_modules/eslint-import-resolver-typescript": { + "version": "3.6.1", + "dev": true, + "license": "ISC", + "dependencies": { + "debug": "^4.3.4", + "enhanced-resolve": "^5.12.0", + "eslint-module-utils": "^2.7.4", + "fast-glob": "^3.3.1", + "get-tsconfig": "^4.5.0", + "is-core-module": "^2.11.0", + "is-glob": "^4.0.3" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts/projects/eslint-import-resolver-ts" + }, + "peerDependencies": { + "eslint": "*", + "eslint-plugin-import": "*" + } + }, + "../../../node_modules/eslint-module-utils": { + "version": "2.8.0", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.2.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "../../../node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "../../../node_modules/eslint-plugin-import": { + "version": "2.29.1", + "dev": true, + "license": "MIT", + "dependencies": { + "array-includes": "^3.1.7", + "array.prototype.findlastindex": "^1.2.3", + "array.prototype.flat": "^1.3.2", + "array.prototype.flatmap": "^1.3.2", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.8.0", + "hasown": "^2.0.0", + "is-core-module": "^2.13.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.7", + "object.groupby": "^1.0.1", + "object.values": "^1.1.7", + "semver": "^6.3.1", + "tsconfig-paths": "^3.15.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" + } + }, + "../../../node_modules/eslint-plugin-import/node_modules/brace-expansion": { + "version": "1.1.11", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "../../../node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "../../../node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "2.1.0", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "../../../node_modules/eslint-plugin-import/node_modules/minimatch": { + "version": "3.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "../../../node_modules/eslint-plugin-import/node_modules/semver": { + "version": "6.3.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "../../../node_modules/eslint-scope": { + "version": "7.2.2", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "../../../node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "../../../node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.11", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "../../../node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "../../../node_modules/espree": { + "version": "9.6.1", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "../../../node_modules/esprima": { + "version": "4.0.1", + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "../../../node_modules/esquery": { + "version": "1.5.0", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "../../../node_modules/esrecurse": { + "version": "4.3.0", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "../../../node_modules/estraverse": { + "version": "5.3.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "../../../node_modules/esutils": { + "version": "2.0.3", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "../../../node_modules/execa": { + "version": "8.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "../../../node_modules/execa/node_modules/mimic-fn": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/execa/node_modules/npm-run-path": { + "version": "5.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/execa/node_modules/onetime": { + "version": "6.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/execa/node_modules/path-key": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/extend": { + "version": "3.0.2", + "license": "MIT" + }, + "../../../node_modules/extend-shallow": { + "version": "2.0.1", + "license": "MIT", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "../../../node_modules/extract-zip": { + "version": "2.0.1", + "dev": true, + "license": "BSD-2-Clause", + "optional": true, + "peer": true, + "dependencies": { + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + }, + "bin": { + "extract-zip": "cli.js" + }, + "engines": { + "node": ">= 10.17.0" + }, + "optionalDependencies": { + "@types/yauzl": "^2.9.1" + } + }, + "../../../node_modules/extract-zip/node_modules/get-stream": { + "version": "5.2.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/extsprintf": { + "version": "1.3.0", + "engines": [ + "node >=0.6.0" + ], + "license": "MIT" + }, + "../../../node_modules/fast-deep-equal": { + "version": "3.1.3", + "license": "MIT" + }, + "../../../node_modules/fast-fifo": { + "version": "1.3.2", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/fast-glob": { + "version": "3.3.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "../../../node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "../../../node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "license": "MIT" + }, + "../../../node_modules/fast-levenshtein": { + "version": "2.0.6", + "license": "MIT" + }, + "../../../node_modules/fastq": { + "version": "1.17.0", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "../../../node_modules/fd-slicer": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "pend": "~1.2.0" + } + }, + "../../../node_modules/fetch-blob": { + "version": "3.2.0", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "paypal", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + }, + "engines": { + "node": "^12.20 || >= 14.13" + } + }, + "../../../node_modules/fflate": { + "version": "0.8.1", + "license": "MIT" + }, + "../../../node_modules/file-entry-cache": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "../../../node_modules/fill-range": { + "version": "7.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "../../../node_modules/find-up": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/flat": { + "version": "5.0.2", + "dev": true, + "license": "BSD-3-Clause", + "bin": { + "flat": "cli.js" + } + }, + "../../../node_modules/flat-cache": { + "version": "3.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "../../../node_modules/flatted": { + "version": "3.2.9", + "dev": true, + "license": "ISC" + }, + "../../../node_modules/for-each": { + "version": "0.3.3", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.1.3" + } + }, + "../../../node_modules/foreground-child": { + "version": "3.1.1", + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "../../../node_modules/forever-agent": { + "version": "0.6.1", + "license": "Apache-2.0", + "engines": { + "node": "*" + } + }, + "../../../node_modules/form-data": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "../../../node_modules/form-data-encoder": { + "version": "2.1.4", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 14.17" + } + }, + "../../../node_modules/formdata-polyfill": { + "version": "4.0.10", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "fetch-blob": "^3.1.2" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "../../../node_modules/fs-extra": { + "version": "11.2.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "../../../node_modules/fs-extra/node_modules/universalify": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "../../../node_modules/fs.realpath": { + "version": "1.0.0", + "dev": true, + "license": "ISC" + }, + "../../../node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "../../../node_modules/fstream": { + "version": "1.0.12", + "dev": true, + "license": "ISC", + "optional": true, + "peer": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + }, + "engines": { + "node": ">=0.6" + } + }, + "../../../node_modules/fstream/node_modules/brace-expansion": { + "version": "1.1.11", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "../../../node_modules/fstream/node_modules/glob": { + "version": "7.2.3", + "dev": true, + "license": "ISC", + "optional": true, + "peer": 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" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "../../../node_modules/fstream/node_modules/minimatch": { + "version": "3.1.2", + "dev": true, + "license": "ISC", + "optional": true, + "peer": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "../../../node_modules/fstream/node_modules/rimraf": { + "version": "2.7.1", + "dev": true, + "license": "ISC", + "optional": true, + "peer": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "../../../node_modules/function-bind": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/function.prototype.name": { + "version": "1.1.6", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/functions-have-names": { + "version": "1.2.3", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/geckodriver": { + "version": "4.3.3", + "dev": true, + "hasInstallScript": true, + "license": "MPL-2.0", + "optional": true, + "peer": true, + "dependencies": { + "@wdio/logger": "^8.28.0", + "decamelize": "^6.0.0", + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.4", + "node-fetch": "^3.3.2", + "tar-fs": "^3.0.5", + "unzipper": "^0.10.14", + "which": "^4.0.0" + }, + "bin": { + "geckodriver": "bin/geckodriver.js" + }, + "engines": { + "node": "^16.13 || >=18 || >=20" + } + }, + "../../../node_modules/geckodriver/node_modules/agent-base": { + "version": "7.1.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "../../../node_modules/geckodriver/node_modules/http-proxy-agent": { + "version": "7.0.2", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "../../../node_modules/geckodriver/node_modules/https-proxy-agent": { + "version": "7.0.4", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "../../../node_modules/geckodriver/node_modules/isexe": { + "version": "3.1.1", + "dev": true, + "license": "ISC", + "optional": true, + "peer": true, + "engines": { + "node": ">=16" + } + }, + "../../../node_modules/geckodriver/node_modules/which": { + "version": "4.0.0", + "dev": true, + "license": "ISC", + "optional": true, + "peer": true, + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^16.13.0 || >=18.0.0" + } + }, + "../../../node_modules/get-caller-file": { + "version": "2.0.5", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "../../../node_modules/get-func-name": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "../../../node_modules/get-intrinsic": { + "version": "1.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/get-port": { + "version": "7.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/get-stream": { + "version": "8.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/get-symbol-description": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/get-tsconfig": { + "version": "4.7.2", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, + "../../../node_modules/get-uri": { + "version": "6.0.3", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "basic-ftp": "^5.0.2", + "data-uri-to-buffer": "^6.0.2", + "debug": "^4.3.4", + "fs-extra": "^11.2.0" + }, + "engines": { + "node": ">= 14" + } + }, + "../../../node_modules/get-uri/node_modules/data-uri-to-buffer": { + "version": "6.0.2", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 14" + } + }, + "../../../node_modules/getpass": { + "version": "0.1.7", + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0" + } + }, + "../../../node_modules/gl-matrix": { + "version": "3.1.0", + "license": "MIT" + }, + "../../../node_modules/glob": { + "version": "10.3.10", + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.5", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "../../../node_modules/glob-parent": { + "version": "6.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "../../../node_modules/glob-to-regexp": { + "version": "0.4.1", + "dev": true, + "license": "BSD-2-Clause", + "optional": true, + "peer": true + }, + "../../../node_modules/globals": { + "version": "13.24.0", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/globals/node_modules/type-fest": { + "version": "0.20.2", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/globalthis": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/gopd": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/got": { + "version": "12.6.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@sindresorhus/is": "^5.2.0", + "@szmarczak/http-timer": "^5.0.1", + "cacheable-lookup": "^7.0.0", + "cacheable-request": "^10.2.8", + "decompress-response": "^6.0.0", + "form-data-encoder": "^2.1.2", + "get-stream": "^6.0.1", + "http2-wrapper": "^2.1.10", + "lowercase-keys": "^3.0.0", + "p-cancelable": "^3.0.0", + "responselike": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" + } + }, + "../../../node_modules/got/node_modules/get-stream": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/graceful-fs": { + "version": "4.2.11", + "dev": true, + "license": "ISC" + }, + "../../../node_modules/grapheme-splitter": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/graphemer": { + "version": "1.4.0", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/gzip-size": { + "version": "6.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "duplexer": "^0.1.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/har-schema": { + "version": "2.0.0", + "license": "ISC", + "engines": { + "node": ">=4" + } + }, + "../../../node_modules/har-validator": { + "version": "5.1.5", + "license": "MIT", + "dependencies": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "../../../node_modules/has-bigints": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "../../../node_modules/has-property-descriptors": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/has-proto": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/has-symbols": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/has-tostringtag": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/hasown": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "../../../node_modules/html-encoding-sniffer": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-encoding": "^1.0.5" + }, + "engines": { + "node": ">=10" + } + }, + "../../../node_modules/html-escaper": { + "version": "2.0.2", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/http-cache-semantics": { + "version": "4.1.1", + "dev": true, + "license": "BSD-2-Clause", + "optional": true, + "peer": true + }, + "../../../node_modules/http-proxy-agent": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "../../../node_modules/http-signature": { + "version": "1.2.0", + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + }, + "engines": { + "node": ">=0.8", + "npm": ">=1.3.7" + } + }, + "../../../node_modules/http2-wrapper": { + "version": "2.2.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.2.0" + }, + "engines": { + "node": ">=10.19.0" + } + }, + "../../../node_modules/https-proxy-agent": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "../../../node_modules/human-signals": { + "version": "5.0.0", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=16.17.0" + } + }, + "../../../node_modules/iconv-lite": { + "version": "0.4.24", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "../../../node_modules/icss-utils": { + "version": "5.1.0", + "dev": true, + "license": "ISC", + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "../../../node_modules/ieee754": { + "version": "1.2.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause", + "optional": true, + "peer": true + }, + "../../../node_modules/ignore": { + "version": "5.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "../../../node_modules/ikonate": { + "version": "1.1.1", + "license": "MIT", + "dependencies": { + "jsdom": "11.10.0", + "pretty": "^2.0.0", + "xmldom": "^0.1.27" + } + }, + "../../../node_modules/ikonate/node_modules/abab": { + "version": "1.0.4", + "license": "ISC" + }, + "../../../node_modules/ikonate/node_modules/acorn": { + "version": "5.7.4", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "../../../node_modules/ikonate/node_modules/acorn-globals": { + "version": "4.3.4", + "license": "MIT", + "dependencies": { + "acorn": "^6.0.1", + "acorn-walk": "^6.0.1" + } + }, + "../../../node_modules/ikonate/node_modules/acorn-globals/node_modules/acorn": { + "version": "6.4.2", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "../../../node_modules/ikonate/node_modules/acorn-walk": { + "version": "6.2.0", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "../../../node_modules/ikonate/node_modules/cssom": { + "version": "0.3.8", + "license": "MIT" + }, + "../../../node_modules/ikonate/node_modules/cssstyle": { + "version": "0.2.37", + "license": "MIT", + "dependencies": { + "cssom": "0.3.x" + } + }, + "../../../node_modules/ikonate/node_modules/data-urls": { + "version": "1.1.0", + "license": "MIT", + "dependencies": { + "abab": "^2.0.0", + "whatwg-mimetype": "^2.2.0", + "whatwg-url": "^7.0.0" + } + }, + "../../../node_modules/ikonate/node_modules/data-urls/node_modules/abab": { + "version": "2.0.6", + "license": "BSD-3-Clause" + }, + "../../../node_modules/ikonate/node_modules/data-urls/node_modules/whatwg-url": { + "version": "7.1.0", + "license": "MIT", + "dependencies": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + }, + "../../../node_modules/ikonate/node_modules/domexception": { + "version": "1.0.1", + "license": "MIT", + "dependencies": { + "webidl-conversions": "^4.0.2" + } + }, + "../../../node_modules/ikonate/node_modules/escodegen": { + "version": "1.14.3", + "license": "BSD-2-Clause", + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=4.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "../../../node_modules/ikonate/node_modules/estraverse": { + "version": "4.3.0", + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "../../../node_modules/ikonate/node_modules/html-encoding-sniffer": { + "version": "1.0.2", + "license": "MIT", + "dependencies": { + "whatwg-encoding": "^1.0.1" + } + }, + "../../../node_modules/ikonate/node_modules/jsdom": { + "version": "11.10.0", + "license": "MIT", + "dependencies": { + "abab": "^1.0.4", + "acorn": "^5.3.0", + "acorn-globals": "^4.1.0", + "array-equal": "^1.0.0", + "cssom": ">= 0.3.2 < 0.4.0", + "cssstyle": ">= 0.2.37 < 0.3.0", + "data-urls": "^1.0.0", + "domexception": "^1.0.0", + "escodegen": "^1.9.0", + "html-encoding-sniffer": "^1.0.2", + "left-pad": "^1.2.0", + "nwmatcher": "^1.4.3", + "parse5": "4.0.0", + "pn": "^1.1.0", + "request": "^2.83.0", + "request-promise-native": "^1.0.5", + "sax": "^1.2.4", + "symbol-tree": "^3.2.2", + "tough-cookie": "^2.3.3", + "w3c-hr-time": "^1.0.1", + "webidl-conversions": "^4.0.2", + "whatwg-encoding": "^1.0.3", + "whatwg-mimetype": "^2.1.0", + "whatwg-url": "^6.4.0", + "ws": "^4.0.0", + "xml-name-validator": "^3.0.0" + } + }, + "../../../node_modules/ikonate/node_modules/levn": { + "version": "0.3.0", + "license": "MIT", + "dependencies": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "../../../node_modules/ikonate/node_modules/optionator": { + "version": "0.8.3", + "license": "MIT", + "dependencies": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "../../../node_modules/ikonate/node_modules/parse5": { + "version": "4.0.0", + "license": "MIT" + }, + "../../../node_modules/ikonate/node_modules/prelude-ls": { + "version": "1.1.2", + "engines": { + "node": ">= 0.8.0" + } + }, + "../../../node_modules/ikonate/node_modules/safe-buffer": { + "version": "5.1.2", + "license": "MIT" + }, + "../../../node_modules/ikonate/node_modules/tough-cookie": { + "version": "2.5.0", + "license": "BSD-3-Clause", + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "../../../node_modules/ikonate/node_modules/tr46": { + "version": "1.0.1", + "license": "MIT", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "../../../node_modules/ikonate/node_modules/type-check": { + "version": "0.3.2", + "license": "MIT", + "dependencies": { + "prelude-ls": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "../../../node_modules/ikonate/node_modules/webidl-conversions": { + "version": "4.0.2", + "license": "BSD-2-Clause" + }, + "../../../node_modules/ikonate/node_modules/whatwg-url": { + "version": "6.5.0", + "license": "MIT", + "dependencies": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + }, + "../../../node_modules/ikonate/node_modules/ws": { + "version": "4.1.0", + "license": "MIT", + "dependencies": { + "async-limiter": "~1.0.0", + "safe-buffer": "~5.1.0" + } + }, + "../../../node_modules/import-fresh": { + "version": "3.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/import-meta-resolve": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "../../../node_modules/imurmurhash": { + "version": "0.1.4", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "../../../node_modules/inflight": { + "version": "1.0.6", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "../../../node_modules/inherits": { + "version": "2.0.4", + "dev": true, + "license": "ISC" + }, + "../../../node_modules/internal-slot": { + "version": "1.0.6", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.2", + "hasown": "^2.0.0", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "../../../node_modules/ip-address": { + "version": "9.0.5", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "jsbn": "1.1.0", + "sprintf-js": "^1.1.3" + }, + "engines": { + "node": ">= 12" + } + }, + "../../../node_modules/ip-address/node_modules/jsbn": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/is-array-buffer": { + "version": "3.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.0", + "is-typed-array": "^1.1.10" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/is-bigint": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/is-boolean-object": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/is-buffer": { + "version": "1.1.6", + "license": "MIT" + }, + "../../../node_modules/is-callable": { + "version": "1.2.7", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/is-core-module": { + "version": "2.13.1", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/is-date-object": { + "version": "1.0.5", + "dev": true, + "license": "MIT", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/is-extendable": { + "version": "0.1.1", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "../../../node_modules/is-extglob": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "../../../node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "../../../node_modules/is-glob": { + "version": "4.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "../../../node_modules/is-negative-zero": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/is-number": { + "version": "7.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "../../../node_modules/is-number-object": { + "version": "1.0.7", + "dev": true, + "license": "MIT", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/is-path-inside": { + "version": "3.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "../../../node_modules/is-plain-obj": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/is-plain-object": { + "version": "2.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "../../../node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/is-regex": { + "version": "1.1.4", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/is-shared-array-buffer": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/is-stream": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/is-string": { + "version": "1.0.7", + "dev": true, + "license": "MIT", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/is-symbol": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/is-typed-array": { + "version": "1.1.12", + "dev": true, + "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.11" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/is-typedarray": { + "version": "1.0.0", + "license": "MIT" + }, + "../../../node_modules/is-weakref": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/is-whitespace": { + "version": "0.3.0", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "../../../node_modules/isarray": { + "version": "2.0.5", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/isexe": { + "version": "2.0.0", + "license": "ISC" + }, + "../../../node_modules/isobject": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "../../../node_modules/isstream": { + "version": "0.1.2", + "license": "MIT" + }, + "../../../node_modules/jackspeak": { + "version": "2.3.6", + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "../../../node_modules/jest-worker": { + "version": "27.5.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "../../../node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "../../../node_modules/js-beautify": { + "version": "1.14.11", + "license": "MIT", + "dependencies": { + "config-chain": "^1.1.13", + "editorconfig": "^1.0.3", + "glob": "^10.3.3", + "nopt": "^7.2.0" + }, + "bin": { + "css-beautify": "js/bin/css-beautify.js", + "html-beautify": "js/bin/html-beautify.js", + "js-beautify": "js/bin/js-beautify.js" + }, + "engines": { + "node": ">=14" + } + }, + "../../../node_modules/js-yaml": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "../../../node_modules/jsbn": { + "version": "0.1.1", + "license": "MIT" + }, + "../../../node_modules/jsdom": { + "version": "17.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "abab": "^2.0.5", + "acorn": "^8.4.1", + "acorn-globals": "^6.0.0", + "cssom": "^0.5.0", + "cssstyle": "^2.3.0", + "data-urls": "^3.0.0", + "decimal.js": "^10.3.1", + "domexception": "^2.0.1", + "escodegen": "^2.0.0", + "form-data": "^4.0.0", + "html-encoding-sniffer": "^2.0.1", + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "^5.0.0", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.0", + "parse5": "6.0.1", + "saxes": "^5.0.1", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.0.0", + "w3c-hr-time": "^1.0.2", + "w3c-xmlserializer": "^2.0.0", + "webidl-conversions": "^6.1.0", + "whatwg-encoding": "^1.0.5", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^9.0.0", + "ws": "^8.0.0", + "xml-name-validator": "^3.0.0" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "canvas": "^2.5.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "../../../node_modules/json-buffer": { + "version": "3.0.1", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/json-schema": { + "version": "0.4.0", + "license": "(AFL-2.1 OR BSD-3-Clause)" + }, + "../../../node_modules/json-schema-traverse": { + "version": "0.4.1", + "license": "MIT" + }, + "../../../node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/json-stringify-safe": { + "version": "5.0.1", + "license": "ISC" + }, + "../../../node_modules/jsonc-parser": { + "version": "3.2.1", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/jsonfile": { + "version": "6.1.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "../../../node_modules/jsonfile/node_modules/universalify": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "../../../node_modules/jsprim": { + "version": "1.4.2", + "license": "MIT", + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "../../../node_modules/keyv": { + "version": "4.5.4", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "../../../node_modules/kind-of": { + "version": "3.2.2", + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "../../../node_modules/ky": { + "version": "0.33.3", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sindresorhus/ky?sponsor=1" + } + }, + "../../../node_modules/lazystream": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "readable-stream": "^2.0.5" + }, + "engines": { + "node": ">= 0.6.3" + } + }, + "../../../node_modules/left-pad": { + "version": "1.3.0", + "license": "WTFPL" + }, + "../../../node_modules/levn": { + "version": "0.4.1", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "../../../node_modules/lightningcss": { + "version": "1.23.0", + "dev": true, + "license": "MPL-2.0", + "optional": true, + "peer": true, + "dependencies": { + "detect-libc": "^1.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-darwin-arm64": "1.23.0", + "lightningcss-darwin-x64": "1.23.0", + "lightningcss-freebsd-x64": "1.23.0", + "lightningcss-linux-arm-gnueabihf": "1.23.0", + "lightningcss-linux-arm64-gnu": "1.23.0", + "lightningcss-linux-arm64-musl": "1.23.0", + "lightningcss-linux-x64-gnu": "1.23.0", + "lightningcss-linux-x64-musl": "1.23.0", + "lightningcss-win32-x64-msvc": "1.23.0" + } + }, + "../../../node_modules/lightningcss-linux-x64-gnu": { + "version": "1.23.0", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "../../../node_modules/lightningcss-linux-x64-musl": { + "version": "1.23.0", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "../../../node_modules/listenercount": { + "version": "1.0.1", + "dev": true, + "license": "ISC", + "optional": true, + "peer": true + }, + "../../../node_modules/loader-runner": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=6.11.5" + } + }, + "../../../node_modules/local-pkg": { + "version": "0.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "mlly": "^1.4.2", + "pkg-types": "^1.0.3" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "../../../node_modules/locate-app": { + "version": "2.2.20", + "dev": true, + "license": "SEE LICENSE IN LICENSE", + "optional": true, + "peer": true, + "dependencies": { + "n12": "1.8.23", + "type-fest": "2.13.0", + "userhome": "1.0.0" + } + }, + "../../../node_modules/locate-app/node_modules/type-fest": { + "version": "2.13.0", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "optional": true, + "peer": true, + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/locate-path": { + "version": "6.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/lodash": { + "version": "4.17.21", + "license": "MIT" + }, + "../../../node_modules/lodash-es": { + "version": "4.17.21", + "license": "MIT" + }, + "../../../node_modules/lodash.clonedeep": { + "version": "4.5.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/lodash.merge": { + "version": "4.6.2", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/lodash.sortby": { + "version": "4.7.0", + "license": "MIT" + }, + "../../../node_modules/lodash.zip": { + "version": "4.2.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/loglevel": { + "version": "1.9.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 0.6.0" + }, + "funding": { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/loglevel" + } + }, + "../../../node_modules/loglevel-plugin-prefix": { + "version": "0.8.4", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/loupe": { + "version": "2.3.7", + "dev": true, + "license": "MIT", + "dependencies": { + "get-func-name": "^2.0.1" + } + }, + "../../../node_modules/lowercase-keys": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/lru-cache": { + "version": "10.2.0", + "license": "ISC", + "engines": { + "node": "14 || >=16.14" + } + }, + "../../../node_modules/magic-string": { + "version": "0.30.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15" + }, + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/merge-stream": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/merge2": { + "version": "1.4.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "../../../node_modules/micromatch": { + "version": "4.0.5", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "../../../node_modules/mime-db": { + "version": "1.52.0", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "../../../node_modules/mime-types": { + "version": "2.1.35", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "../../../node_modules/mimic-response": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/minimatch": { + "version": "9.0.3", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "../../../node_modules/minimist": { + "version": "1.2.8", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/minipass": { + "version": "7.0.4", + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "../../../node_modules/mitt": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/mkdirp": { + "version": "0.5.6", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "../../../node_modules/mlly": { + "version": "1.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.11.3", + "pathe": "^1.1.2", + "pkg-types": "^1.0.3", + "ufo": "^1.3.2" + } + }, + "../../../node_modules/mrmime": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "../../../node_modules/ms": { + "version": "2.1.2", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/n12": { + "version": "1.8.23", + "dev": true, + "license": "SEE LICENSE IN LICENSE", + "optional": true, + "peer": true + }, + "../../../node_modules/nanoid": { + "version": "3.3.7", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "../../../node_modules/natural-compare": { + "version": "1.4.0", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/neo-async": { + "version": "2.6.2", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/netmask": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 0.4.0" + } + }, + "../../../node_modules/nifti-reader-js": { + "version": "0.6.8", + "license": "MIT", + "dependencies": { + "fflate": "*" + } + }, + "../../../node_modules/node-domexception": { + "version": "1.0.0", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=10.5.0" + } + }, + "../../../node_modules/node-fetch": { + "version": "3.3.2", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" + } + }, + "../../../node_modules/node-releases": { + "version": "2.0.14", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/nopt": { + "version": "7.2.0", + "license": "ISC", + "dependencies": { + "abbrev": "^2.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "../../../node_modules/normalize-path": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "../../../node_modules/normalize-url": { + "version": "8.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/numcodecs": { + "version": "0.3.1", + "license": "MIT", + "dependencies": { + "fflate": "^0.8.0" + } + }, + "../../../node_modules/nwmatcher": { + "version": "1.4.4", + "license": "MIT" + }, + "../../../node_modules/nwsapi": { + "version": "2.2.7", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/oauth-sign": { + "version": "0.9.0", + "license": "Apache-2.0", + "engines": { + "node": "*" + } + }, + "../../../node_modules/object-inspect": { + "version": "1.13.1", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/object-keys": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "../../../node_modules/object.assign": { + "version": "4.1.5", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/object.fromentries": { + "version": "2.0.7", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/object.groupby": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1" + } + }, + "../../../node_modules/object.values": { + "version": "1.1.7", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/once": { + "version": "1.4.0", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "../../../node_modules/opener": { + "version": "1.5.2", + "dev": true, + "license": "(WTFPL OR MIT)", + "bin": { + "opener": "bin/opener-bin.js" + } + }, + "../../../node_modules/optionator": { + "version": "0.9.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@aashutoshrathi/word-wrap": "^1.2.3", + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "../../../node_modules/p-cancelable": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=12.20" + } + }, + "../../../node_modules/p-limit": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/p-locate": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/pac-proxy-agent": { + "version": "7.0.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@tootallnate/quickjs-emscripten": "^0.23.0", + "agent-base": "^7.0.2", + "debug": "^4.3.4", + "get-uri": "^6.0.1", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.2", + "pac-resolver": "^7.0.0", + "socks-proxy-agent": "^8.0.2" + }, + "engines": { + "node": ">= 14" + } + }, + "../../../node_modules/pac-proxy-agent/node_modules/agent-base": { + "version": "7.1.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "../../../node_modules/pac-proxy-agent/node_modules/http-proxy-agent": { + "version": "7.0.2", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "../../../node_modules/pac-proxy-agent/node_modules/https-proxy-agent": { + "version": "7.0.4", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "../../../node_modules/pac-resolver": { + "version": "7.0.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "degenerator": "^5.0.0", + "netmask": "^2.0.2" + }, + "engines": { + "node": ">= 14" + } + }, + "../../../node_modules/parent-module": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "../../../node_modules/parse5": { + "version": "6.0.1", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/path-exists": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "../../../node_modules/path-is-absolute": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "../../../node_modules/path-key": { + "version": "3.1.1", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "../../../node_modules/path-parse": { + "version": "1.0.7", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/path-scurry": { + "version": "1.10.1", + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^9.1.1 || ^10.0.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "../../../node_modules/pathe": { + "version": "1.1.2", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/pathval": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "../../../node_modules/pend": { + "version": "1.2.0", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/performance-now": { + "version": "2.1.0", + "license": "MIT" + }, + "../../../node_modules/picocolors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "dev": true + }, + "../../../node_modules/picomatch": { + "version": "2.3.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "../../../node_modules/pkg-types": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "jsonc-parser": "^3.2.0", + "mlly": "^1.2.0", + "pathe": "^1.1.0" + } + }, + "../../../node_modules/pn": { + "version": "1.1.0", + "license": "MIT" + }, + "../../../node_modules/postcss": { + "version": "8.4.39", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz", + "integrity": "sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==", + "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.7", + "picocolors": "^1.0.1", + "source-map-js": "^1.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "../../../node_modules/postcss-modules-extract-imports": { + "version": "3.0.0", + "dev": true, + "license": "ISC", + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "../../../node_modules/postcss-modules-local-by-default": { + "version": "4.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "icss-utils": "^5.0.0", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.1.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "../../../node_modules/postcss-modules-scope": { + "version": "3.1.1", + "dev": true, + "license": "ISC", + "dependencies": { + "postcss-selector-parser": "^6.0.4" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "../../../node_modules/postcss-modules-values": { + "version": "4.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "icss-utils": "^5.0.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "../../../node_modules/postcss-selector-parser": { + "version": "6.0.15", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "../../../node_modules/postcss-value-parser": { + "version": "4.2.0", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/prelude-ls": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "../../../node_modules/prettier": { + "version": "3.2.5", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "../../../node_modules/pretty": { + "version": "2.0.0", + "license": "MIT", + "dependencies": { + "condense-newlines": "^0.2.1", + "extend-shallow": "^2.0.1", + "js-beautify": "^1.6.12" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "../../../node_modules/pretty-format": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "../../../node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "../../../node_modules/process-nextick-args": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/progress": { + "version": "2.0.3", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=0.4.0" + } + }, + "../../../node_modules/proto-list": { + "version": "1.2.4", + "license": "ISC" + }, + "../../../node_modules/proxy-agent": { + "version": "6.4.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "agent-base": "^7.0.2", + "debug": "^4.3.4", + "http-proxy-agent": "^7.0.1", + "https-proxy-agent": "^7.0.3", + "lru-cache": "^7.14.1", + "pac-proxy-agent": "^7.0.1", + "proxy-from-env": "^1.1.0", + "socks-proxy-agent": "^8.0.2" + }, + "engines": { + "node": ">= 14" + } + }, + "../../../node_modules/proxy-agent/node_modules/agent-base": { + "version": "7.1.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "../../../node_modules/proxy-agent/node_modules/http-proxy-agent": { + "version": "7.0.2", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "../../../node_modules/proxy-agent/node_modules/https-proxy-agent": { + "version": "7.0.4", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "../../../node_modules/proxy-agent/node_modules/lru-cache": { + "version": "7.18.3", + "dev": true, + "license": "ISC", + "optional": true, + "peer": true, + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/proxy-from-env": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/psl": { + "version": "1.9.0", + "license": "MIT" + }, + "../../../node_modules/pump": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "../../../node_modules/punycode": { + "version": "2.3.1", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "../../../node_modules/puppeteer-core": { + "version": "20.9.0", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "peer": true, + "dependencies": { + "@puppeteer/browsers": "1.4.6", + "chromium-bidi": "0.4.16", + "cross-fetch": "4.0.0", + "debug": "4.3.4", + "devtools-protocol": "0.0.1147663", + "ws": "8.13.0" + }, + "engines": { + "node": ">=16.3.0" + }, + "peerDependencies": { + "typescript": ">= 4.7.4" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "../../../node_modules/puppeteer-core/node_modules/devtools-protocol": { + "version": "0.0.1147663", + "dev": true, + "license": "BSD-3-Clause", + "optional": true, + "peer": true + }, + "../../../node_modules/puppeteer-core/node_modules/ws": { + "version": "8.13.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "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_modules/qs": { + "version": "6.5.3", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.6" + } + }, + "../../../node_modules/query-selector-shadow-dom": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/querystringify": { + "version": "2.2.0", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/queue-microtask": { + "version": "1.2.3", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "../../../node_modules/queue-tick": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/quick-lru": { + "version": "5.1.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/randombytes": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "../../../node_modules/react-is": { + "version": "18.2.0", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/readable-stream": { + "version": "2.3.8", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "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" + } + }, + "../../../node_modules/readable-stream/node_modules/isarray": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/readable-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/readdir-glob": { + "version": "1.1.3", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "peer": true, + "dependencies": { + "minimatch": "^5.1.0" + } + }, + "../../../node_modules/readdir-glob/node_modules/minimatch": { + "version": "5.1.6", + "dev": true, + "license": "ISC", + "optional": true, + "peer": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "../../../node_modules/regexp.prototype.flags": { + "version": "1.5.1", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "set-function-name": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/request": { + "version": "2.88.2", + "license": "Apache-2.0", + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "../../../node_modules/request-promise-core": { + "version": "1.1.4", + "license": "ISC", + "dependencies": { + "lodash": "^4.17.19" + }, + "engines": { + "node": ">=0.10.0" + }, + "peerDependencies": { + "request": "^2.34" + } + }, + "../../../node_modules/request-promise-native": { + "version": "1.0.9", + "license": "ISC", + "dependencies": { + "request-promise-core": "1.1.4", + "stealthy-require": "^1.1.1", + "tough-cookie": "^2.3.3" + }, + "engines": { + "node": ">=0.12.0" + }, + "peerDependencies": { + "request": "^2.34" + } + }, + "../../../node_modules/request-promise-native/node_modules/tough-cookie": { + "version": "2.5.0", + "license": "BSD-3-Clause", + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "../../../node_modules/request/node_modules/form-data": { + "version": "2.3.3", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "../../../node_modules/request/node_modules/tough-cookie": { + "version": "2.5.0", + "license": "BSD-3-Clause", + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "../../../node_modules/require-directory": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "../../../node_modules/requires-port": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/resolve": { + "version": "1.22.8", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/resolve-alpn": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/resolve-from": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "../../../node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, + "../../../node_modules/responselike": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "lowercase-keys": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/resq": { + "version": "1.11.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "fast-deep-equal": "^2.0.1" + } + }, + "../../../node_modules/resq/node_modules/fast-deep-equal": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/reusify": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "../../../node_modules/rgb2hex": { + "version": "0.2.5", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/rimraf": { + "version": "3.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "../../../node_modules/rimraf/node_modules/brace-expansion": { + "version": "1.1.11", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "../../../node_modules/rimraf/node_modules/glob": { + "version": "7.2.3", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "../../../node_modules/rimraf/node_modules/minimatch": { + "version": "3.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "../../../node_modules/rollup": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.19.0.tgz", + "integrity": "sha512-5r7EYSQIowHsK4eTZ0Y81qpZuJz+MUuYeqmmYmRMl1nwhdmbiYqt5jwzf6u7wyOzJgYqtCRMtVRKOtHANBz7rA==", + "dev": true, + "dependencies": { + "@types/estree": "1.0.5" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.19.0", + "@rollup/rollup-android-arm64": "4.19.0", + "@rollup/rollup-darwin-arm64": "4.19.0", + "@rollup/rollup-darwin-x64": "4.19.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.19.0", + "@rollup/rollup-linux-arm-musleabihf": "4.19.0", + "@rollup/rollup-linux-arm64-gnu": "4.19.0", + "@rollup/rollup-linux-arm64-musl": "4.19.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.19.0", + "@rollup/rollup-linux-riscv64-gnu": "4.19.0", + "@rollup/rollup-linux-s390x-gnu": "4.19.0", + "@rollup/rollup-linux-x64-gnu": "4.19.0", + "@rollup/rollup-linux-x64-musl": "4.19.0", + "@rollup/rollup-win32-arm64-msvc": "4.19.0", + "@rollup/rollup-win32-ia32-msvc": "4.19.0", + "@rollup/rollup-win32-x64-msvc": "4.19.0", + "fsevents": "~2.3.2" + } + }, + "../../../node_modules/run-parallel": { + "version": "1.2.0", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "../../../node_modules/safaridriver": { + "version": "0.1.2", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/safe-array-concat": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.5", + "get-intrinsic": "^1.2.2", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/safe-buffer": { + "version": "5.2.1", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "../../../node_modules/safe-regex-test": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.5", + "get-intrinsic": "^1.2.2", + "is-regex": "^1.1.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/safer-buffer": { + "version": "2.1.2", + "license": "MIT" + }, + "../../../node_modules/sax": { + "version": "1.3.0", + "license": "ISC" + }, + "../../../node_modules/saxes": { + "version": "5.0.1", + "dev": true, + "license": "ISC", + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=10" + } + }, + "../../../node_modules/schema-utils": { + "version": "3.3.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "../../../node_modules/semver": { + "version": "7.5.4", + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "../../../node_modules/semver/node_modules/lru-cache": { + "version": "6.0.0", + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "../../../node_modules/serialize-error": { + "version": "11.0.3", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "type-fest": "^2.12.2" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/serialize-javascript": { + "version": "6.0.2", + "dev": true, + "license": "BSD-3-Clause", + "optional": true, + "peer": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "../../../node_modules/set-function-length": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.1", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.2", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "../../../node_modules/set-function-name": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.0.1", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "../../../node_modules/setimmediate": { + "version": "1.0.5", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/shallow-clone": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "../../../node_modules/shallow-clone/node_modules/kind-of": { + "version": "6.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "../../../node_modules/shebang-command": { + "version": "2.0.0", + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "../../../node_modules/shebang-regex": { + "version": "3.0.0", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "../../../node_modules/side-channel": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/siginfo": { + "version": "2.0.0", + "dev": true, + "license": "ISC" + }, + "../../../node_modules/signal-exit": { + "version": "4.1.0", + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "../../../node_modules/sirv": { + "version": "2.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@polka/url": "^1.0.0-next.24", + "mrmime": "^2.0.0", + "totalist": "^3.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "../../../node_modules/smart-buffer": { + "version": "4.2.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "../../../node_modules/socks": { + "version": "2.7.3", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "ip-address": "^9.0.5", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" + } + }, + "../../../node_modules/socks-proxy-agent": { + "version": "8.0.2", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "agent-base": "^7.0.2", + "debug": "^4.3.4", + "socks": "^2.7.1" + }, + "engines": { + "node": ">= 14" + } + }, + "../../../node_modules/socks-proxy-agent/node_modules/agent-base": { + "version": "7.1.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "../../../node_modules/source-map": { + "version": "0.6.1", + "license": "BSD-3-Clause", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "../../../node_modules/source-map-js": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "../../../node_modules/source-map-support": { + "version": "0.5.21", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "../../../node_modules/split2": { + "version": "4.2.0", + "dev": true, + "license": "ISC", + "optional": true, + "peer": true, + "engines": { + "node": ">= 10.x" + } + }, + "../../../node_modules/sprintf-js": { + "version": "1.1.3", + "dev": true, + "license": "BSD-3-Clause", + "optional": true, + "peer": true + }, + "../../../node_modules/sshpk": { + "version": "1.18.0", + "license": "MIT", + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "../../../node_modules/stackback": { + "version": "0.0.2", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/std-env": { + "version": "3.7.0", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/stealthy-require": { + "version": "1.1.1", + "license": "ISC", + "engines": { + "node": ">=0.10.0" + } + }, + "../../../node_modules/streamx": { + "version": "2.15.6", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "fast-fifo": "^1.1.0", + "queue-tick": "^1.0.1" + } + }, + "../../../node_modules/string_decoder": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "../../../node_modules/string_decoder/node_modules/safe-buffer": { + "version": "5.1.2", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/string-width": { + "version": "5.1.2", + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "../../../node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "license": "MIT" + }, + "../../../node_modules/string-width/node_modules/ansi-regex": { + "version": "6.0.1", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "../../../node_modules/string-width/node_modules/strip-ansi": { + "version": "7.1.0", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "../../../node_modules/string.prototype.trim": { + "version": "1.2.8", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/string.prototype.trimend": { + "version": "1.0.7", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/string.prototype.trimstart": { + "version": "1.0.7", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/strip-ansi": { + "version": "6.0.1", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "../../../node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "../../../node_modules/strip-bom": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "../../../node_modules/strip-final-newline": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/strip-json-comments": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/strip-literal": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "js-tokens": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "../../../node_modules/strip-literal/node_modules/js-tokens": { + "version": "8.0.3", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "../../../node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/symbol-tree": { + "version": "3.2.4", + "license": "MIT" + }, + "../../../node_modules/tapable": { + "version": "2.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "../../../node_modules/tar-fs": { + "version": "3.0.5", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "pump": "^3.0.0", + "tar-stream": "^3.1.5" + }, + "optionalDependencies": { + "bare-fs": "^2.1.1", + "bare-path": "^2.1.0" + } + }, + "../../../node_modules/tar-stream": { + "version": "3.1.7", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "b4a": "^1.6.4", + "fast-fifo": "^1.2.0", + "streamx": "^2.15.0" + } + }, + "../../../node_modules/terser": { + "version": "5.29.1", + "dev": true, + "license": "BSD-2-Clause", + "optional": true, + "peer": true, + "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" + }, + "engines": { + "node": ">=10" + } + }, + "../../../node_modules/terser-webpack-plugin": { + "version": "5.3.10", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.20", + "jest-worker": "^27.4.5", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.1", + "terser": "^5.26.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "../../../node_modules/terser/node_modules/commander": { + "version": "2.20.3", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/text-table": { + "version": "0.2.0", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/through": { + "version": "2.3.8", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "../../../node_modules/tinybench": { + "version": "2.6.0", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/tinypool": { + "version": "0.8.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "../../../node_modules/tinyspy": { + "version": "2.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "../../../node_modules/to-regex-range": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "../../../node_modules/totalist": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "../../../node_modules/tough-cookie": { + "version": "4.1.3", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.2.0", + "url-parse": "^1.5.3" + }, + "engines": { + "node": ">=6" + } + }, + "../../../node_modules/tr46": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "../../../node_modules/traverse": { + "version": "0.3.9", + "dev": true, + "license": "MIT/X11", + "optional": true, + "peer": true + }, + "../../../node_modules/tsconfig-paths": { + "version": "3.15.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "../../../node_modules/tsconfig-paths/node_modules/json5": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "../../../node_modules/tslib": { + "version": "2.6.2", + "dev": true, + "license": "0BSD", + "optional": true, + "peer": true + }, + "../../../node_modules/tsx": { + "version": "4.7.1", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "~0.19.10", + "get-tsconfig": "^4.7.2" + }, + "bin": { + "tsx": "dist/cli.mjs" + }, + "engines": { + "node": ">=18.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + } + }, + "../../../node_modules/tsx/node_modules/@esbuild/aix-ppc64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz", + "integrity": "sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/tsx/node_modules/@esbuild/android-arm": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.12.tgz", + "integrity": "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/tsx/node_modules/@esbuild/android-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz", + "integrity": "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/tsx/node_modules/@esbuild/android-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.12.tgz", + "integrity": "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/tsx/node_modules/@esbuild/darwin-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz", + "integrity": "sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/tsx/node_modules/@esbuild/darwin-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz", + "integrity": "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/tsx/node_modules/@esbuild/freebsd-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz", + "integrity": "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/tsx/node_modules/@esbuild/freebsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz", + "integrity": "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/tsx/node_modules/@esbuild/linux-arm": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz", + "integrity": "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/tsx/node_modules/@esbuild/linux-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz", + "integrity": "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/tsx/node_modules/@esbuild/linux-ia32": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz", + "integrity": "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/tsx/node_modules/@esbuild/linux-loong64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz", + "integrity": "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/tsx/node_modules/@esbuild/linux-mips64el": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz", + "integrity": "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/tsx/node_modules/@esbuild/linux-ppc64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz", + "integrity": "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/tsx/node_modules/@esbuild/linux-riscv64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz", + "integrity": "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/tsx/node_modules/@esbuild/linux-s390x": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz", + "integrity": "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/tsx/node_modules/@esbuild/linux-x64": { + "version": "0.19.12", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/tsx/node_modules/@esbuild/netbsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz", + "integrity": "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/tsx/node_modules/@esbuild/openbsd-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz", + "integrity": "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/tsx/node_modules/@esbuild/sunos-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz", + "integrity": "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/tsx/node_modules/@esbuild/win32-arm64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz", + "integrity": "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/tsx/node_modules/@esbuild/win32-ia32": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz", + "integrity": "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/tsx/node_modules/@esbuild/win32-x64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz", + "integrity": "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/tsx/node_modules/esbuild": { + "version": "0.19.12", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.19.12", + "@esbuild/android-arm": "0.19.12", + "@esbuild/android-arm64": "0.19.12", + "@esbuild/android-x64": "0.19.12", + "@esbuild/darwin-arm64": "0.19.12", + "@esbuild/darwin-x64": "0.19.12", + "@esbuild/freebsd-arm64": "0.19.12", + "@esbuild/freebsd-x64": "0.19.12", + "@esbuild/linux-arm": "0.19.12", + "@esbuild/linux-arm64": "0.19.12", + "@esbuild/linux-ia32": "0.19.12", + "@esbuild/linux-loong64": "0.19.12", + "@esbuild/linux-mips64el": "0.19.12", + "@esbuild/linux-ppc64": "0.19.12", + "@esbuild/linux-riscv64": "0.19.12", + "@esbuild/linux-s390x": "0.19.12", + "@esbuild/linux-x64": "0.19.12", + "@esbuild/netbsd-x64": "0.19.12", + "@esbuild/openbsd-x64": "0.19.12", + "@esbuild/sunos-x64": "0.19.12", + "@esbuild/win32-arm64": "0.19.12", + "@esbuild/win32-ia32": "0.19.12", + "@esbuild/win32-x64": "0.19.12" + } + }, + "../../../node_modules/tunnel-agent": { + "version": "0.6.0", + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "../../../node_modules/tweetnacl": { + "version": "0.14.5", + "license": "Unlicense" + }, + "../../../node_modules/type-check": { + "version": "0.4.0", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "../../../node_modules/type-detect": { + "version": "4.0.8", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "../../../node_modules/type-fest": { + "version": "2.19.0", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "optional": true, + "peer": true, + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/typed-array-buffer": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + } + }, + "../../../node_modules/typed-array-byte-length": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "has-proto": "^1.0.1", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/typed-array-byte-offset": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "has-proto": "^1.0.1", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/typed-array-length": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "is-typed-array": "^1.1.9" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/typescript": { + "version": "5.3.3", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "../../../node_modules/ufo": { + "version": "1.3.2", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/unbox-primitive": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/unbzip2-stream": { + "version": "1.4.3", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "buffer": "^5.2.1", + "through": "^2.3.8" + } + }, + "../../../node_modules/unbzip2-stream/node_modules/buffer": { + "version": "5.7.1", + "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, + "peer": true, + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "../../../node_modules/undici-types": { + "version": "5.26.5", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/universalify": { + "version": "0.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, + "../../../node_modules/unzipper": { + "version": "0.10.14", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "big-integer": "^1.6.17", + "binary": "~0.3.0", + "bluebird": "~3.4.1", + "buffer-indexof-polyfill": "~1.0.0", + "duplexer2": "~0.1.4", + "fstream": "^1.0.12", + "graceful-fs": "^4.2.2", + "listenercount": "~1.0.1", + "readable-stream": "~2.3.6", + "setimmediate": "~1.0.4" + } + }, + "../../../node_modules/update-browserslist-db": { + "version": "1.0.13", + "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", + "optional": true, + "peer": true, + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "../../../node_modules/uri-js": { + "version": "4.4.1", + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "../../../node_modules/url-parse": { + "version": "1.5.10", + "dev": true, + "license": "MIT", + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, + "../../../node_modules/userhome": { + "version": "1.0.0", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "../../../node_modules/util-deprecate": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/uuid": { + "version": "3.4.0", + "license": "MIT", + "bin": { + "uuid": "bin/uuid" + } + }, + "../../../node_modules/verror": { + "version": "1.10.0", + "engines": [ + "node >=0.6.0" + ], + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "../../../node_modules/verror/node_modules/core-util-is": { + "version": "1.0.2", + "license": "MIT" + }, + "../../../node_modules/vite": { + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.4.tgz", + "integrity": "sha512-Cw+7zL3ZG9/NZBB8C+8QbQZmR54GwqIz+WMI4b3JgdYJvX+ny9AjJXqkGQlDXSXRP9rP0B4tbciRMOVEKulVOA==", + "dev": true, + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.39", + "rollup": "^4.13.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "../../../node_modules/vite-node": { + "version": "1.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "cac": "^6.7.14", + "debug": "^4.3.4", + "pathe": "^1.1.1", + "picocolors": "^1.0.0", + "vite": "^5.0.0" + }, + "bin": { + "vite-node": "vite-node.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "../../../node_modules/vite/node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/vite/node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "../../../node_modules/vitest": { + "version": "1.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/expect": "1.3.1", + "@vitest/runner": "1.3.1", + "@vitest/snapshot": "1.3.1", + "@vitest/spy": "1.3.1", + "@vitest/utils": "1.3.1", + "acorn-walk": "^8.3.2", + "chai": "^4.3.10", + "debug": "^4.3.4", + "execa": "^8.0.1", + "local-pkg": "^0.5.0", + "magic-string": "^0.30.5", + "pathe": "^1.1.1", + "picocolors": "^1.0.0", + "std-env": "^3.5.0", + "strip-literal": "^2.0.0", + "tinybench": "^2.5.1", + "tinypool": "^0.8.2", + "vite": "^5.0.0", + "vite-node": "1.3.1", + "why-is-node-running": "^2.2.2" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@types/node": "^18.0.0 || >=20.0.0", + "@vitest/browser": "1.3.1", + "@vitest/ui": "1.3.1", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } + } + }, + "../../../node_modules/vitest/node_modules/acorn-walk": { + "version": "8.3.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "../../../node_modules/w3c-hr-time": { + "version": "1.0.2", + "license": "MIT", + "dependencies": { + "browser-process-hrtime": "^1.0.0" + } + }, + "../../../node_modules/w3c-xmlserializer": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "xml-name-validator": "^3.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "../../../node_modules/wait-port": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "chalk": "^4.1.2", + "commander": "^9.3.0", + "debug": "^4.3.4" + }, + "bin": { + "wait-port": "bin/wait-port.js" + }, + "engines": { + "node": ">=10" + } + }, + "../../../node_modules/watchpack": { + "version": "2.4.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "../../../node_modules/web-streams-polyfill": { + "version": "3.3.3", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 8" + } + }, + "../../../node_modules/webdriver": { + "version": "8.32.3", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@types/node": "^20.1.0", + "@types/ws": "^8.5.3", + "@wdio/config": "8.32.3", + "@wdio/logger": "8.28.0", + "@wdio/protocols": "8.32.0", + "@wdio/types": "8.32.2", + "@wdio/utils": "8.32.3", + "deepmerge-ts": "^5.1.0", + "got": "^12.6.1", + "ky": "^0.33.0", + "ws": "^8.8.0" + }, + "engines": { + "node": "^16.13 || >=18" + } + }, + "../../../node_modules/webdriverio": { + "version": "8.32.3", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@types/node": "^20.1.0", + "@wdio/config": "8.32.3", + "@wdio/logger": "8.28.0", + "@wdio/protocols": "8.32.0", + "@wdio/repl": "8.24.12", + "@wdio/types": "8.32.2", + "@wdio/utils": "8.32.3", + "archiver": "^6.0.0", + "aria-query": "^5.0.0", + "css-shorthand-properties": "^1.1.1", + "css-value": "^0.0.1", + "devtools-protocol": "^0.0.1262051", + "grapheme-splitter": "^1.0.2", + "import-meta-resolve": "^4.0.0", + "is-plain-obj": "^4.1.0", + "lodash.clonedeep": "^4.5.0", + "lodash.zip": "^4.2.0", + "minimatch": "^9.0.0", + "puppeteer-core": "^20.9.0", + "query-selector-shadow-dom": "^1.0.0", + "resq": "^1.9.1", + "rgb2hex": "0.2.5", + "serialize-error": "^11.0.1", + "webdriver": "8.32.3" + }, + "engines": { + "node": "^16.13 || >=18" + }, + "peerDependencies": { + "devtools": "^8.14.0" + }, + "peerDependenciesMeta": { + "devtools": { + "optional": true + } + } + }, + "../../../node_modules/webidl-conversions": { + "version": "6.1.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=10.4" + } + }, + "../../../node_modules/webpack": { + "version": "5.90.3", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@types/eslint-scope": "^3.7.3", + "@types/estree": "^1.0.5", + "@webassemblyjs/ast": "^1.11.5", + "@webassemblyjs/wasm-edit": "^1.11.5", + "@webassemblyjs/wasm-parser": "^1.11.5", + "acorn": "^8.7.1", + "acorn-import-assertions": "^1.9.0", + "browserslist": "^4.21.10", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.15.0", + "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.9", + "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": "^3.2.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.10", + "watchpack": "^2.4.0", + "webpack-sources": "^3.2.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "../../../node_modules/webpack-bundle-analyzer": { + "version": "4.10.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@discoveryjs/json-ext": "0.5.7", + "acorn": "^8.0.4", + "acorn-walk": "^8.0.0", + "commander": "^7.2.0", + "debounce": "^1.2.1", + "escape-string-regexp": "^4.0.0", + "gzip-size": "^6.0.0", + "html-escaper": "^2.0.2", + "is-plain-object": "^5.0.0", + "opener": "^1.5.2", + "picocolors": "^1.0.0", + "sirv": "^2.0.3", + "ws": "^7.3.1" + }, + "bin": { + "webpack-bundle-analyzer": "lib/bin/analyzer.js" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "../../../node_modules/webpack-bundle-analyzer/node_modules/acorn-walk": { + "version": "8.3.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "../../../node_modules/webpack-bundle-analyzer/node_modules/commander": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "../../../node_modules/webpack-bundle-analyzer/node_modules/is-plain-object": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "../../../node_modules/webpack-bundle-analyzer/node_modules/ws": { + "version": "7.5.9", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "../../../node_modules/webpack-merge": { + "version": "5.10.0", + "dev": true, + "license": "MIT", + "dependencies": { + "clone-deep": "^4.0.1", + "flat": "^5.0.2", + "wildcard": "^2.0.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "../../../node_modules/webpack/node_modules/eslint-scope": { + "version": "5.1.1", + "dev": true, + "license": "BSD-2-Clause", + "optional": true, + "peer": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "../../../node_modules/webpack/node_modules/estraverse": { + "version": "4.3.0", + "dev": true, + "license": "BSD-2-Clause", + "optional": true, + "peer": true, + "engines": { + "node": ">=4.0" + } + }, + "../../../node_modules/webpack/node_modules/events": { + "version": "3.3.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=0.8.x" + } + }, + "../../../node_modules/webpack/node_modules/webpack-sources": { + "version": "3.2.3", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=10.13.0" + } + }, + "../../../node_modules/whatwg-encoding": { + "version": "1.0.5", + "license": "MIT", + "dependencies": { + "iconv-lite": "0.4.24" + } + }, + "../../../node_modules/whatwg-mimetype": { + "version": "2.3.0", + "license": "MIT" + }, + "../../../node_modules/whatwg-url": { + "version": "9.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "tr46": "^2.1.0", + "webidl-conversions": "^6.1.0" + }, + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/which": { + "version": "2.0.2", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "../../../node_modules/which-boxed-primitive": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/which-typed-array": { + "version": "1.1.13", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.4", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../../../node_modules/why-is-node-running": { + "version": "2.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "../../../node_modules/wildcard": { + "version": "2.0.1", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/word-wrap": { + "version": "1.2.5", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "../../../node_modules/wrap-ansi": { + "version": "8.1.0", + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "../../../node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "../../../node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "license": "MIT" + }, + "../../../node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "../../../node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "6.0.1", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "../../../node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "../../../node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "7.1.0", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "../../../node_modules/wrappy": { + "version": "1.0.2", + "dev": true, + "license": "ISC" + }, + "../../../node_modules/ws": { + "version": "8.16.0", + "dev": true, + "license": "MIT", + "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_modules/xml-name-validator": { + "version": "3.0.0", + "license": "Apache-2.0" + }, + "../../../node_modules/xmlchars": { + "version": "2.2.0", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/xmldom": { + "version": "0.1.31", + "license": "(LGPL-2.0 or MIT)", + "engines": { + "node": ">=0.1" + } + }, + "../../../node_modules/y18n": { + "version": "5.0.8", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "../../../node_modules/yallist": { + "version": "4.0.0", + "license": "ISC" + }, + "../../../node_modules/yargs": { + "version": "17.7.2", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/yargs-parser": { + "version": "21.1.1", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "../../../node_modules/yargs/node_modules/emoji-regex": { + "version": "8.0.0", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/yargs/node_modules/string-width": { + "version": "4.2.3", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "../../../node_modules/yauzl": { + "version": "2.10.0", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, + "../../../node_modules/yocto-queue": { + "version": "0.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../../../node_modules/zip-stream": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "archiver-utils": "^4.0.1", + "compress-commons": "^5.0.1", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "../../../node_modules/zip-stream/node_modules/readable-stream": { + "version": "3.6.2", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@discoveryjs/json-ext": { + "version": "0.5.7", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.3", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.5", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.22", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@leichtgewicht/ip-codec": { + "version": "2.0.4", + "dev": true, + "license": "MIT" + }, + "node_modules/@module-federation/runtime": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@module-federation/runtime/-/runtime-0.5.1.tgz", + "integrity": "sha512-xgiMUWwGLWDrvZc9JibuEbXIbhXg6z2oUkemogSvQ4LKvrl/n0kbqP1Blk669mXzyWbqtSp6PpvNdwaE1aN5xQ==", + "dev": true, + "dependencies": { + "@module-federation/sdk": "0.5.1" + } + }, + "node_modules/@module-federation/runtime-tools": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@module-federation/runtime-tools/-/runtime-tools-0.5.1.tgz", + "integrity": "sha512-nfBedkoZ3/SWyO0hnmaxuz0R0iGPSikHZOAZ0N/dVSQaIzlffUo35B5nlC2wgWIc0JdMZfkwkjZRrnuuDIJbzg==", + "dev": true, + "dependencies": { + "@module-federation/runtime": "0.5.1", + "@module-federation/webpack-bundler-runtime": "0.5.1" + } + }, + "node_modules/@module-federation/sdk": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@module-federation/sdk/-/sdk-0.5.1.tgz", + "integrity": "sha512-exvchtjNURJJkpqjQ3/opdbfeT2wPKvrbnGnyRkrwW5o3FH1LaST1tkiNviT6OXTexGaVc2DahbdniQHVtQ7pA==", + "dev": true + }, + "node_modules/@module-federation/webpack-bundler-runtime": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@module-federation/webpack-bundler-runtime/-/webpack-bundler-runtime-0.5.1.tgz", + "integrity": "sha512-mMhRFH0k2VjwHt3Jol9JkUsmI/4XlrAoBG3E0o7HoyoPYv1UFOWyqAflfANcUPgbYpvqmyLzDcO+3IT36LXnrA==", + "dev": true, + "dependencies": { + "@module-federation/runtime": "0.5.1", + "@module-federation/sdk": "0.5.1" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@polka/url": { + "version": "1.0.0-next.28", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.28.tgz", + "integrity": "sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw==", + "dev": true + }, + "node_modules/@rspack/binding": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rspack/binding/-/binding-1.1.5.tgz", + "integrity": "sha512-RsSkgi56Q5XUXut0qweLSE1C4Ogcm7g/ueKoOgsbHAYVKrCs9/dTFlPHWSIAaI7QWh0GWEePR/MM2O2HIu+1rw==", + "dev": true, + "optionalDependencies": { + "@rspack/binding-darwin-arm64": "1.1.5", + "@rspack/binding-darwin-x64": "1.1.5", + "@rspack/binding-linux-arm64-gnu": "1.1.5", + "@rspack/binding-linux-arm64-musl": "1.1.5", + "@rspack/binding-linux-x64-gnu": "1.1.5", + "@rspack/binding-linux-x64-musl": "1.1.5", + "@rspack/binding-win32-arm64-msvc": "1.1.5", + "@rspack/binding-win32-ia32-msvc": "1.1.5", + "@rspack/binding-win32-x64-msvc": "1.1.5" + } + }, + "node_modules/@rspack/binding-darwin-arm64": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rspack/binding-darwin-arm64/-/binding-darwin-arm64-1.1.5.tgz", + "integrity": "sha512-eEynmyPPl+OGYQ9LRFwiQosyRfcca3OQB73akqY4mqDRl39OyiBjq7347DLHJysgbm9z+B1bsiLuh2xc6mdclQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rspack/binding-darwin-x64": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rspack/binding-darwin-x64/-/binding-darwin-x64-1.1.5.tgz", + "integrity": "sha512-I6HPRgogewU5v1OKe3noEzq2U1FCEYAbW+smy+lPvpTW+3X6PlVMzTT4oelhB0EXDQ+KxjXH9KpOKON1hg/JGg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rspack/binding-linux-arm64-gnu": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rspack/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.1.5.tgz", + "integrity": "sha512-LQnqucNa6Dr6y3By+/M2ARO4jDR3AM+PuCsHgzlYT0RDRLS+Ow3f50WbNBf7eI/DhrEA0aucYL3sz1ljguB3EA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rspack/binding-linux-arm64-musl": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rspack/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.1.5.tgz", + "integrity": "sha512-b9L/9HJxrWY4cezPWqgj28I9Xe2XxwLHu8x0CMGobwF2XKR0QQVLAst38RW/EusJ8TURdyvNEOuRZlWEIJuYOw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rspack/binding-linux-x64-gnu": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rspack/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.1.5.tgz", + "integrity": "sha512-0az52ZXTg/ErCGC1v/oFLWByKAiXvng4euv+prwMWF6p1pA7lfLRLzdibDFO4KgC16Zlfcg3hqs7YikLng4x+w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rspack/binding-linux-x64-musl": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rspack/binding-linux-x64-musl/-/binding-linux-x64-musl-1.1.5.tgz", + "integrity": "sha512-EF/LJTtCTkuti2gJnCyvXHC5Q2L5M4+RXm5kj9Bfu/t0Zmmfe6Jd5QUsifgogioeL0ZsH/Pou5QiiVcOFcqFKQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rspack/binding-win32-arm64-msvc": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rspack/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.1.5.tgz", + "integrity": "sha512-VEqhK6HwIHby6gtOkxIx66SkqYndiaP1ddZ3X39RLE40TY3KlNgfG/SzbN9J5Qb+8jjq3ogV8n50+wLEGkhiWw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rspack/binding-win32-ia32-msvc": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rspack/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-1.1.5.tgz", + "integrity": "sha512-Yi2BwYehc5/sRVgI7zTGYJKjnV8UszAJt/stWdFHaq82chHiuuF/tQd1WcBUq0Iin9ylBMo16mRJAuFkFmJ74Q==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rspack/binding-win32-x64-msvc": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rspack/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.1.5.tgz", + "integrity": "sha512-4UArXYqJO1Ni7TmCw1T11JnrwfpoThDdiQ9k1P1voBWK3bDahPEBOptk9ZPu2+ZuRX8hFrvumRKkLY3oy7fTMw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rspack/cli": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rspack/cli/-/cli-1.1.5.tgz", + "integrity": "sha512-R08aM5gEvRV9zSE9fIaTxT77Nu/kRtoghj9TqItFk0xTbFxai9jF1fwRTbnDv23yVGNCwPfwvPOmpqvrf3SGnQ==", + "dev": true, + "dependencies": { + "@discoveryjs/json-ext": "^0.5.7", + "@rspack/dev-server": "1.0.9", + "colorette": "2.0.19", + "exit-hook": "^4.0.0", + "interpret": "^3.1.1", + "rechoir": "^0.8.0", + "semver": "^7.6.2", + "webpack-bundle-analyzer": "4.6.1", + "yargs": "17.6.2" + }, + "bin": { + "rspack": "bin/rspack.js" + }, + "peerDependencies": { + "@rspack/core": "^1.0.0-alpha || ^1.x" + } + }, + "node_modules/@rspack/cli/node_modules/colorette": { + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz", + "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==", + "dev": true + }, + "node_modules/@rspack/core": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rspack/core/-/core-1.1.5.tgz", + "integrity": "sha512-/FmxDeMuW8fJkhz8fHuCu7OiJHFKW78xclEu7LkEujWl4PqJgdWjUL/6FWIj50spRwj6PRfuc31hFSL4hbNfCA==", + "dev": true, + "dependencies": { + "@module-federation/runtime-tools": "0.5.1", + "@rspack/binding": "1.1.5", + "@rspack/lite-tapable": "1.0.1", + "caniuse-lite": "^1.0.30001616" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@swc/helpers": ">=0.5.1" + }, + "peerDependenciesMeta": { + "@swc/helpers": { + "optional": true + } + } + }, + "node_modules/@rspack/dev-server": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@rspack/dev-server/-/dev-server-1.0.9.tgz", + "integrity": "sha512-VF+apLFfl5LWIhVbfkJ5ccU0Atl5mi+sGTkx+XtE1tbUmMJkde0nm/4+eaQCud7oGl+ZCzt4kW14uuzLSiEGDw==", + "dev": true, + "dependencies": { + "chokidar": "^3.6.0", + "connect-history-api-fallback": "^2.0.0", + "express": "^4.19.2", + "http-proxy-middleware": "^2.0.6", + "mime-types": "^2.1.35", + "p-retry": "4.6.2", + "webpack-dev-middleware": "^7.4.2", + "webpack-dev-server": "5.0.4", + "ws": "^8.16.0" + }, + "peerDependencies": { + "@rspack/core": "*" + } + }, + "node_modules/@rspack/dev-server/node_modules/@types/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==", + "dev": true + }, + "node_modules/@rspack/dev-server/node_modules/p-retry": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", + "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", + "dev": true, + "dependencies": { + "@types/retry": "0.12.0", + "retry": "^0.13.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@rspack/lite-tapable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@rspack/lite-tapable/-/lite-tapable-1.0.1.tgz", + "integrity": "sha512-VynGOEsVw2s8TAlLf/uESfrgfrq2+rcXB1muPJYBWbsm1Oa6r5qVQhjA5ggM6z/coYPrsVMgovl3Ff7Q7OCp1w==", + "dev": true, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/bonjour": { + "version": "3.5.13", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect-history-api-fallback": { + "version": "1.5.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/express-serve-static-core": "*", + "@types/node": "*" + } + }, + "node_modules/@types/eslint": { + "version": "8.56.2", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.7", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.5", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/@types/express": { + "version": "4.17.21", + "dev": true, + "license": "MIT", + "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.17.42", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/http-errors": { + "version": "2.0.4", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/http-proxy": { + "version": "1.17.14", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/mime": { + "version": "1.3.5", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "20.11.10", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/node-forge": { + "version": "1.3.11", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/qs": { + "version": "6.9.11", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/retry": { + "version": "0.12.2", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/send": { + "version": "0.17.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-index": { + "version": "1.9.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/express": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/http-errors": "*", + "@types/mime": "*", + "@types/node": "*" + } + }, + "node_modules/@types/sockjs": { + "version": "0.3.36", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/ws": { + "version": "8.5.10", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", + "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", + "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", + "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", + "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.12.1" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", + "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", + "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", + "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-opt": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1", + "@webassemblyjs/wast-printer": "1.12.1" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", + "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", + "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", + "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", + "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.12.1", + "@xtuc/long": "4.2.2" + } + }, + "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, + "optional": true, + "peer": 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, + "optional": true, + "peer": true + }, + "node_modules/accepts": { + "version": "1.3.8", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.11.3", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-import-attributes": { + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", + "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", + "dev": true, + "optional": true, + "peer": true, + "peerDependencies": { + "acorn": "^8" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", + "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", + "dev": true, + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-formats/node_modules/ajv": { + "version": "8.12.0", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats/node_modules/json-schema-traverse": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ajv-keywords": { + "version": "3.5.2", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/ansi-html-community": { + "version": "0.0.8", + "dev": true, + "engines": [ + "node >= 0.8.0" + ], + "license": "Apache-2.0", + "bin": { + "ansi-html": "bin/ansi-html" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "6.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "dev": true, + "license": "MIT" + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/batch": { + "version": "0.6.1", + "dev": true, + "license": "MIT" + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/body-parser": { + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", + "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", + "dev": true, + "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.11.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/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/bonjour-service": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "multicast-dns": "^7.2.5" + } + }, + "node_modules/brace-expansion": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.22.3", + "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", + "optional": true, + "peer": true, + "dependencies": { + "caniuse-lite": "^1.0.30001580", + "electron-to-chromium": "^1.4.648", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.13" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/bundle-name": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "run-applescript": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bytes": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001687", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001687.tgz", + "integrity": "sha512-0S/FDhf4ZiqrTUiQ39dKeUjYRjkv7lOZU1Dgif2rIqrTzX/1wV2hfKu9TOm1IHkdSijfLswxTFzl/cvir+SLSQ==", + "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==", + "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" + } + }, + "node_modules/chalk/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/chalk/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, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "dev": true, + "license": "MIT", + "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" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chrome-trace-event": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=6.0" + } + }, + "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/cliui/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/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==", + "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==", + "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/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==", + "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/color-convert": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/colorette": { + "version": "2.0.20", + "dev": true, + "license": "MIT" + }, + "node_modules/commander": { + "version": "2.20.3", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/compressible": { + "version": "2.0.18", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": ">= 1.43.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/compression": { + "version": "1.7.4", + "dev": true, + "license": "MIT", + "dependencies": { + "accepts": "~1.3.5", + "bytes": "3.0.0", + "compressible": "~2.0.16", + "debug": "2.6.9", + "on-headers": "~1.0.2", + "safe-buffer": "5.1.2", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/compression/node_modules/safe-buffer": { + "version": "5.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/connect-history-api-fallback": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "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, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "dev": true, + "license": "MIT" + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "dev": true, + "license": "MIT" + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "2.6.9", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/default-browser": { + "version": "5.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "bundle-name": "^4.1.0", + "default-browser-id": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser-id": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-gateway": { + "version": "6.0.3", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "execa": "^5.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-lazy-prop": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/detect-node": { + "version": "2.1.0", + "dev": true, + "license": "MIT" + }, + "node_modules/dns-packet": { + "version": "5.6.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@leichtgewicht/ip-codec": "^2.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/duplexer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", + "dev": true + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ee-first": { + "version": "1.1.1", + "dev": true, + "license": "MIT" + }, + "node_modules/electron-to-chromium": { + "version": "1.4.649", + "dev": true, + "license": "ISC", + "optional": true, + "peer": true + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "dev": true, + "license": "MIT" + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/enhanced-resolve": { + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", + "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "1.4.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/escalade": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "dev": true, + "license": "MIT" + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "dev": true, + "license": "BSD-2-Clause", + "optional": true, + "peer": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "dev": true, + "license": "BSD-2-Clause", + "optional": true, + "peer": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "dev": true, + "license": "BSD-2-Clause", + "optional": true, + "peer": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "dev": true, + "license": "BSD-2-Clause", + "optional": true, + "peer": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "dev": true, + "license": "MIT" + }, + "node_modules/events": { + "version": "3.3.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/exit-hook": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-4.0.0.tgz", + "integrity": "sha512-Fqs7ChZm72y40wKjOFXBKg7nJZvQJmewP5/7LtePDdnah/+FH9Hp5sgMujSCMPXlxOAW2//1jrW9pnsY7o20vQ==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/express": { + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", + "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", + "dev": true, + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.2", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.6.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.11.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/faye-websocket": { + "version": "0.11.4", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/foreground-child": { + "version": "3.1.1", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/foreground-child/node_modules/signal-exit": { + "version": "4.1.0", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/glob": { + "version": "10.3.10", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.5", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "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, + "optional": true, + "peer": true + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "dev": true, + "license": "ISC" + }, + "node_modules/gzip-size": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", + "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==", + "dev": true, + "dependencies": { + "duplexer": "^0.1.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/handle-thing": { + "version": "2.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hpack.js": { + "version": "2.1.6", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" + } + }, + "node_modules/hpack.js/node_modules/readable-stream": { + "version": "2.3.8", + "dev": true, + "license": "MIT", + "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" + } + }, + "node_modules/hpack.js/node_modules/safe-buffer": { + "version": "5.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/hpack.js/node_modules/string_decoder": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/html-entities": { + "version": "2.4.0", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/mdevils" + }, + { + "type": "patreon", + "url": "https://patreon.com/mdevils" + } + ], + "license": "MIT" + }, + "node_modules/http-deceiver": { + "version": "1.2.7", + "dev": true, + "license": "MIT" + }, + "node_modules/http-errors": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-parser-js": { + "version": "0.5.8", + "dev": true, + "license": "MIT" + }, + "node_modules/http-proxy": { + "version": "1.18.1", + "dev": true, + "license": "MIT", + "dependencies": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/http-proxy-middleware": { + "version": "2.0.6", + "dev": true, + "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" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "@types/express": "^4.17.13" + }, + "peerDependenciesMeta": { + "@types/express": { + "optional": true + } + } + }, + "node_modules/human-signals": { + "version": "2.1.0", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.17.0" + } + }, + "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": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "dev": true, + "license": "ISC" + }, + "node_modules/interpret": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/ipaddr.js": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-core-module": { + "version": "2.13.1", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-docker": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-inside-container": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-network-error": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-plain-obj": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-wsl": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "is-inside-container": "^1.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/jackspeak": { + "version": "2.3.6", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jest-worker": { + "version": "27.5.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/launch-editor": { + "version": "2.6.1", + "dev": true, + "license": "MIT", + "dependencies": { + "picocolors": "^1.0.0", + "shell-quote": "^1.8.1" + } + }, + "node_modules/loader-runner": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=6.11.5" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "dev": true, + "license": "MIT" + }, + "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": ">= 0.6" + } + }, + "node_modules/memfs": { + "version": "4.7.7", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">= 4.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/methods": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "dev": true, + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "dev": true, + "license": "ISC" + }, + "node_modules/minimatch": { + "version": "9.0.3", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minipass": { + "version": "7.0.4", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/mrmime": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-1.0.1.tgz", + "integrity": "sha512-hzzEagAgDyoU1Q6yg5uI+AorQgdvMCur3FcKf7NhMKWsaYg+RnbTyHRa/9IlLF9rf455MOCtcqqrQQ83pPP7Uw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/multicast-dns": { + "version": "7.2.5", + "dev": true, + "license": "MIT", + "dependencies": { + "dns-packet": "^5.2.2", + "thunky": "^1.0.2" + }, + "bin": { + "multicast-dns": "cli.js" + } + }, + "node_modules/negotiator": { + "version": "0.6.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/neuroglancer": { + "resolved": "../../..", + "link": true + }, + "node_modules/node-forge": { + "version": "1.3.1", + "dev": true, + "license": "(BSD-3-Clause OR GPL-2.0)", + "engines": { + "node": ">= 6.13.0" + } + }, + "node_modules/node-releases": { + "version": "2.0.14", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/object-inspect": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/obuf": { + "version": "1.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/on-finished": { + "version": "2.4.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/on-headers": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/open": { + "version": "10.0.3", + "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" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/opener": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", + "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", + "dev": true, + "bin": { + "opener": "bin/opener-bin.js" + } + }, + "node_modules/p-retry": { + "version": "6.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/retry": "0.12.2", + "is-network-error": "^1.0.0", + "retry": "^0.13.1" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "dev": true, + "license": "MIT" + }, + "node_modules/path-scurry": { + "version": "1.10.1", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^9.1.1 || ^10.0.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.2.0", + "dev": true, + "license": "ISC", + "engines": { + "node": "14 || >=16.14" + } + }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "dev": true, + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "dev": true, + "license": "MIT", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/proxy-addr/node_modules/ipaddr.js": { + "version": "1.9.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dev": true, + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "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==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/raw-body/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": ">= 0.8" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/rechoir": { + "version": "0.8.0", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve": "^1.20.0" + }, + "engines": { + "node": ">= 10.13.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==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/resolve": { + "version": "1.22.8", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/retry": { + "version": "0.13.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/rimraf": { + "version": "5.0.5", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^10.3.7" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/run-applescript": { + "version": "7.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "node_modules/schema-utils": { + "version": "3.3.0", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/select-hose": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/selfsigned": { + "version": "2.4.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node-forge": "^1.3.0", + "node-forge": "^1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/send": { + "version": "0.18.0", + "dev": true, + "license": "MIT", + "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" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "dev": true, + "license": "BSD-3-Clause", + "optional": true, + "peer": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/serve-index": { + "version": "1.9.1", + "dev": true, + "license": "MIT", + "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" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/serve-index/node_modules/depd": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/http-errors": { + "version": "1.6.3", + "dev": true, + "license": "MIT", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/inherits": { + "version": "2.0.3", + "dev": true, + "license": "ISC" + }, + "node_modules/serve-index/node_modules/setprototypeof": { + "version": "1.1.0", + "dev": true, + "license": "ISC" + }, + "node_modules/serve-index/node_modules/statuses": { + "version": "1.5.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-static": { + "version": "1.15.0", + "dev": true, + "license": "MIT", + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "dev": true, + "license": "ISC" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/shell-quote": { + "version": "1.8.1", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "dev": true, + "license": "ISC" + }, + "node_modules/sirv": { + "version": "1.0.19", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-1.0.19.tgz", + "integrity": "sha512-JuLThK3TnZG1TAKDwNIqNq6QA2afLOCcm+iE8D1Kj3GA40pSPsxQjjJl0J8X3tsR7T+CP1GavpzLwYkgVLWrZQ==", + "dev": true, + "dependencies": { + "@polka/url": "^1.0.0-next.20", + "mrmime": "^1.0.0", + "totalist": "^1.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/sockjs": { + "version": "0.3.24", + "dev": true, + "license": "MIT", + "dependencies": { + "faye-websocket": "^0.11.3", + "uuid": "^8.3.2", + "websocket-driver": "^0.7.4" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "dev": true, + "license": "BSD-3-Clause", + "optional": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/spdy": { + "version": "4.0.2", + "dev": true, + "license": "MIT", + "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" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/spdy-transport": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "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_modules/spdy-transport/node_modules/debug": { + "version": "4.3.4", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/spdy-transport/node_modules/ms": { + "version": "2.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/spdy/node_modules/debug": { + "version": "4.3.4", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/spdy/node_modules/ms": { + "version": "2.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/statuses": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "5.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/string-width/node_modules/ansi-regex": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/string-width/node_modules/strip-ansi": { + "version": "7.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/supports-color": { + "version": "8.1.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tapable": { + "version": "2.2.1", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/terser": { + "version": "5.27.0", + "dev": true, + "license": "BSD-2-Clause", + "optional": true, + "peer": true, + "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" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.3.10", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.20", + "jest-worker": "^27.4.5", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.1", + "terser": "^5.26.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/thunky": { + "version": "1.1.0", + "dev": true, + "license": "MIT" + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/totalist": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-1.1.0.tgz", + "integrity": "sha512-gduQwd1rOdDMGxFG1gEvhV88Oirdo2p+KjoYFU7k2g+i7n6AFFbDQ5kMPUsW0pNbfQsB/cwXvT1i4Bue0s9g5g==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/tslib": { + "version": "2.6.2", + "dev": true, + "license": "0BSD" + }, + "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": ">= 0.6" + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "dev": true, + "license": "MIT" + }, + "node_modules/unpipe": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.0.13", + "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", + "optional": true, + "peer": true, + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "8.3.2", + "dev": true, + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/watchpack": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.1.tgz", + "integrity": "sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/wbuf": { + "version": "1.7.3", + "dev": true, + "license": "MIT", + "dependencies": { + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/webpack": { + "version": "5.93.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.93.0.tgz", + "integrity": "sha512-Y0m5oEY1LRuwly578VqluorkXbvXKh7U3rLoQCEO04M97ScRr44afGVkI0FQFsXzysk5OgFAxjZAb9rsGQVihA==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@types/eslint-scope": "^3.7.3", + "@types/estree": "^1.0.5", + "@webassemblyjs/ast": "^1.12.1", + "@webassemblyjs/wasm-edit": "^1.12.1", + "@webassemblyjs/wasm-parser": "^1.12.1", + "acorn": "^8.7.1", + "acorn-import-attributes": "^1.9.5", + "browserslist": "^4.21.10", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.17.0", + "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": "^3.2.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.10", + "watchpack": "^2.4.1", + "webpack-sources": "^3.2.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-bundle-analyzer": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.6.1.tgz", + "integrity": "sha512-oKz9Oz9j3rUciLNfpGFjOb49/jEpXNmWdVH8Ls//zNcnLlQdTGXQQMsBbb/gR7Zl8WNLxVCq+0Hqbx3zv6twBw==", + "dev": true, + "dependencies": { + "acorn": "^8.0.4", + "acorn-walk": "^8.0.0", + "chalk": "^4.1.0", + "commander": "^7.2.0", + "gzip-size": "^6.0.0", + "lodash": "^4.17.20", + "opener": "^1.5.2", + "sirv": "^1.0.7", + "ws": "^7.3.1" + }, + "bin": { + "webpack-bundle-analyzer": "lib/bin/analyzer.js" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/webpack-bundle-analyzer/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/webpack-bundle-analyzer/node_modules/ws": { + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", + "dev": true, + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/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==", + "dev": true, + "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" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + } + } + }, + "node_modules/webpack-dev-middleware/node_modules/ajv": { + "version": "8.12.0", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/webpack-dev-middleware/node_modules/ajv-keywords": { + "version": "5.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/webpack-dev-middleware/node_modules/json-schema-traverse": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/webpack-dev-middleware/node_modules/schema-utils": { + "version": "4.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/webpack-dev-server": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-5.0.4.tgz", + "integrity": "sha512-dljXhUgx3HqKP2d8J/fUMvhxGhzjeNVarDLcbO/EWMSgRizDkxHQDZQaLFL5VJY9tRBj2Gz+rvCEYYvhbqPHNA==", + "dev": true, + "dependencies": { + "@types/bonjour": "^3.5.13", + "@types/connect-history-api-fallback": "^1.5.4", + "@types/express": "^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", + "default-gateway": "^6.0.3", + "express": "^4.17.3", + "graceful-fs": "^4.2.6", + "html-entities": "^2.4.0", + "http-proxy-middleware": "^2.0.3", + "ipaddr.js": "^2.1.0", + "launch-editor": "^2.6.1", + "open": "^10.0.3", + "p-retry": "^6.2.0", + "rimraf": "^5.0.5", + "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.1.0", + "ws": "^8.16.0" + }, + "bin": { + "webpack-dev-server": "bin/webpack-dev-server.js" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + }, + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-dev-server/node_modules/ajv": { + "version": "8.12.0", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/webpack-dev-server/node_modules/ajv-keywords": { + "version": "5.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/webpack-dev-server/node_modules/json-schema-traverse": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/webpack-dev-server/node_modules/schema-utils": { + "version": "4.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/webpack-sources": { + "version": "3.2.3", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/websocket-driver": { + "version": "0.7.4", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "7.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/ws": { + "version": "8.16.0", + "dev": true, + "license": "MIT", + "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_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs": { + "version": "17.6.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz", + "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==", + "dev": true, + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "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/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" + } + } + } +} diff --git a/examples/rspack/rspack-project-source/package.json b/examples/rspack/rspack-project-source/package.json new file mode 100644 index 0000000000..615515febd --- /dev/null +++ b/examples/rspack/rspack-project-source/package.json @@ -0,0 +1,24 @@ +{ + "name": "neuroglancer-rspack-project-source", + "version": "0.0.0", + "private": true, + "description": "Test of an rspack-bundled project that depends on Neuroglancer.", + "scripts": { + "build": "rspack build", + "dev-server": "rspack serve" + }, + "dependencies": { + "neuroglancer": "file:../../.." + }, + "browserslist": [ + "last 2 Chrome versions", + "last 2 Firefox versions", + "last 2 Safari versions" + ], + "license": "Apache-2.0", + "devDependencies": { + "@rspack/cli": "^1.1.5", + "@rspack/core": "^1.1.5" + }, + "type": "module" +} diff --git a/examples/rspack/rspack-project-source/rspack.config.js b/examples/rspack/rspack-project-source/rspack.config.js new file mode 100644 index 0000000000..8eff44f67b --- /dev/null +++ b/examples/rspack/rspack-project-source/rspack.config.js @@ -0,0 +1,61 @@ +import rspack from "@rspack/core"; + +export default { + mode: "development", + performance: { + // Avoid unhelpful warnings due to large bundles. + maxAssetSize: 3 * 1024 * 1024, + maxEntrypointSize: 3 * 1024 * 1024, + }, + module: { + rules: [ + // Needed to support Neuroglancer TypeScript sources when using + // Neuroglancer source package directly. + { + test: /\.tsx?$/, + loader: "builtin:swc-loader", + options: { + jsc: { + parser: { + syntax: "typescript", + decorators: true, + }, + }, + }, + type: "javascript/auto", + }, + // Needed for .svg?raw imports used for embedding icons. + { + resourceQuery: /raw/, + type: "asset/source", + }, + // Needed for .html assets used for auth redirect pages for the brainmaps + // and bossDB data sources. Can be skipped if those data sources are + // excluded. + { + test: /\.html$/, + type: "asset/resource", + generator: { + // Filename must be preserved since exact redirect URLs must be allowlisted. + filename: "[name][ext]", + }, + }, + ], + }, + devServer: { + client: { + overlay: { + // Prevent intrusive notification spam. + runtimeErrors: false, + }, + }, + }, + plugins: [ + new rspack.HtmlRspackPlugin({ + title: "Neuroglancer webpack test", + }), + ], + experiments: { + css: true, + }, +}; diff --git a/examples/rspack/rspack-project-source/src/index.js b/examples/rspack/rspack-project-source/src/index.js new file mode 100644 index 0000000000..805818b627 --- /dev/null +++ b/examples/rspack/rspack-project-source/src/index.js @@ -0,0 +1,3 @@ +import "neuroglancer"; +import { setupDefaultViewer } from "neuroglancer/unstable/ui/default_viewer_setup.js"; +setupDefaultViewer(); diff --git a/examples/vite/vite-project-built/package-lock.json b/examples/vite/vite-project-built/package-lock.json index 4c96409511..eb70c5c6d2 100644 --- a/examples/vite/vite-project-built/package-lock.json +++ b/examples/vite/vite-project-built/package-lock.json @@ -21,16 +21,16 @@ "license": "Apache-2.0", "dependencies": { "codemirror": "^5.61.1", + "core-js": "^3.40.0", + "crc-32": "^1.2.2", "gl-matrix": "3.1.0", - "glsl-editor": "^1.0.0", "ikonate": "github:mikolajdobrucki/ikonate#a86b4107c6ec717e7877f880a930d1ccf0b59d89", "lodash-es": "^4.17.21", "nifti-reader-js": "^0.6.8", - "numcodecs": "^0.3.1", - "pako": "^2.1.0" + "numcodecs": "^0.3.2" }, "engines": { - "node": ">=20.10 <21 || >=21.2" + "node": ">=22" } }, "node_modules/@esbuild/aix-ppc64": { diff --git a/examples/vite/vite-project-built/vite.config.ts b/examples/vite/vite-project-built/vite.config.ts index b8be9b45a4..1ae991fa49 100644 --- a/examples/vite/vite-project-built/vite.config.ts +++ b/examples/vite/vite-project-built/vite.config.ts @@ -23,8 +23,28 @@ export default defineConfig({ fs: { // Allow serving files from parent neuroglancer project, due to the local // path reference. This would not be needed for projects that depend on - // Neuroglancer normally. + // Neuroglancer normally, or when using pnpm rather than npm. allow: ["../../.."], }, }, + optimizeDeps: { + // Neuroglancer is incompatible with Vite's optimizeDeps step used for the + // dev server due to its use of `new URL` syntax (not supported by esbuild). + exclude: ["neuroglancer"], + // Some of Neuroglancer's dependencies are CommonJS modules for which the + // optimizeDeps step is mandatory. + // + // There does not seem to be a way to avoid having to specify all of these + // explicitly. + include: [ + "neuroglancer > codemirror", + "neuroglancer > codemirror/mode/javascript/javascript.js", + "neuroglancer > codemirror/addon/fold/foldcode.js", + "neuroglancer > codemirror/addon/fold/foldgutter.js", + "neuroglancer > codemirror/addon/fold/brace-fold.js", + "neuroglancer > codemirror/addon/lint/lint.js", + "neuroglancer > core-js/actual/symbol/dispose.js", + "neuroglancer > core-js/actual/symbol/async-dispose.js", + ], + }, }); diff --git a/examples/vite/vite-project-source/package-lock.json b/examples/vite/vite-project-source/package-lock.json index 7427d782d5..2816c75a6d 100644 --- a/examples/vite/vite-project-source/package-lock.json +++ b/examples/vite/vite-project-source/package-lock.json @@ -20,53 +20,63 @@ "license": "Apache-2.0", "dependencies": { "codemirror": "^5.61.1", + "core-js": "^3.40.0", + "crc-32": "^1.2.2", "gl-matrix": "3.1.0", - "glsl-editor": "^1.0.0", "ikonate": "github:mikolajdobrucki/ikonate#a86b4107c6ec717e7877f880a930d1ccf0b59d89", "lodash-es": "^4.17.21", "nifti-reader-js": "^0.6.8", - "numcodecs": "^0.3.1", - "pako": "^2.1.0" + "numcodecs": "^0.3.2" }, "devDependencies": { + "@eslint/js": "^9.18.0", + "@iodigital/vite-plugin-msw": "^2.0.0", + "@playwright/browser-chromium": "^1.49.1", + "@rspack/cli": "^1.1.8", + "@rspack/core": "^1.1.8", "@types/codemirror": "5.60.15", "@types/gl-matrix": "^2.4.5", + "@types/http-server": "^0.12.4", + "@types/jsdom": "^21.1.7", "@types/lodash-es": "^4.17.12", - "@types/node": "^20.14.12", - "@types/pako": "^2.0.3", - "@types/yargs": "^17.0.32", - "@typescript-eslint/eslint-plugin": "^7.17.0", - "@typescript-eslint/parser": "^7.17.0", - "@vitest/browser": "^2.0.4", - "@vitest/ui": "^2.0.4", + "@types/node": "^22.10.7", + "@types/nunjucks": "^3.2.6", + "@types/s3rver": "^3.7.4", + "@types/yargs": "^17.0.33", + "@vitest/browser": "^3.0.2", + "@vitest/ui": "^3.0.2", + "@vitest/web-worker": "^3.0.2", + "cookie": "^1.0.2", "css-loader": "^7.1.2", - "esbuild": "^0.23.0", - "esbuild-loader": "^4.2.2", - "eslint": "^8.56.0", + "esbuild": "^0.24.2", + "eslint": "^9.18.0", "eslint-formatter-codeframe": "^7.32.1", - "eslint-import-resolver-typescript": "^3.6.1", - "eslint-interactive": "^10.8.0", - "eslint-plugin-import": "^2.29.1", - "eslint-webpack-plugin": "^4.0.1", - "fork-ts-checker-webpack-plugin": "^6.5.3", - "glob": "^11.0.0", - "html-webpack-plugin": "^5.6.0", - "mini-css-extract-plugin": "^2.9.0", - "prettier": "3.3.3", - "style-loader": "^4.0.0", - "svg-inline-loader": "^0.8.2", - "tsx": "^4.16.2", - "typescript": "^5.5.4", - "vitest": "^2.0.4", - "webdriverio": "^8.39.1", - "webpack": "^5.93.0", + "eslint-import-resolver-typescript": "^3.7.0", + "eslint-plugin-import": "^2.31.0", + "eslint-plugin-oxlint": "^0.15.7", + "eslint-rspack-plugin": "^4.2.1", + "express": "^4.21.2", + "glob": "^11.0.1", + "http-server": "^14.1.1", + "jsdom": "^26.0.0", + "msw": "^2.7.0", + "nunjucks": "^3.2.4", + "oxlint": "^0.15.7", + "playwright": "^1.49.1", + "prettier": "3.4.2", + "s3rver": "^3.7.1", + "ts-checker-rspack-plugin": "^1.1.1", + "tsx": "^4.19.2", + "typescript": "^5.7.3", + "typescript-eslint": "^8.20.0", + "vitest": "^3.0.2", "webpack-bundle-analyzer": "^4.10.2", - "webpack-cli": "^5.1.4", - "webpack-dev-server": "^5.0.4", - "webpack-merge": "^6.0.1" + "webpack-merge": "^6.0.1", + "yargs": "^17.7.2", + "yauzl": "^3.2.0" }, "engines": { - "node": ">=20.10 <21 || >=21.2" + "node": ">=22" } }, "../../../node_modules/@aashutoshrathi/word-wrap": { @@ -77,99 +87,6 @@ "node": ">=0.10.0" } }, - "../../../node_modules/@babel/code-frame": { - "version": "7.12.11", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/highlight": "^7.10.4" - } - }, - "../../../node_modules/@babel/helper-validator-identifier": { - "version": "7.22.20", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "../../../node_modules/@babel/highlight": { - "version": "7.23.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-validator-identifier": "^7.22.20", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "../../../node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "../../../node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "../../../node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "1.1.3" - } - }, - "../../../node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/@babel/highlight/node_modules/escape-string-regexp": { - "version": "1.0.5", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, - "../../../node_modules/@babel/highlight/node_modules/has-flag": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "../../../node_modules/@babel/highlight/node_modules/supports-color": { - "version": "5.5.0", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, "../../../node_modules/@discoveryjs/json-ext": { "version": "0.5.7", "dev": true, @@ -364,26 +281,12 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "../../../node_modules/@jest/types": { - "version": "29.6.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/schemas": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, "../../../node_modules/@jridgewell/gen-mapping": { "version": "0.3.5", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -397,6 +300,8 @@ "version": "3.1.2", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=6.0.0" } @@ -405,6 +310,8 @@ "version": "1.2.1", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=6.0.0" } @@ -413,6 +320,8 @@ "version": "0.3.5", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@jridgewell/gen-mapping": "^0.3.0", "@jridgewell/trace-mapping": "^0.3.9" @@ -427,16 +336,13 @@ "version": "0.3.25", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "../../../node_modules/@leichtgewicht/ip-codec": { - "version": "2.0.4", - "dev": true, - "license": "MIT" - }, "../../../node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "dev": true, @@ -490,6 +396,8 @@ "version": "2.0.1", "dev": true, "license": "Apache-2.0", + "optional": true, + "peer": true, "dependencies": { "debug": "4.3.4", "extract-zip": "2.0.1", @@ -539,6 +447,8 @@ "version": "5.6.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=14.16" }, @@ -550,6 +460,8 @@ "version": "5.0.1", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "defer-to-connect": "^2.0.1" }, @@ -561,8 +473,6 @@ "version": "1.1.2", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "engines": { "node": ">= 6" } @@ -570,24 +480,9 @@ "../../../node_modules/@tootallnate/quickjs-emscripten": { "version": "0.23.0", "dev": true, - "license": "MIT" - }, - "../../../node_modules/@types/body-parser": { - "version": "1.19.5", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/connect": "*", - "@types/node": "*" - } - }, - "../../../node_modules/@types/bonjour": { - "version": "3.5.13", - "dev": true, "license": "MIT", - "dependencies": { - "@types/node": "*" - } + "optional": true, + "peer": true }, "../../../node_modules/@types/codemirror": { "version": "5.60.15", @@ -597,27 +492,12 @@ "@types/tern": "*" } }, - "../../../node_modules/@types/connect": { - "version": "3.4.38", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "../../../node_modules/@types/connect-history-api-fallback": { - "version": "1.5.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/express-serve-static-core": "*", - "@types/node": "*" - } - }, "../../../node_modules/@types/eslint": { "version": "8.56.5", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@types/estree": "*", "@types/json-schema": "*" @@ -627,6 +507,8 @@ "version": "3.7.7", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@types/eslint": "*", "@types/estree": "*" @@ -637,81 +519,24 @@ "dev": true, "license": "MIT" }, - "../../../node_modules/@types/express": { - "version": "4.17.21", - "dev": true, - "license": "MIT", - "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.17.43", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*", - "@types/send": "*" - } - }, "../../../node_modules/@types/gl-matrix": { "version": "2.4.5", "dev": true, "license": "MIT" }, - "../../../node_modules/@types/html-minifier-terser": { - "version": "6.1.0", - "dev": true, - "license": "MIT" - }, "../../../node_modules/@types/http-cache-semantics": { "version": "4.0.4", "dev": true, - "license": "MIT" - }, - "../../../node_modules/@types/http-errors": { - "version": "2.0.4", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/@types/http-proxy": { - "version": "1.17.14", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "../../../node_modules/@types/istanbul-lib-coverage": { - "version": "2.0.6", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/@types/istanbul-lib-report": { - "version": "3.0.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-coverage": "*" - } - }, - "../../../node_modules/@types/istanbul-reports": { - "version": "3.0.4", - "dev": true, "license": "MIT", - "dependencies": { - "@types/istanbul-lib-report": "*" - } + "optional": true, + "peer": true }, "../../../node_modules/@types/json-schema": { "version": "7.0.15", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/@types/json5": { "version": "0.0.29", @@ -731,11 +556,6 @@ "@types/lodash": "*" } }, - "../../../node_modules/@types/mime": { - "version": "1.3.5", - "dev": true, - "license": "MIT" - }, "../../../node_modules/@types/node": { "version": "20.11.20", "dev": true, @@ -744,79 +564,6 @@ "undici-types": "~5.26.4" } }, - "../../../node_modules/@types/node-forge": { - "version": "1.3.11", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "../../../node_modules/@types/pako": { - "version": "2.0.3", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/@types/parse-json": { - "version": "4.0.2", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/@types/qs": { - "version": "6.9.12", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/@types/range-parser": { - "version": "1.2.7", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/@types/retry": { - "version": "0.12.2", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/@types/semver": { - "version": "7.5.7", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/@types/send": { - "version": "0.17.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/mime": "^1", - "@types/node": "*" - } - }, - "../../../node_modules/@types/serve-index": { - "version": "1.9.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/express": "*" - } - }, - "../../../node_modules/@types/serve-static": { - "version": "1.15.5", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/http-errors": "*", - "@types/mime": "*", - "@types/node": "*" - } - }, - "../../../node_modules/@types/sockjs": { - "version": "0.3.36", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, "../../../node_modules/@types/tern": { "version": "0.23.9", "dev": true, @@ -828,12 +575,16 @@ "../../../node_modules/@types/which": { "version": "2.0.2", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/@types/ws": { "version": "8.5.10", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@types/node": "*" } @@ -856,213 +607,32 @@ "dev": true, "license": "MIT", "optional": true, + "peer": true, "dependencies": { "@types/node": "*" } }, - "../../../node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.0.2", + "../../../node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "dev": true, + "license": "ISC" + }, + "../../../node_modules/@vitest/browser": { + "version": "1.3.1", "dev": true, "license": "MIT", "dependencies": { - "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "7.0.2", - "@typescript-eslint/type-utils": "7.0.2", - "@typescript-eslint/utils": "7.0.2", - "@typescript-eslint/visitor-keys": "7.0.2", - "debug": "^4.3.4", - "graphemer": "^1.4.0", - "ignore": "^5.2.4", - "natural-compare": "^1.4.0", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" + "@vitest/utils": "1.3.1", + "magic-string": "^0.30.5", + "sirv": "^2.0.4" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "url": "https://opencollective.com/vitest" }, "peerDependencies": { - "@typescript-eslint/parser": "^7.0.0", - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "../../../node_modules/@typescript-eslint/parser": { - "version": "7.0.2", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "@typescript-eslint/scope-manager": "7.0.2", - "@typescript-eslint/types": "7.0.2", - "@typescript-eslint/typescript-estree": "7.0.2", - "@typescript-eslint/visitor-keys": "7.0.2", - "debug": "^4.3.4" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "../../../node_modules/@typescript-eslint/scope-manager": { - "version": "7.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "7.0.2", - "@typescript-eslint/visitor-keys": "7.0.2" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "../../../node_modules/@typescript-eslint/type-utils": { - "version": "7.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/typescript-estree": "7.0.2", - "@typescript-eslint/utils": "7.0.2", - "debug": "^4.3.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "../../../node_modules/@typescript-eslint/types": { - "version": "7.0.2", - "dev": true, - "license": "MIT", - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "../../../node_modules/@typescript-eslint/typescript-estree": { - "version": "7.0.2", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "@typescript-eslint/types": "7.0.2", - "@typescript-eslint/visitor-keys": "7.0.2", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "9.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "../../../node_modules/@typescript-eslint/utils": { - "version": "7.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@types/json-schema": "^7.0.12", - "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "7.0.2", - "@typescript-eslint/types": "7.0.2", - "@typescript-eslint/typescript-estree": "7.0.2", - "semver": "^7.5.4" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - } - }, - "../../../node_modules/@typescript-eslint/visitor-keys": { - "version": "7.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "7.0.2", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "../../../node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "dev": true, - "license": "ISC" - }, - "../../../node_modules/@vitest/browser": { - "version": "1.3.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@vitest/utils": "1.3.1", - "magic-string": "^0.30.5", - "sirv": "^2.0.4" - }, - "funding": { - "url": "https://opencollective.com/vitest" - }, - "peerDependencies": { - "playwright": "*", - "vitest": "1.3.1", - "webdriverio": "*" + "playwright": "*", + "vitest": "1.3.1", + "webdriverio": "*" }, "peerDependenciesMeta": { "playwright": { @@ -1197,6 +767,8 @@ "version": "8.32.3", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@wdio/logger": "8.28.0", "@wdio/types": "8.32.2", @@ -1214,6 +786,8 @@ "version": "8.28.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "chalk": "^5.1.2", "loglevel": "^1.6.0", @@ -1228,6 +802,8 @@ "version": "6.0.1", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=12" }, @@ -1239,6 +815,8 @@ "version": "5.3.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": "^12.17.0 || ^14.13 || >=16.0.0" }, @@ -1250,6 +828,8 @@ "version": "7.1.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "ansi-regex": "^6.0.1" }, @@ -1263,12 +843,16 @@ "../../../node_modules/@wdio/protocols": { "version": "8.32.0", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/@wdio/repl": { "version": "8.24.12", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@types/node": "^20.1.0" }, @@ -1280,6 +864,8 @@ "version": "8.32.2", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@types/node": "^20.1.0" }, @@ -1291,6 +877,8 @@ "version": "8.32.3", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@puppeteer/browsers": "^1.6.0", "@wdio/logger": "8.28.0", @@ -1314,6 +902,8 @@ "version": "1.11.6", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@webassemblyjs/helper-numbers": "1.11.6", "@webassemblyjs/helper-wasm-bytecode": "1.11.6" @@ -1322,22 +912,30 @@ "../../../node_modules/@webassemblyjs/floating-point-hex-parser": { "version": "1.11.6", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/@webassemblyjs/helper-api-error": { "version": "1.11.6", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/@webassemblyjs/helper-buffer": { "version": "1.11.6", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/@webassemblyjs/helper-numbers": { "version": "1.11.6", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@webassemblyjs/floating-point-hex-parser": "1.11.6", "@webassemblyjs/helper-api-error": "1.11.6", @@ -1347,12 +945,16 @@ "../../../node_modules/@webassemblyjs/helper-wasm-bytecode": { "version": "1.11.6", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/@webassemblyjs/helper-wasm-section": { "version": "1.11.6", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@webassemblyjs/ast": "1.11.6", "@webassemblyjs/helper-buffer": "1.11.6", @@ -1364,6 +966,8 @@ "version": "1.11.6", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@xtuc/ieee754": "^1.2.0" } @@ -1372,6 +976,8 @@ "version": "1.11.6", "dev": true, "license": "Apache-2.0", + "optional": true, + "peer": true, "dependencies": { "@xtuc/long": "4.2.2" } @@ -1379,12 +985,16 @@ "../../../node_modules/@webassemblyjs/utf8": { "version": "1.11.6", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/@webassemblyjs/wasm-edit": { "version": "1.11.6", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@webassemblyjs/ast": "1.11.6", "@webassemblyjs/helper-buffer": "1.11.6", @@ -1400,6 +1010,8 @@ "version": "1.11.6", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@webassemblyjs/ast": "1.11.6", "@webassemblyjs/helper-wasm-bytecode": "1.11.6", @@ -1412,6 +1024,8 @@ "version": "1.11.6", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@webassemblyjs/ast": "1.11.6", "@webassemblyjs/helper-buffer": "1.11.6", @@ -1423,6 +1037,8 @@ "version": "1.11.6", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@webassemblyjs/ast": "1.11.6", "@webassemblyjs/helper-api-error": "1.11.6", @@ -1436,68 +1052,31 @@ "version": "1.11.6", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@webassemblyjs/ast": "1.11.6", "@xtuc/long": "4.2.2" } }, - "../../../node_modules/@webpack-cli/configtest": { - "version": "2.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14.15.0" - }, - "peerDependencies": { - "webpack": "5.x.x", - "webpack-cli": "5.x.x" - } - }, - "../../../node_modules/@webpack-cli/info": { - "version": "2.0.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14.15.0" - }, - "peerDependencies": { - "webpack": "5.x.x", - "webpack-cli": "5.x.x" - } - }, - "../../../node_modules/@webpack-cli/serve": { - "version": "2.0.5", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14.15.0" - }, - "peerDependencies": { - "webpack": "5.x.x", - "webpack-cli": "5.x.x" - }, - "peerDependenciesMeta": { - "webpack-dev-server": { - "optional": true - } - } - }, "../../../node_modules/@xtuc/ieee754": { "version": "1.2.0", "dev": true, - "license": "BSD-3-Clause" + "license": "BSD-3-Clause", + "optional": true, + "peer": true }, "../../../node_modules/@xtuc/long": { "version": "4.2.2", "dev": true, - "license": "Apache-2.0" + "license": "Apache-2.0", + "optional": true, + "peer": true }, "../../../node_modules/abab": { "version": "2.0.6", "dev": true, - "license": "BSD-3-Clause", - "optional": true, - "peer": true + "license": "BSD-3-Clause" }, "../../../node_modules/abbrev": { "version": "2.0.0", @@ -1506,18 +1085,6 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "../../../node_modules/accepts": { - "version": "1.3.8", - "dev": true, - "license": "MIT", - "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - }, - "engines": { - "node": ">= 0.6" - } - }, "../../../node_modules/acorn": { "version": "8.11.3", "dev": true, @@ -1533,8 +1100,6 @@ "version": "6.0.0", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "dependencies": { "acorn": "^7.1.1", "acorn-walk": "^7.1.1" @@ -1544,8 +1109,6 @@ "version": "7.4.1", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -1557,6 +1120,8 @@ "version": "1.9.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "peerDependencies": { "acorn": "^8" } @@ -1573,8 +1138,6 @@ "version": "7.2.0", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "engines": { "node": ">=0.4.0" } @@ -1583,8 +1146,6 @@ "version": "6.0.2", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "dependencies": { "debug": "4" }, @@ -1606,120 +1167,16 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "../../../node_modules/ajv-formats": { - "version": "2.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } - } - }, - "../../../node_modules/ajv-formats/node_modules/ajv": { - "version": "8.12.0", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "../../../node_modules/ajv-formats/node_modules/json-schema-traverse": { - "version": "1.0.0", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/ajv-keywords": { - "version": "3.5.2", + "../../../node_modules/ajv-keywords": { + "version": "3.5.2", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "peerDependencies": { "ajv": "^6.9.1" } }, - "../../../node_modules/ansi-align": { - "version": "3.0.1", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^4.1.0" - } - }, - "../../../node_modules/ansi-align/node_modules/emoji-regex": { - "version": "8.0.0", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/ansi-align/node_modules/string-width": { - "version": "4.2.3", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "../../../node_modules/ansi-colors": { - "version": "4.1.3", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "../../../node_modules/ansi-escapes": { - "version": "5.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "type-fest": "^1.0.2" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/ansi-escapes/node_modules/type-fest": { - "version": "1.4.0", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/ansi-html-community": { - "version": "0.0.8", - "dev": true, - "engines": [ - "node >= 0.8.0" - ], - "license": "Apache-2.0", - "bin": { - "ansi-html": "bin/ansi-html" - } - }, "../../../node_modules/ansi-regex": { "version": "5.0.1", "license": "MIT", @@ -1740,22 +1197,12 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "../../../node_modules/anymatch": { - "version": "3.1.3", - "dev": true, - "license": "ISC", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, "../../../node_modules/archiver": { "version": "6.0.1", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "archiver-utils": "^4.0.1", "async": "^3.2.4", @@ -1773,6 +1220,8 @@ "version": "4.0.1", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "glob": "^8.0.0", "graceful-fs": "^4.2.0", @@ -1789,6 +1238,8 @@ "version": "8.1.0", "dev": true, "license": "ISC", + "optional": true, + "peer": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -1807,6 +1258,8 @@ "version": "5.1.6", "dev": true, "license": "ISC", + "optional": true, + "peer": true, "dependencies": { "brace-expansion": "^2.0.1" }, @@ -1818,6 +1271,8 @@ "version": "3.6.2", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -1831,6 +1286,8 @@ "version": "3.6.2", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -1849,6 +1306,8 @@ "version": "5.3.0", "dev": true, "license": "Apache-2.0", + "optional": true, + "peer": true, "dependencies": { "dequal": "^2.0.3" } @@ -1872,11 +1331,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "../../../node_modules/array-flatten": { - "version": "1.1.1", - "dev": true, - "license": "MIT" - }, "../../../node_modules/array-includes": { "version": "3.1.7", "dev": true, @@ -1895,14 +1349,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "../../../node_modules/array-union": { - "version": "2.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "../../../node_modules/array.prototype.findlastindex": { "version": "1.2.3", "dev": true, @@ -2001,6 +1447,8 @@ "version": "0.13.4", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "tslib": "^2.0.1" }, @@ -2008,18 +1456,12 @@ "node": ">=4" } }, - "../../../node_modules/astral-regex": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "../../../node_modules/async": { "version": "3.2.5", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/async-limiter": { "version": "1.0.1", @@ -2029,14 +1471,6 @@ "version": "0.4.0", "license": "MIT" }, - "../../../node_modules/at-least-node": { - "version": "1.0.0", - "dev": true, - "license": "ISC", - "engines": { - "node": ">= 4.0.0" - } - }, "../../../node_modules/available-typed-arrays": { "version": "1.0.5", "dev": true, @@ -2062,7 +1496,9 @@ "../../../node_modules/b4a": { "version": "1.6.4", "dev": true, - "license": "ISC" + "license": "ISC", + "optional": true, + "peer": true }, "../../../node_modules/balanced-match": { "version": "1.0.2", @@ -2072,13 +1508,15 @@ "version": "2.2.0", "dev": true, "license": "Apache-2.0", - "optional": true + "optional": true, + "peer": true }, "../../../node_modules/bare-fs": { "version": "2.1.5", "dev": true, "license": "Apache-2.0", "optional": true, + "peer": true, "dependencies": { "bare-events": "^2.0.0", "bare-os": "^2.0.0", @@ -2090,13 +1528,15 @@ "version": "2.2.0", "dev": true, "license": "Apache-2.0", - "optional": true + "optional": true, + "peer": true }, "../../../node_modules/bare-path": { "version": "2.1.0", "dev": true, "license": "Apache-2.0", "optional": true, + "peer": true, "dependencies": { "bare-os": "^2.1.0" } @@ -2118,21 +1558,20 @@ "url": "https://feross.org/support" } ], - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/basic-ftp": { "version": "5.0.4", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=10.0.0" } }, - "../../../node_modules/batch": { - "version": "0.6.1", - "dev": true, - "license": "MIT" - }, "../../../node_modules/bcrypt-pbkdf": { "version": "1.0.2", "license": "BSD-3-Clause", @@ -2144,320 +1583,119 @@ "version": "1.6.52", "dev": true, "license": "Unlicense", + "optional": true, + "peer": true, "engines": { "node": ">=0.6" } }, - "../../../node_modules/big.js": { - "version": "5.2.2", - "dev": true, - "license": "MIT", - "engines": { - "node": "*" - } - }, "../../../node_modules/binary": { "version": "0.3.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "buffers": "~0.1.1", "chainsaw": "~0.1.0" } }, - "../../../node_modules/binary-extensions": { - "version": "2.2.0", + "../../../node_modules/bluebird": { + "version": "3.4.7", "dev": true, "license": "MIT", - "engines": { - "node": ">=8" - } + "optional": true, + "peer": true }, - "../../../node_modules/bl": { - "version": "5.1.0", - "dev": true, + "../../../node_modules/brace-expansion": { + "version": "2.0.1", "license": "MIT", "dependencies": { - "buffer": "^6.0.3", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" + "balanced-match": "^1.0.0" } }, - "../../../node_modules/bl/node_modules/readable-stream": { - "version": "3.6.2", + "../../../node_modules/braces": { + "version": "3.0.2", "dev": true, "license": "MIT", "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" + "fill-range": "^7.0.1" }, "engines": { - "node": ">= 6" + "node": ">=8" } }, - "../../../node_modules/bluebird": { - "version": "3.4.7", - "dev": true, - "license": "MIT" + "../../../node_modules/browser-process-hrtime": { + "version": "1.0.0", + "license": "BSD-2-Clause" }, - "../../../node_modules/body-parser": { - "version": "1.20.2", + "../../../node_modules/browserslist": { + "version": "4.23.0", "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", + "optional": true, + "peer": true, "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.11.0", - "raw-body": "2.5.2", - "type-is": "~1.6.18", - "unpipe": "1.0.0" + "caniuse-lite": "^1.0.30001587", + "electron-to-chromium": "^1.4.668", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.13" + }, + "bin": { + "browserslist": "cli.js" }, "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "../../../node_modules/body-parser/node_modules/bytes": { - "version": "3.1.2", + "../../../node_modules/buffer-crc32": { + "version": "0.2.13", "dev": true, "license": "MIT", "engines": { - "node": ">= 0.8" + "node": "*" } }, - "../../../node_modules/body-parser/node_modules/debug": { - "version": "2.6.9", + "../../../node_modules/buffer-from": { + "version": "1.1.2", "dev": true, "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "../../../node_modules/body-parser/node_modules/ms": { - "version": "2.0.0", - "dev": true, - "license": "MIT" + "optional": true, + "peer": true }, - "../../../node_modules/body-parser/node_modules/qs": { - "version": "6.11.0", + "../../../node_modules/buffer-indexof-polyfill": { + "version": "1.0.2", "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "side-channel": "^1.0.4" - }, + "license": "MIT", + "optional": true, + "peer": true, "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=0.10" } }, - "../../../node_modules/bonjour-service": { - "version": "1.2.1", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "multicast-dns": "^7.2.5" - } - }, - "../../../node_modules/boolbase": { - "version": "1.0.0", - "dev": true, - "license": "ISC" - }, - "../../../node_modules/boxen": { - "version": "7.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-align": "^3.0.1", - "camelcase": "^7.0.1", - "chalk": "^5.2.0", - "cli-boxes": "^3.0.0", - "string-width": "^5.1.2", - "type-fest": "^2.13.0", - "widest-line": "^4.0.1", - "wrap-ansi": "^8.1.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/boxen/node_modules/chalk": { - "version": "5.3.0", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "../../../node_modules/brace-expansion": { - "version": "2.0.1", - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "../../../node_modules/braces": { - "version": "3.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "../../../node_modules/brfs": { - "version": "1.6.1", - "license": "MIT", - "dependencies": { - "quote-stream": "^1.0.1", - "resolve": "^1.1.5", - "static-module": "^2.2.0", - "through2": "^2.0.0" - }, - "bin": { - "brfs": "bin/cmd.js" - } - }, - "../../../node_modules/brfs/node_modules/through2": { - "version": "2.0.5", - "license": "MIT", - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "../../../node_modules/browser-process-hrtime": { - "version": "1.0.0", - "license": "BSD-2-Clause" - }, - "../../../node_modules/browserslist": { - "version": "4.23.0", - "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": { - "caniuse-lite": "^1.0.30001587", - "electron-to-chromium": "^1.4.668", - "node-releases": "^2.0.14", - "update-browserslist-db": "^1.0.13" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "../../../node_modules/buffer": { - "version": "6.0.3", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, - "../../../node_modules/buffer-crc32": { - "version": "0.2.13", - "dev": true, - "license": "MIT", - "engines": { - "node": "*" - } - }, - "../../../node_modules/buffer-equal": { - "version": "0.0.1", - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, - "../../../node_modules/buffer-from": { - "version": "1.1.2", - "license": "MIT" - }, - "../../../node_modules/buffer-indexof-polyfill": { - "version": "1.0.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10" - } - }, - "../../../node_modules/buffers": { - "version": "0.1.1", + "../../../node_modules/buffers": { + "version": "0.1.1", "dev": true, + "optional": true, + "peer": true, "engines": { "node": ">=0.2.0" } }, - "../../../node_modules/bundle-name": { - "version": "4.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "run-applescript": "^7.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/bytes": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, "../../../node_modules/cac": { "version": "6.7.14", "dev": true, @@ -2470,6 +1708,8 @@ "version": "7.0.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=14.16" } @@ -2478,6 +1718,8 @@ "version": "10.2.14", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@types/http-cache-semantics": "^4.0.2", "get-stream": "^6.0.1", @@ -2495,6 +1737,8 @@ "version": "6.0.1", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=10" }, @@ -2523,26 +1767,6 @@ "node": ">=6" } }, - "../../../node_modules/camel-case": { - "version": "4.1.2", - "dev": true, - "license": "MIT", - "dependencies": { - "pascal-case": "^3.1.2", - "tslib": "^2.0.3" - } - }, - "../../../node_modules/camelcase": { - "version": "7.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "../../../node_modules/caniuse-lite": { "version": "1.0.30001596", "dev": true, @@ -2560,7 +1784,9 @@ "url": "https://github.com/sponsors/ai" } ], - "license": "CC-BY-4.0" + "license": "CC-BY-4.0", + "optional": true, + "peer": true }, "../../../node_modules/caseless": { "version": "0.12.0", @@ -2587,6 +1813,8 @@ "version": "0.1.0", "dev": true, "license": "MIT/X11", + "optional": true, + "peer": true, "dependencies": { "traverse": ">=0.3.0 <0.4" } @@ -2617,44 +1845,12 @@ "node": "*" } }, - "../../../node_modules/chokidar": { - "version": "3.6.0", - "dev": true, - "license": "MIT", - "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" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "../../../node_modules/chokidar/node_modules/glob-parent": { - "version": "5.1.2", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "../../../node_modules/chrome-trace-event": { "version": "1.0.3", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=6.0" } @@ -2663,6 +1859,8 @@ "version": "0.4.16", "dev": true, "license": "Apache-2.0", + "optional": true, + "peer": true, "dependencies": { "mitt": "3.0.0" }, @@ -2670,67 +1868,6 @@ "devtools-protocol": "*" } }, - "../../../node_modules/ci-info": { - "version": "3.9.0", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "../../../node_modules/clean-css": { - "version": "5.3.3", - "dev": true, - "license": "MIT", - "dependencies": { - "source-map": "~0.6.0" - }, - "engines": { - "node": ">= 10.0" - } - }, - "../../../node_modules/cli-boxes": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/cli-cursor": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "restore-cursor": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/cli-spinners": { - "version": "2.9.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "../../../node_modules/cliui": { "version": "8.0.1", "dev": true, @@ -2817,11 +1954,6 @@ "version": "1.1.4", "license": "MIT" }, - "../../../node_modules/colorette": { - "version": "2.0.20", - "dev": true, - "license": "MIT" - }, "../../../node_modules/combined-stream": { "version": "1.0.8", "license": "MIT", @@ -2832,28 +1964,22 @@ "node": ">= 0.8" } }, - "../../../node_modules/comlink": { - "version": "4.4.1", - "dev": true, - "license": "Apache-2.0" - }, "../../../node_modules/commander": { "version": "9.5.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": "^12.20.0 || >=14" } }, - "../../../node_modules/common-path-prefix": { - "version": "3.0.0", - "dev": true, - "license": "ISC" - }, "../../../node_modules/compress-commons": { "version": "5.0.1", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "crc-32": "^1.2.0", "crc32-stream": "^5.0.0", @@ -2867,80 +1993,23 @@ "../../../node_modules/compress-commons/node_modules/readable-stream": { "version": "3.6.2", "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "../../../node_modules/compressible": { - "version": "2.0.18", - "dev": true, - "license": "MIT", - "dependencies": { - "mime-db": ">= 1.43.0 < 2" - }, - "engines": { - "node": ">= 0.6" - } - }, - "../../../node_modules/compression": { - "version": "1.7.4", - "dev": true, - "license": "MIT", - "dependencies": { - "accepts": "~1.3.5", - "bytes": "3.0.0", - "compressible": "~2.0.16", - "debug": "2.6.9", - "on-headers": "~1.0.2", - "safe-buffer": "5.1.2", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "../../../node_modules/compression/node_modules/debug": { - "version": "2.6.9", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "../../../node_modules/compression/node_modules/ms": { - "version": "2.0.0", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/compression/node_modules/safe-buffer": { - "version": "5.1.2", - "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } }, "../../../node_modules/concat-map": { "version": "0.0.1", "dev": true, "license": "MIT" }, - "../../../node_modules/concat-stream": { - "version": "1.6.2", - "engines": [ - "node >= 0.8" - ], - "license": "MIT", - "dependencies": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, "../../../node_modules/condense-newlines": { "version": "0.2.1", "license": "MIT", @@ -2965,73 +2034,15 @@ "version": "1.3.8", "license": "ISC" }, - "../../../node_modules/connect-history-api-fallback": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8" - } - }, - "../../../node_modules/content-disposition": { - "version": "0.5.4", - "dev": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "5.2.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "../../../node_modules/content-type": { - "version": "1.0.5", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "../../../node_modules/convert-source-map": { - "version": "1.9.0", - "license": "MIT" - }, - "../../../node_modules/cookie": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "../../../node_modules/cookie-signature": { - "version": "1.0.6", - "dev": true, - "license": "MIT" - }, "../../../node_modules/core-util-is": { "version": "1.0.3", - "license": "MIT" - }, - "../../../node_modules/cosmiconfig": { - "version": "6.0.0", "dev": true, "license": "MIT", - "dependencies": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.1.0", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.7.2" - }, - "engines": { - "node": ">=8" - } + "optional": true, + "peer": true }, "../../../node_modules/crc-32": { "version": "1.2.2", - "dev": true, "license": "Apache-2.0", "bin": { "crc32": "bin/crc32.njs" @@ -3044,6 +2055,8 @@ "version": "5.0.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "crc-32": "^1.2.0", "readable-stream": "^3.4.0" @@ -3056,6 +2069,8 @@ "version": "3.6.2", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -3069,6 +2084,8 @@ "version": "4.0.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "node-fetch": "^2.6.12" } @@ -3077,6 +2094,8 @@ "version": "2.7.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "whatwg-url": "^5.0.0" }, @@ -3095,17 +2114,23 @@ "../../../node_modules/cross-fetch/node_modules/tr46": { "version": "0.0.3", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/cross-fetch/node_modules/webidl-conversions": { "version": "3.0.1", "dev": true, - "license": "BSD-2-Clause" + "license": "BSD-2-Clause", + "optional": true, + "peer": true }, "../../../node_modules/cross-fetch/node_modules/whatwg-url": { "version": "5.0.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" @@ -3157,39 +2182,17 @@ } } }, - "../../../node_modules/css-select": { - "version": "4.3.0", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^6.0.1", - "domhandler": "^4.3.1", - "domutils": "^2.8.0", - "nth-check": "^2.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, "../../../node_modules/css-shorthand-properties": { "version": "1.1.1", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "../../../node_modules/css-value": { "version": "0.0.1", - "dev": true - }, - "../../../node_modules/css-what": { - "version": "6.1.0", "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">= 6" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } + "optional": true, + "peer": true }, "../../../node_modules/cssesc": { "version": "3.0.0", @@ -3205,16 +2208,12 @@ "../../../node_modules/cssom": { "version": "0.5.0", "dev": true, - "license": "MIT", - "optional": true, - "peer": true + "license": "MIT" }, "../../../node_modules/cssstyle": { "version": "2.3.0", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "dependencies": { "cssom": "~0.3.6" }, @@ -3225,9 +2224,7 @@ "../../../node_modules/cssstyle/node_modules/cssom": { "version": "0.3.8", "dev": true, - "license": "MIT", - "optional": true, - "peer": true + "license": "MIT" }, "../../../node_modules/dashdash": { "version": "1.14.1", @@ -3243,6 +2240,8 @@ "version": "4.0.1", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">= 12" } @@ -3251,8 +2250,6 @@ "version": "3.0.2", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "dependencies": { "abab": "^2.0.6", "whatwg-mimetype": "^3.0.0", @@ -3266,8 +2263,6 @@ "version": "3.0.0", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "dependencies": { "punycode": "^2.1.1" }, @@ -3279,8 +2274,6 @@ "version": "7.0.0", "dev": true, "license": "BSD-2-Clause", - "optional": true, - "peer": true, "engines": { "node": ">=12" } @@ -3289,8 +2282,6 @@ "version": "3.0.0", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "engines": { "node": ">=12" } @@ -3298,237 +2289,114 @@ "../../../node_modules/data-urls/node_modules/whatwg-url": { "version": "11.0.0", "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "tr46": "^3.0.0", - "webidl-conversions": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "../../../node_modules/debounce": { - "version": "1.2.1", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/debug": { - "version": "4.3.4", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "../../../node_modules/decamelize": { - "version": "6.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/decimal.js": { - "version": "10.4.3", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true - }, - "../../../node_modules/decompress-response": { - "version": "6.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "mimic-response": "^3.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/decompress-response/node_modules/mimic-response": { - "version": "3.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/deep-eql": { - "version": "4.1.3", - "dev": true, - "license": "MIT", - "dependencies": { - "type-detect": "^4.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "../../../node_modules/deep-is": { - "version": "0.1.4", - "license": "MIT" - }, - "../../../node_modules/deepmerge": { - "version": "4.3.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "../../../node_modules/deepmerge-ts": { - "version": "5.1.0", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=16.0.0" - } - }, - "../../../node_modules/default-browser": { - "version": "5.2.1", - "dev": true, - "license": "MIT", - "dependencies": { - "bundle-name": "^4.1.0", - "default-browser-id": "^5.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/default-browser-id": { - "version": "5.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/default-gateway": { - "version": "6.0.3", - "dev": true, - "license": "BSD-2-Clause", + "license": "MIT", "dependencies": { - "execa": "^5.0.0" + "tr46": "^3.0.0", + "webidl-conversions": "^7.0.0" }, "engines": { - "node": ">= 10" + "node": ">=12" } }, - "../../../node_modules/default-gateway/node_modules/execa": { - "version": "5.1.1", + "../../../node_modules/debounce": { + "version": "1.2.1", + "dev": true, + "license": "MIT" + }, + "../../../node_modules/debug": { + "version": "4.3.4", "dev": true, "license": "MIT", "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" + "ms": "2.1.2" }, "engines": { - "node": ">=10" + "node": ">=6.0" }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "../../../node_modules/default-gateway/node_modules/get-stream": { - "version": "6.0.1", + "../../../node_modules/decamelize": { + "version": "6.0.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { - "node": ">=10" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "../../../node_modules/default-gateway/node_modules/human-signals": { - "version": "2.1.0", + "../../../node_modules/decimal.js": { + "version": "10.4.3", "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=10.17.0" - } + "license": "MIT" }, - "../../../node_modules/default-gateway/node_modules/is-stream": { - "version": "2.0.1", + "../../../node_modules/decompress-response": { + "version": "6.0.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "mimic-response": "^3.1.0" + }, "engines": { - "node": ">=8" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "../../../node_modules/default-gateway/node_modules/signal-exit": { - "version": "3.0.7", - "dev": true, - "license": "ISC" - }, - "../../../node_modules/default-gateway/node_modules/strip-final-newline": { - "version": "2.0.0", + "../../../node_modules/decompress-response/node_modules/mimic-response": { + "version": "3.1.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { - "node": ">=6" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "../../../node_modules/defaults": { - "version": "1.0.4", + "../../../node_modules/deep-eql": { + "version": "4.1.3", "dev": true, "license": "MIT", "dependencies": { - "clone": "^1.0.2" + "type-detect": "^4.0.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">=6" } }, - "../../../node_modules/defaults/node_modules/clone": { - "version": "1.0.4", + "../../../node_modules/deep-is": { + "version": "0.1.4", + "license": "MIT" + }, + "../../../node_modules/deepmerge-ts": { + "version": "5.1.0", "dev": true, - "license": "MIT", + "license": "BSD-3-Clause", + "optional": true, + "peer": true, "engines": { - "node": ">=0.8" + "node": ">=16.0.0" } }, "../../../node_modules/defer-to-connect": { "version": "2.0.1", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=10" } @@ -3546,17 +2414,6 @@ "node": ">= 0.4" } }, - "../../../node_modules/define-lazy-prop": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "../../../node_modules/define-properties": { "version": "1.2.1", "dev": true, @@ -3577,6 +2434,8 @@ "version": "5.0.1", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "ast-types": "^0.13.4", "escodegen": "^2.1.0", @@ -3593,31 +2452,16 @@ "node": ">=0.4.0" } }, - "../../../node_modules/depd": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, "../../../node_modules/dequal": { "version": "2.0.3", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=6" } }, - "../../../node_modules/destroy": { - "version": "1.2.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, "../../../node_modules/detect-libc": { "version": "1.0.3", "dev": true, @@ -3631,15 +2475,12 @@ "node": ">=0.10" } }, - "../../../node_modules/detect-node": { - "version": "2.1.0", - "dev": true, - "license": "MIT" - }, "../../../node_modules/devtools-protocol": { "version": "0.0.1262051", "dev": true, - "license": "BSD-3-Clause" + "license": "BSD-3-Clause", + "optional": true, + "peer": true }, "../../../node_modules/diff-sequences": { "version": "29.6.3", @@ -3649,28 +2490,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "../../../node_modules/dir-glob": { - "version": "3.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "../../../node_modules/dns-packet": { - "version": "5.6.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@leichtgewicht/ip-codec": "^2.0.1" - }, - "engines": { - "node": ">=6" - } - }, "../../../node_modules/doctrine": { "version": "3.0.0", "dev": true, @@ -3682,44 +2501,10 @@ "node": ">=6.0.0" } }, - "../../../node_modules/dom-converter": { - "version": "0.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "utila": "~0.4" - } - }, - "../../../node_modules/dom-serializer": { - "version": "1.4.1", - "dev": true, - "license": "MIT", - "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.0", - "entities": "^2.0.0" - }, - "funding": { - "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" - } - }, - "../../../node_modules/domelementtype": { - "version": "2.3.0", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "license": "BSD-2-Clause" - }, "../../../node_modules/domexception": { "version": "2.0.1", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "dependencies": { "webidl-conversions": "^5.0.0" }, @@ -3731,48 +2516,10 @@ "version": "5.0.0", "dev": true, "license": "BSD-2-Clause", - "optional": true, - "peer": true, "engines": { "node": ">=8" } }, - "../../../node_modules/domhandler": { - "version": "4.3.1", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "domelementtype": "^2.2.0" - }, - "engines": { - "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" - } - }, - "../../../node_modules/domutils": { - "version": "2.8.0", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "dom-serializer": "^1.0.1", - "domelementtype": "^2.2.0", - "domhandler": "^4.2.0" - }, - "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" - } - }, - "../../../node_modules/dot-case": { - "version": "3.0.4", - "dev": true, - "license": "MIT", - "dependencies": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, "../../../node_modules/duplexer": { "version": "0.1.2", "dev": true, @@ -3780,7 +2527,10 @@ }, "../../../node_modules/duplexer2": { "version": "0.1.4", + "dev": true, "license": "BSD-3-Clause", + "optional": true, + "peer": true, "dependencies": { "readable-stream": "^2.0.2" } @@ -3801,6 +2551,8 @@ "version": "3.0.5", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@types/which": "^2.0.1", "which": "^2.0.2" @@ -3817,6 +2569,8 @@ "dev": true, "hasInstallScript": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@wdio/logger": "^8.28.0", "decamelize": "^6.0.0", @@ -3833,6 +2587,8 @@ "version": "3.1.1", "dev": true, "license": "ISC", + "optional": true, + "peer": true, "engines": { "node": ">=16" } @@ -3841,6 +2597,8 @@ "version": "4.0.0", "dev": true, "license": "ISC", + "optional": true, + "peer": true, "dependencies": { "isexe": "^3.1.1" }, @@ -3887,44 +2645,23 @@ "url": "https://github.com/sponsors/isaacs" } }, - "../../../node_modules/ee-first": { - "version": "1.1.1", - "dev": true, - "license": "MIT" - }, "../../../node_modules/electron-to-chromium": { "version": "1.4.699", "dev": true, - "license": "ISC" - }, - "../../../node_modules/element-size": { - "version": "1.1.1", - "license": "MIT" + "license": "ISC", + "optional": true, + "peer": true }, "../../../node_modules/emoji-regex": { "version": "9.2.2", "license": "MIT" }, - "../../../node_modules/emojis-list": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "../../../node_modules/encodeurl": { - "version": "1.0.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, "../../../node_modules/end-of-stream": { "version": "1.4.4", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "once": "^1.4.0" } @@ -3941,45 +2678,6 @@ "node": ">=10.13.0" } }, - "../../../node_modules/enquirer": { - "version": "2.4.1", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-colors": "^4.1.1", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "../../../node_modules/entities": { - "version": "2.2.0", - "dev": true, - "license": "BSD-2-Clause", - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "../../../node_modules/envinfo": { - "version": "7.11.1", - "dev": true, - "license": "MIT", - "bin": { - "envinfo": "dist/cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "../../../node_modules/error-ex": { - "version": "1.3.2", - "dev": true, - "license": "MIT", - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, "../../../node_modules/es-abstract": { "version": "1.22.3", "dev": true, @@ -4035,7 +2733,9 @@ "../../../node_modules/es-module-lexer": { "version": "1.4.1", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/es-set-tostringtag": { "version": "2.0.2", @@ -4111,23 +2811,6 @@ "@esbuild/win32-x64": "0.20.1" } }, - "../../../node_modules/esbuild-loader": { - "version": "4.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "esbuild": "^0.20.0", - "get-tsconfig": "^4.7.0", - "loader-utils": "^2.0.4", - "webpack-sources": "^1.4.3" - }, - "funding": { - "url": "https://github.com/privatenumber/esbuild-loader?sponsor=1" - }, - "peerDependencies": { - "webpack": "^4.40.0 || ^5.0.0" - } - }, "../../../node_modules/escalade": { "version": "3.1.1", "dev": true, @@ -4136,11 +2819,6 @@ "node": ">=6" } }, - "../../../node_modules/escape-html": { - "version": "1.0.3", - "dev": true, - "license": "MIT" - }, "../../../node_modules/escape-string-regexp": { "version": "4.0.0", "dev": true, @@ -4154,6 +2832,7 @@ }, "../../../node_modules/escodegen": { "version": "2.1.0", + "dev": true, "license": "BSD-2-Clause", "dependencies": { "esprima": "^4.0.1", @@ -4225,18 +2904,6 @@ "url": "https://opencollective.com/eslint" } }, - "../../../node_modules/eslint-formatter-codeframe": { - "version": "7.32.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "7.12.11", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, "../../../node_modules/eslint-import-resolver-node": { "version": "0.3.9", "dev": true, @@ -4279,71 +2946,6 @@ "eslint-plugin-import": "*" } }, - "../../../node_modules/eslint-interactive": { - "version": "10.8.0", - "dev": true, - "license": "MIT", - "dependencies": { - "boxen": "^7.0.2", - "chalk": "^5.0.1", - "comlink": "^4.3.1", - "enquirer": "^2.3.6", - "eslint-formatter-codeframe": "^7.32.1", - "estraverse": "^5.3.0", - "find-cache-dir": "^4.0.0", - "is-installed-globally": "^0.4.0", - "ora": "^6.1.2", - "strip-ansi": "^7.0.1", - "table": "^6.8.1", - "terminal-link": "^3.0.0", - "yargs": "^17.5.1" - }, - "bin": { - "eslint-interactive": "bin/eslint-interactive.js" - }, - "engines": { - "node": "^14.13.1 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" - } - }, - "../../../node_modules/eslint-interactive/node_modules/ansi-regex": { - "version": "6.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "../../../node_modules/eslint-interactive/node_modules/chalk": { - "version": "5.3.0", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "../../../node_modules/eslint-interactive/node_modules/strip-ansi": { - "version": "7.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, "../../../node_modules/eslint-module-utils": { "version": "2.8.0", "dev": true, @@ -4471,106 +3073,6 @@ "url": "https://opencollective.com/eslint" } }, - "../../../node_modules/eslint-webpack-plugin": { - "version": "4.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/eslint": "^8.37.0", - "jest-worker": "^29.5.0", - "micromatch": "^4.0.5", - "normalize-path": "^3.0.0", - "schema-utils": "^4.0.0" - }, - "engines": { - "node": ">= 14.15.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "eslint": "^8.0.0", - "webpack": "^5.0.0" - } - }, - "../../../node_modules/eslint-webpack-plugin/node_modules/ajv": { - "version": "8.12.0", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "../../../node_modules/eslint-webpack-plugin/node_modules/ajv-keywords": { - "version": "5.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, - "../../../node_modules/eslint-webpack-plugin/node_modules/jest-worker": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*", - "jest-util": "^29.7.0", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "../../../node_modules/eslint-webpack-plugin/node_modules/json-schema-traverse": { - "version": "1.0.0", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/eslint-webpack-plugin/node_modules/schema-utils": { - "version": "4.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.9.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.1.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "../../../node_modules/eslint-webpack-plugin/node_modules/supports-color": { - "version": "8.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, "../../../node_modules/eslint/node_modules/brace-expansion": { "version": "1.1.11", "dev": true, @@ -4642,6 +3144,7 @@ }, "../../../node_modules/estraverse": { "version": "5.3.0", + "dev": true, "license": "BSD-2-Clause", "engines": { "node": ">=4.0" @@ -4654,26 +3157,6 @@ "node": ">=0.10.0" } }, - "../../../node_modules/etag": { - "version": "1.8.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "../../../node_modules/eventemitter3": { - "version": "4.0.7", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/events": { - "version": "1.1.1", - "license": "MIT", - "engines": { - "node": ">=0.4.x" - } - }, "../../../node_modules/execa": { "version": "8.0.1", "dev": true, @@ -4746,75 +3229,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "../../../node_modules/express": { - "version": "4.19.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", - "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", - "dev": true, - "dependencies": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.2", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.6.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.2.0", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.7", - "qs": "6.11.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "../../../node_modules/express/node_modules/debug": { - "version": "2.6.9", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "../../../node_modules/express/node_modules/ms": { - "version": "2.0.0", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/express/node_modules/qs": { - "version": "6.11.0", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "../../../node_modules/extend": { "version": "3.0.2", "license": "MIT" @@ -4833,6 +3247,8 @@ "version": "2.0.1", "dev": true, "license": "BSD-2-Clause", + "optional": true, + "peer": true, "dependencies": { "debug": "^4.1.1", "get-stream": "^5.1.0", @@ -4852,6 +3268,8 @@ "version": "5.2.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "pump": "^3.0.0" }, @@ -4869,27 +3287,6 @@ ], "license": "MIT" }, - "../../../node_modules/falafel": { - "version": "2.2.5", - "license": "MIT", - "dependencies": { - "acorn": "^7.1.1", - "isarray": "^2.0.1" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "../../../node_modules/falafel/node_modules/acorn": { - "version": "7.4.1", - "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, "../../../node_modules/fast-deep-equal": { "version": "3.1.3", "license": "MIT" @@ -4897,7 +3294,9 @@ "../../../node_modules/fast-fifo": { "version": "1.3.2", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/fast-glob": { "version": "3.3.2", @@ -4933,14 +3332,6 @@ "version": "2.0.6", "license": "MIT" }, - "../../../node_modules/fastest-levenshtein": { - "version": "1.0.16", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4.9.1" - } - }, "../../../node_modules/fastq": { "version": "1.17.0", "dev": true, @@ -4949,17 +3340,6 @@ "reusify": "^1.0.4" } }, - "../../../node_modules/faye-websocket": { - "version": "0.11.4", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "websocket-driver": ">=0.5.1" - }, - "engines": { - "node": ">=0.8.0" - } - }, "../../../node_modules/fd-slicer": { "version": "1.1.0", "dev": true, @@ -4982,6 +3362,8 @@ } ], "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "node-domexception": "^1.0.0", "web-streams-polyfill": "^3.0.3" @@ -5000,65 +3382,20 @@ "license": "MIT", "dependencies": { "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "../../../node_modules/fill-range": { - "version": "7.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "../../../node_modules/finalhandler": { - "version": "1.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "../../../node_modules/finalhandler/node_modules/debug": { - "version": "2.6.9", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.0.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" } }, - "../../../node_modules/finalhandler/node_modules/ms": { - "version": "2.0.0", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/find-cache-dir": { - "version": "4.0.0", + "../../../node_modules/fill-range": { + "version": "7.0.1", "dev": true, "license": "MIT", "dependencies": { - "common-path-prefix": "^3.0.0", - "pkg-dir": "^7.0.0" + "to-regex-range": "^5.0.1" }, "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, "../../../node_modules/find-up": { @@ -5102,26 +3439,6 @@ "dev": true, "license": "ISC" }, - "../../../node_modules/follow-redirects": { - "version": "1.15.6", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", - "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, "../../../node_modules/for-each": { "version": "0.3.3", "dev": true, @@ -5151,223 +3468,10 @@ "node": "*" } }, - "../../../node_modules/fork-ts-checker-webpack-plugin": { - "version": "6.5.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.8.3", - "@types/json-schema": "^7.0.5", - "chalk": "^4.1.0", - "chokidar": "^3.4.2", - "cosmiconfig": "^6.0.0", - "deepmerge": "^4.2.2", - "fs-extra": "^9.0.0", - "glob": "^7.1.6", - "memfs": "^3.1.2", - "minimatch": "^3.0.4", - "schema-utils": "2.7.0", - "semver": "^7.3.2", - "tapable": "^1.0.0" - }, - "engines": { - "node": ">=10", - "yarn": ">=1.0.0" - }, - "peerDependencies": { - "eslint": ">= 6", - "typescript": ">= 2.7", - "vue-template-compiler": "*", - "webpack": ">= 4" - }, - "peerDependenciesMeta": { - "eslint": { - "optional": true - }, - "vue-template-compiler": { - "optional": true - } - } - }, - "../../../node_modules/fork-ts-checker-webpack-plugin/node_modules/@babel/code-frame": { - "version": "7.23.5", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/highlight": "^7.23.4", - "chalk": "^2.4.2" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "../../../node_modules/fork-ts-checker-webpack-plugin/node_modules/@babel/code-frame/node_modules/chalk": { - "version": "2.4.2", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "../../../node_modules/fork-ts-checker-webpack-plugin/node_modules/ansi-styles": { - "version": "3.2.1", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "../../../node_modules/fork-ts-checker-webpack-plugin/node_modules/brace-expansion": { - "version": "1.1.11", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "../../../node_modules/fork-ts-checker-webpack-plugin/node_modules/color-convert": { - "version": "1.9.3", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "1.1.3" - } - }, - "../../../node_modules/fork-ts-checker-webpack-plugin/node_modules/color-name": { - "version": "1.1.3", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/fork-ts-checker-webpack-plugin/node_modules/escape-string-regexp": { - "version": "1.0.5", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, - "../../../node_modules/fork-ts-checker-webpack-plugin/node_modules/fs-extra": { - "version": "9.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "../../../node_modules/fork-ts-checker-webpack-plugin/node_modules/glob": { - "version": "7.2.3", - "dev": true, - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "../../../node_modules/fork-ts-checker-webpack-plugin/node_modules/has-flag": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "../../../node_modules/fork-ts-checker-webpack-plugin/node_modules/memfs": { - "version": "3.5.3", - "dev": true, - "license": "Unlicense", - "dependencies": { - "fs-monkey": "^1.0.4" - }, - "engines": { - "node": ">= 4.0.0" - } - }, - "../../../node_modules/fork-ts-checker-webpack-plugin/node_modules/minimatch": { - "version": "3.1.2", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "../../../node_modules/fork-ts-checker-webpack-plugin/node_modules/schema-utils": { - "version": "2.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/json-schema": "^7.0.4", - "ajv": "^6.12.2", - "ajv-keywords": "^3.4.1" - }, - "engines": { - "node": ">= 8.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "../../../node_modules/fork-ts-checker-webpack-plugin/node_modules/supports-color": { - "version": "5.5.0", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "../../../node_modules/fork-ts-checker-webpack-plugin/node_modules/tapable": { - "version": "1.1.3", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "../../../node_modules/fork-ts-checker-webpack-plugin/node_modules/universalify": { - "version": "2.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 10.0.0" - } - }, "../../../node_modules/form-data": { "version": "4.0.0", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -5381,6 +3485,8 @@ "version": "2.1.4", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">= 14.17" } @@ -5389,6 +3495,8 @@ "version": "4.0.10", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "fetch-blob": "^3.1.2" }, @@ -5396,26 +3504,12 @@ "node": ">=12.20.0" } }, - "../../../node_modules/forwarded": { - "version": "0.2.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "../../../node_modules/fresh": { - "version": "0.5.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, "../../../node_modules/fs-extra": { "version": "11.2.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", @@ -5429,15 +3523,12 @@ "version": "2.0.1", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">= 10.0.0" } }, - "../../../node_modules/fs-monkey": { - "version": "1.0.5", - "dev": true, - "license": "Unlicense" - }, "../../../node_modules/fs.realpath": { "version": "1.0.0", "dev": true, @@ -5447,6 +3538,8 @@ "version": "1.0.12", "dev": true, "license": "ISC", + "optional": true, + "peer": true, "dependencies": { "graceful-fs": "^4.1.2", "inherits": "~2.0.0", @@ -5461,6 +3554,8 @@ "version": "1.1.11", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -5470,6 +3565,8 @@ "version": "7.2.3", "dev": true, "license": "ISC", + "optional": true, + "peer": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -5489,6 +3586,8 @@ "version": "3.1.2", "dev": true, "license": "ISC", + "optional": true, + "peer": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -5500,6 +3599,8 @@ "version": "2.7.1", "dev": true, "license": "ISC", + "optional": true, + "peer": true, "dependencies": { "glob": "^7.1.3" }, @@ -5509,6 +3610,7 @@ }, "../../../node_modules/function-bind": { "version": "1.1.2", + "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" @@ -5544,6 +3646,8 @@ "dev": true, "hasInstallScript": true, "license": "MPL-2.0", + "optional": true, + "peer": true, "dependencies": { "@wdio/logger": "^8.28.0", "decamelize": "^6.0.0", @@ -5565,6 +3669,8 @@ "version": "7.1.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "debug": "^4.3.4" }, @@ -5576,6 +3682,8 @@ "version": "7.0.2", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "agent-base": "^7.1.0", "debug": "^4.3.4" @@ -5588,6 +3696,8 @@ "version": "7.0.4", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "agent-base": "^7.0.2", "debug": "4" @@ -5600,6 +3710,8 @@ "version": "3.1.1", "dev": true, "license": "ISC", + "optional": true, + "peer": true, "engines": { "node": ">=16" } @@ -5608,6 +3720,8 @@ "version": "4.0.0", "dev": true, "license": "ISC", + "optional": true, + "peer": true, "dependencies": { "isexe": "^3.1.1" }, @@ -5652,6 +3766,8 @@ "version": "7.0.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=16" }, @@ -5700,6 +3816,8 @@ "version": "6.0.3", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "basic-ftp": "^5.0.2", "data-uri-to-buffer": "^6.0.2", @@ -5714,6 +3832,8 @@ "version": "6.0.2", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">= 14" } @@ -5757,28 +3877,16 @@ "is-glob": "^4.0.3" }, "engines": { - "node": ">=10.13.0" - } - }, - "../../../node_modules/glob-to-regexp": { - "version": "0.4.1", - "dev": true, - "license": "BSD-2-Clause" - }, - "../../../node_modules/global-dirs": { - "version": "3.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "ini": "2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=10.13.0" } }, + "../../../node_modules/glob-to-regexp": { + "version": "0.4.1", + "dev": true, + "license": "BSD-2-Clause", + "optional": true, + "peer": true + }, "../../../node_modules/globals": { "version": "13.24.0", "dev": true, @@ -5818,42 +3926,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "../../../node_modules/globby": { - "version": "11.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/glsl-editor": { - "version": "1.0.0", - "license": "MIT", - "dependencies": { - "brfs": "^1.2.0", - "codemirror": "^4.5.0", - "element-size": "^1.1.1", - "events": "^1.0.2", - "inherits": "^2.0.1", - "insert-css": "^0.2.0", - "through2": "^0.6.1", - "xtend": "^4.0.0" - } - }, - "../../../node_modules/glsl-editor/node_modules/codemirror": { - "version": "4.13.0" - }, "../../../node_modules/gopd": { "version": "1.0.1", "dev": true, @@ -5869,6 +3941,8 @@ "version": "12.6.1", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@sindresorhus/is": "^5.2.0", "@szmarczak/http-timer": "^5.0.1", @@ -5893,6 +3967,8 @@ "version": "6.0.1", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=10" }, @@ -5908,7 +3984,9 @@ "../../../node_modules/grapheme-splitter": { "version": "1.0.4", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/graphemer": { "version": "1.4.0", @@ -5929,11 +4007,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "../../../node_modules/handle-thing": { - "version": "2.0.1", - "dev": true, - "license": "MIT" - }, "../../../node_modules/har-schema": { "version": "2.0.0", "license": "ISC", @@ -5952,13 +4025,6 @@ "node": ">=6" } }, - "../../../node_modules/has": { - "version": "1.0.4", - "license": "MIT", - "engines": { - "node": ">= 0.4.0" - } - }, "../../../node_modules/has-bigints": { "version": "1.0.2", "dev": true, @@ -6024,6 +4090,7 @@ }, "../../../node_modules/hasown": { "version": "2.0.0", + "dev": true, "license": "MIT", "dependencies": { "function-bind": "^1.1.2" @@ -6032,31 +4099,10 @@ "node": ">= 0.4" } }, - "../../../node_modules/he": { - "version": "1.2.0", - "dev": true, - "license": "MIT", - "bin": { - "he": "bin/he" - } - }, - "../../../node_modules/hpack.js": { - "version": "2.1.6", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.1", - "obuf": "^1.0.0", - "readable-stream": "^2.0.1", - "wbuf": "^1.1.0" - } - }, "../../../node_modules/html-encoding-sniffer": { "version": "2.0.1", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "dependencies": { "whatwg-encoding": "^1.0.5" }, @@ -6064,152 +4110,22 @@ "node": ">=10" } }, - "../../../node_modules/html-entities": { - "version": "2.5.2", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/mdevils" - }, - { - "type": "patreon", - "url": "https://patreon.com/mdevils" - } - ], - "license": "MIT" - }, "../../../node_modules/html-escaper": { "version": "2.0.2", "dev": true, "license": "MIT" }, - "../../../node_modules/html-minifier-terser": { - "version": "6.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "camel-case": "^4.1.2", - "clean-css": "^5.2.2", - "commander": "^8.3.0", - "he": "^1.2.0", - "param-case": "^3.0.4", - "relateurl": "^0.2.7", - "terser": "^5.10.0" - }, - "bin": { - "html-minifier-terser": "cli.js" - }, - "engines": { - "node": ">=12" - } - }, - "../../../node_modules/html-minifier-terser/node_modules/commander": { - "version": "8.3.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 12" - } - }, - "../../../node_modules/html-webpack-plugin": { - "version": "5.6.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/html-minifier-terser": "^6.0.0", - "html-minifier-terser": "^6.0.2", - "lodash": "^4.17.21", - "pretty-error": "^4.0.0", - "tapable": "^2.0.0" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/html-webpack-plugin" - }, - "peerDependencies": { - "@rspack/core": "0.x || 1.x", - "webpack": "^5.20.0" - }, - "peerDependenciesMeta": { - "@rspack/core": { - "optional": true - }, - "webpack": { - "optional": true - } - } - }, - "../../../node_modules/htmlparser2": { - "version": "6.1.0", - "dev": true, - "funding": [ - "https://github.com/fb55/htmlparser2?sponsor=1", - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "license": "MIT", - "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.0.0", - "domutils": "^2.5.2", - "entities": "^2.0.0" - } - }, "../../../node_modules/http-cache-semantics": { "version": "4.1.1", "dev": true, - "license": "BSD-2-Clause" - }, - "../../../node_modules/http-deceiver": { - "version": "1.2.7", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/http-errors": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "../../../node_modules/http-parser-js": { - "version": "0.5.8", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/http-proxy": { - "version": "1.18.1", - "dev": true, - "license": "MIT", - "dependencies": { - "eventemitter3": "^4.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" - }, - "engines": { - "node": ">=8.0.0" - } + "license": "BSD-2-Clause", + "optional": true, + "peer": true }, "../../../node_modules/http-proxy-agent": { "version": "4.0.1", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "dependencies": { "@tootallnate/once": "1", "agent-base": "6", @@ -6219,40 +4135,6 @@ "node": ">= 6" } }, - "../../../node_modules/http-proxy-middleware": { - "version": "2.0.6", - "dev": true, - "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" - }, - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "@types/express": "^4.17.13" - }, - "peerDependenciesMeta": { - "@types/express": { - "optional": true - } - } - }, - "../../../node_modules/http-proxy-middleware/node_modules/is-plain-obj": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "../../../node_modules/http-signature": { "version": "1.2.0", "license": "MIT", @@ -6270,6 +4152,8 @@ "version": "2.2.1", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "quick-lru": "^5.1.1", "resolve-alpn": "^1.2.0" @@ -6282,8 +4166,6 @@ "version": "5.0.1", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "dependencies": { "agent-base": "6", "debug": "4" @@ -6338,7 +4220,9 @@ "url": "https://feross.org/support" } ], - "license": "BSD-3-Clause" + "license": "BSD-3-Clause", + "optional": true, + "peer": true }, "../../../node_modules/ignore": { "version": "5.3.0", @@ -6576,117 +4460,42 @@ }, "../../../node_modules/ikonate/node_modules/whatwg-url": { "version": "6.5.0", - "license": "MIT", - "dependencies": { - "lodash.sortby": "^4.7.0", - "tr46": "^1.0.1", - "webidl-conversions": "^4.0.2" - } - }, - "../../../node_modules/ikonate/node_modules/ws": { - "version": "4.1.0", - "license": "MIT", - "dependencies": { - "async-limiter": "~1.0.0", - "safe-buffer": "~5.1.0" - } - }, - "../../../node_modules/import-fresh": { - "version": "3.3.0", - "dev": true, - "license": "MIT", - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/import-local": { - "version": "3.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - }, - "bin": { - "import-local-fixture": "fixtures/cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/import-local/node_modules/find-up": { - "version": "4.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "../../../node_modules/import-local/node_modules/locate-path": { - "version": "5.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "../../../node_modules/import-local/node_modules/p-limit": { - "version": "2.3.0", - "dev": true, - "license": "MIT", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "license": "MIT", + "dependencies": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" } }, - "../../../node_modules/import-local/node_modules/p-locate": { + "../../../node_modules/ikonate/node_modules/ws": { "version": "4.1.0", - "dev": true, "license": "MIT", "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" + "async-limiter": "~1.0.0", + "safe-buffer": "~5.1.0" } }, - "../../../node_modules/import-local/node_modules/pkg-dir": { - "version": "4.2.0", + "../../../node_modules/import-fresh": { + "version": "3.3.0", "dev": true, "license": "MIT", "dependencies": { - "find-up": "^4.0.0" + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" }, "engines": { - "node": ">=8" + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "../../../node_modules/import-meta-resolve": { "version": "4.0.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -6711,19 +4520,8 @@ }, "../../../node_modules/inherits": { "version": "2.0.4", - "license": "ISC" - }, - "../../../node_modules/ini": { - "version": "2.0.0", "dev": true, - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "../../../node_modules/insert-css": { - "version": "0.2.0", - "license": "MIT" + "license": "ISC" }, "../../../node_modules/internal-slot": { "version": "1.0.6", @@ -6738,18 +4536,12 @@ "node": ">= 0.4" } }, - "../../../node_modules/interpret": { - "version": "3.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10.13.0" - } - }, "../../../node_modules/ip-address": { "version": "9.0.5", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "jsbn": "1.1.0", "sprintf-js": "^1.1.3" @@ -6761,15 +4553,9 @@ "../../../node_modules/ip-address/node_modules/jsbn": { "version": "1.1.0", "dev": true, - "license": "MIT" - }, - "../../../node_modules/ipaddr.js": { - "version": "2.1.0", - "dev": true, "license": "MIT", - "engines": { - "node": ">= 10" - } + "optional": true, + "peer": true }, "../../../node_modules/is-array-buffer": { "version": "3.0.2", @@ -6784,11 +4570,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "../../../node_modules/is-arrayish": { - "version": "0.2.1", - "dev": true, - "license": "MIT" - }, "../../../node_modules/is-bigint": { "version": "1.0.4", "dev": true, @@ -6800,17 +4581,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "../../../node_modules/is-binary-path": { - "version": "2.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, "../../../node_modules/is-boolean-object": { "version": "1.1.2", "dev": true, @@ -6843,6 +4613,7 @@ }, "../../../node_modules/is-core-module": { "version": "2.13.1", + "dev": true, "license": "MIT", "dependencies": { "hasown": "^2.0.0" @@ -6865,20 +4636,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "../../../node_modules/is-docker": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "../../../node_modules/is-extendable": { "version": "0.1.1", "license": "MIT", @@ -6912,49 +4669,6 @@ "node": ">=0.10.0" } }, - "../../../node_modules/is-inside-container": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "is-docker": "^3.0.0" - }, - "bin": { - "is-inside-container": "cli.js" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/is-installed-globally": { - "version": "0.4.0", - "dev": true, - "license": "MIT", - "dependencies": { - "global-dirs": "^3.0.0", - "is-path-inside": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/is-interactive": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "../../../node_modules/is-negative-zero": { "version": "2.0.2", "dev": true, @@ -6966,17 +4680,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "../../../node_modules/is-network-error": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "../../../node_modules/is-number": { "version": "7.0.0", "dev": true, @@ -7011,6 +4714,8 @@ "version": "4.1.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=12" }, @@ -7032,9 +4737,7 @@ "../../../node_modules/is-potential-custom-element-name": { "version": "1.0.1", "dev": true, - "license": "MIT", - "optional": true, - "peer": true + "license": "MIT" }, "../../../node_modules/is-regex": { "version": "1.1.4", @@ -7119,17 +4822,6 @@ "version": "1.0.0", "license": "MIT" }, - "../../../node_modules/is-unicode-supported": { - "version": "1.3.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "../../../node_modules/is-weakref": { "version": "1.0.2", "dev": true, @@ -7148,22 +4840,9 @@ "node": ">=0.10.0" } }, - "../../../node_modules/is-wsl": { - "version": "3.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "is-inside-container": "^1.0.0" - }, - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "../../../node_modules/isarray": { "version": "2.0.5", + "dev": true, "license": "MIT" }, "../../../node_modules/isexe": { @@ -7198,26 +4877,12 @@ "@pkgjs/parseargs": "^0.11.0" } }, - "../../../node_modules/jest-util": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, "../../../node_modules/jest-worker": { "version": "27.5.1", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@types/node": "*", "merge-stream": "^2.0.0", @@ -7231,6 +4896,8 @@ "version": "8.1.1", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -7259,11 +4926,6 @@ "node": ">=14" } }, - "../../../node_modules/js-tokens": { - "version": "4.0.0", - "dev": true, - "license": "MIT" - }, "../../../node_modules/js-yaml": { "version": "4.1.0", "dev": true, @@ -7283,8 +4945,6 @@ "version": "17.0.0", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "dependencies": { "abab": "^2.0.5", "acorn": "^8.4.1", @@ -7334,7 +4994,9 @@ "../../../node_modules/json-parse-even-better-errors": { "version": "2.3.1", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/json-schema": { "version": "0.4.0", @@ -7353,17 +5015,6 @@ "version": "5.0.1", "license": "ISC" }, - "../../../node_modules/json5": { - "version": "2.2.3", - "dev": true, - "license": "MIT", - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, "../../../node_modules/jsonc-parser": { "version": "3.2.1", "dev": true, @@ -7373,6 +5024,8 @@ "version": "6.1.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "universalify": "^2.0.0" }, @@ -7384,6 +5037,8 @@ "version": "2.0.1", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">= 10.0.0" } @@ -7423,6 +5078,8 @@ "version": "0.33.3", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=14.16" }, @@ -7430,19 +5087,12 @@ "url": "https://github.com/sindresorhus/ky?sponsor=1" } }, - "../../../node_modules/launch-editor": { - "version": "2.6.1", - "dev": true, - "license": "MIT", - "dependencies": { - "picocolors": "^1.0.0", - "shell-quote": "^1.8.1" - } - }, "../../../node_modules/lazystream": { "version": "1.0.1", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "readable-stream": "^2.0.5" }, @@ -7534,37 +5184,23 @@ "url": "https://opencollective.com/parcel" } }, - "../../../node_modules/lines-and-columns": { - "version": "1.2.4", - "dev": true, - "license": "MIT" - }, "../../../node_modules/listenercount": { "version": "1.0.1", "dev": true, - "license": "ISC" + "license": "ISC", + "optional": true, + "peer": true }, "../../../node_modules/loader-runner": { "version": "4.3.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=6.11.5" } }, - "../../../node_modules/loader-utils": { - "version": "2.0.4", - "dev": true, - "license": "MIT", - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - }, - "engines": { - "node": ">=8.9.0" - } - }, "../../../node_modules/local-pkg": { "version": "0.5.0", "dev": true, @@ -7584,6 +5220,8 @@ "version": "2.2.20", "dev": true, "license": "SEE LICENSE IN LICENSE", + "optional": true, + "peer": true, "dependencies": { "n12": "1.8.23", "type-fest": "2.13.0", @@ -7594,6 +5232,8 @@ "version": "2.13.0", "dev": true, "license": "(MIT OR CC0-1.0)", + "optional": true, + "peer": true, "engines": { "node": ">=12.20" }, @@ -7626,7 +5266,9 @@ "../../../node_modules/lodash.clonedeep": { "version": "4.5.0", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/lodash.merge": { "version": "4.6.2", @@ -7637,46 +5279,19 @@ "version": "4.7.0", "license": "MIT" }, - "../../../node_modules/lodash.truncate": { - "version": "4.4.2", - "dev": true, - "license": "MIT" - }, "../../../node_modules/lodash.zip": { "version": "4.2.0", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/log-symbols": { - "version": "5.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^5.0.0", - "is-unicode-supported": "^1.1.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/log-symbols/node_modules/chalk": { - "version": "5.3.0", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } + "dev": true, + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/loglevel": { "version": "1.9.1", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">= 0.6.0" }, @@ -7688,7 +5303,9 @@ "../../../node_modules/loglevel-plugin-prefix": { "version": "0.8.4", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/loupe": { "version": "2.3.7", @@ -7698,18 +5315,12 @@ "get-func-name": "^2.0.1" } }, - "../../../node_modules/lower-case": { - "version": "2.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "tslib": "^2.0.3" - } - }, "../../../node_modules/lowercase-keys": { "version": "3.0.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, @@ -7735,48 +5346,6 @@ "node": ">=12" } }, - "../../../node_modules/media-typer": { - "version": "0.3.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "../../../node_modules/memfs": { - "version": "4.7.7", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.0.0" - }, - "engines": { - "node": ">= 4.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - } - }, - "../../../node_modules/merge-descriptors": { - "version": "1.0.1", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/merge-source-map": { - "version": "1.0.4", - "license": "MIT", - "dependencies": { - "source-map": "^0.5.6" - } - }, - "../../../node_modules/merge-source-map/node_modules/source-map": { - "version": "0.5.7", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, "../../../node_modules/merge-stream": { "version": "2.0.0", "dev": true, @@ -7790,14 +5359,6 @@ "node": ">= 8" } }, - "../../../node_modules/methods": { - "version": "1.1.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, "../../../node_modules/micromatch": { "version": "4.0.5", "dev": true, @@ -7810,17 +5371,6 @@ "node": ">=8.6" } }, - "../../../node_modules/mime": { - "version": "1.6.0", - "dev": true, - "license": "MIT", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, "../../../node_modules/mime-db": { "version": "1.52.0", "license": "MIT", @@ -7838,18 +5388,12 @@ "node": ">= 0.6" } }, - "../../../node_modules/mimic-fn": { - "version": "2.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "../../../node_modules/mimic-response": { "version": "4.0.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, @@ -7857,79 +5401,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "../../../node_modules/mini-css-extract-plugin": { - "version": "2.8.1", - "dev": true, - "license": "MIT", - "dependencies": { - "schema-utils": "^4.0.0", - "tapable": "^2.2.1" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.0.0" - } - }, - "../../../node_modules/mini-css-extract-plugin/node_modules/ajv": { - "version": "8.12.0", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "../../../node_modules/mini-css-extract-plugin/node_modules/ajv-keywords": { - "version": "5.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, - "../../../node_modules/mini-css-extract-plugin/node_modules/json-schema-traverse": { - "version": "1.0.0", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/mini-css-extract-plugin/node_modules/schema-utils": { - "version": "4.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.9.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.1.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "../../../node_modules/minimalistic-assert": { - "version": "1.0.1", - "dev": true, - "license": "ISC" - }, "../../../node_modules/minimatch": { "version": "9.0.3", "license": "ISC", @@ -7945,6 +5416,7 @@ }, "../../../node_modules/minimist": { "version": "1.2.8", + "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" @@ -7960,12 +5432,16 @@ "../../../node_modules/mitt": { "version": "3.0.0", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/mkdirp": { "version": "0.5.6", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "minimist": "^1.2.6" }, @@ -7997,22 +5473,12 @@ "dev": true, "license": "MIT" }, - "../../../node_modules/multicast-dns": { - "version": "7.2.5", - "dev": true, - "license": "MIT", - "dependencies": { - "dns-packet": "^5.2.2", - "thunky": "^1.0.2" - }, - "bin": { - "multicast-dns": "cli.js" - } - }, "../../../node_modules/n12": { "version": "1.8.23", "dev": true, - "license": "SEE LICENSE IN LICENSE" + "license": "SEE LICENSE IN LICENSE", + "optional": true, + "peer": true }, "../../../node_modules/nanoid": { "version": "3.3.7", @@ -8036,23 +5502,19 @@ "dev": true, "license": "MIT" }, - "../../../node_modules/negotiator": { - "version": "0.6.3", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, "../../../node_modules/neo-async": { "version": "2.6.2", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/netmask": { "version": "2.0.2", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">= 0.4.0" } @@ -8064,15 +5526,6 @@ "fflate": "*" } }, - "../../../node_modules/no-case": { - "version": "3.0.4", - "dev": true, - "license": "MIT", - "dependencies": { - "lower-case": "^2.0.2", - "tslib": "^2.0.3" - } - }, "../../../node_modules/node-domexception": { "version": "1.0.0", "dev": true, @@ -8087,6 +5540,8 @@ } ], "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=10.5.0" } @@ -8095,6 +5550,8 @@ "version": "3.3.2", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "data-uri-to-buffer": "^4.0.0", "fetch-blob": "^3.1.4", @@ -8108,18 +5565,12 @@ "url": "https://opencollective.com/node-fetch" } }, - "../../../node_modules/node-forge": { - "version": "1.3.1", - "dev": true, - "license": "(BSD-3-Clause OR GPL-2.0)", - "engines": { - "node": ">= 6.13.0" - } - }, "../../../node_modules/node-releases": { "version": "2.0.14", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/nopt": { "version": "7.2.0", @@ -8138,6 +5589,8 @@ "version": "3.0.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=0.10.0" } @@ -8146,6 +5599,8 @@ "version": "8.0.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=14.16" }, @@ -8153,28 +5608,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "../../../node_modules/npm-run-path": { - "version": "4.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "path-key": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "../../../node_modules/nth-check": { - "version": "2.1.1", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "boolbase": "^1.0.0" - }, - "funding": { - "url": "https://github.com/fb55/nth-check?sponsor=1" - } - }, "../../../node_modules/numcodecs": { "version": "0.3.1", "license": "MIT", @@ -8189,9 +5622,7 @@ "../../../node_modules/nwsapi": { "version": "2.2.7", "dev": true, - "license": "MIT", - "optional": true, - "peer": true + "license": "MIT" }, "../../../node_modules/oauth-sign": { "version": "0.9.0", @@ -8200,14 +5631,6 @@ "node": "*" } }, - "../../../node_modules/object-assign": { - "version": "4.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "../../../node_modules/object-inspect": { "version": "1.13.1", "dev": true, @@ -8284,67 +5707,12 @@ "url": "https://github.com/sponsors/ljharb" } }, - "../../../node_modules/obuf": { - "version": "1.1.2", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/on-finished": { - "version": "2.4.1", - "dev": true, - "license": "MIT", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "../../../node_modules/on-headers": { - "version": "1.0.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, "../../../node_modules/once": { - "version": "1.4.0", - "dev": true, - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, - "../../../node_modules/onetime": { - "version": "5.1.2", - "dev": true, - "license": "MIT", - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/open": { - "version": "10.1.0", - "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" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "version": "1.4.0", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" } }, "../../../node_modules/opener": { @@ -8371,68 +5739,12 @@ "node": ">= 0.8.0" } }, - "../../../node_modules/ora": { - "version": "6.3.1", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^5.0.0", - "cli-cursor": "^4.0.0", - "cli-spinners": "^2.6.1", - "is-interactive": "^2.0.0", - "is-unicode-supported": "^1.1.0", - "log-symbols": "^5.1.0", - "stdin-discarder": "^0.1.0", - "strip-ansi": "^7.0.1", - "wcwidth": "^1.0.1" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/ora/node_modules/ansi-regex": { - "version": "6.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "../../../node_modules/ora/node_modules/chalk": { - "version": "5.3.0", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "../../../node_modules/ora/node_modules/strip-ansi": { - "version": "7.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, "../../../node_modules/p-cancelable": { "version": "3.0.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=12.20" } @@ -8465,34 +5777,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "../../../node_modules/p-retry": { - "version": "6.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/retry": "0.12.2", - "is-network-error": "^1.0.0", - "retry": "^0.13.1" - }, - "engines": { - "node": ">=16.17" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/p-try": { - "version": "2.2.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "../../../node_modules/pac-proxy-agent": { "version": "7.0.1", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@tootallnate/quickjs-emscripten": "^0.23.0", "agent-base": "^7.0.2", @@ -8511,6 +5801,8 @@ "version": "7.1.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "debug": "^4.3.4" }, @@ -8522,6 +5814,8 @@ "version": "7.0.2", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "agent-base": "^7.1.0", "debug": "^4.3.4" @@ -8534,6 +5828,8 @@ "version": "7.0.4", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "agent-base": "^7.0.2", "debug": "4" @@ -8546,6 +5842,8 @@ "version": "7.0.1", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "degenerator": "^5.0.0", "netmask": "^2.0.2" @@ -8554,19 +5852,6 @@ "node": ">= 14" } }, - "../../../node_modules/pako": { - "version": "2.1.0", - "license": "(MIT AND Zlib)" - }, - "../../../node_modules/param-case": { - "version": "3.0.4", - "dev": true, - "license": "MIT", - "dependencies": { - "dot-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, "../../../node_modules/parent-module": { "version": "1.0.1", "dev": true, @@ -8578,46 +5863,10 @@ "node": ">=6" } }, - "../../../node_modules/parse-json": { - "version": "5.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "../../../node_modules/parse5": { "version": "6.0.1", "dev": true, - "license": "MIT", - "optional": true, - "peer": true - }, - "../../../node_modules/parseurl": { - "version": "1.3.3", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "../../../node_modules/pascal-case": { - "version": "3.1.2", - "dev": true, - "license": "MIT", - "dependencies": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } + "license": "MIT" }, "../../../node_modules/path-exists": { "version": "4.0.0", @@ -8644,6 +5893,7 @@ }, "../../../node_modules/path-parse": { "version": "1.0.7", + "dev": true, "license": "MIT" }, "../../../node_modules/path-scurry": { @@ -8660,19 +5910,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "../../../node_modules/path-to-regexp": { - "version": "0.1.7", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/path-type": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "../../../node_modules/pathe": { "version": "1.1.2", "dev": true, @@ -8711,96 +5948,6 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "../../../node_modules/pkg-dir": { - "version": "7.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "find-up": "^6.3.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/pkg-dir/node_modules/find-up": { - "version": "6.3.0", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^7.1.0", - "path-exists": "^5.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/pkg-dir/node_modules/locate-path": { - "version": "7.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^6.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/pkg-dir/node_modules/p-limit": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "yocto-queue": "^1.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/pkg-dir/node_modules/p-locate": { - "version": "6.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/pkg-dir/node_modules/path-exists": { - "version": "5.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - } - }, - "../../../node_modules/pkg-dir/node_modules/yocto-queue": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "../../../node_modules/pkg-types": { "version": "1.0.3", "dev": true, @@ -8948,15 +6095,6 @@ "node": ">=0.10.0" } }, - "../../../node_modules/pretty-error": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "lodash": "^4.17.20", - "renderkid": "^3.0.0" - } - }, "../../../node_modules/pretty-format": { "version": "29.7.0", "dev": true, @@ -8983,12 +6121,17 @@ }, "../../../node_modules/process-nextick-args": { "version": "2.0.1", - "license": "MIT" + "dev": true, + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/progress": { "version": "2.0.3", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=0.4.0" } @@ -8997,30 +6140,12 @@ "version": "1.2.4", "license": "ISC" }, - "../../../node_modules/proxy-addr": { - "version": "2.0.7", - "dev": true, - "license": "MIT", - "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "../../../node_modules/proxy-addr/node_modules/ipaddr.js": { - "version": "1.9.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.10" - } - }, "../../../node_modules/proxy-agent": { "version": "6.4.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "agent-base": "^7.0.2", "debug": "^4.3.4", @@ -9039,6 +6164,8 @@ "version": "7.1.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "debug": "^4.3.4" }, @@ -9050,6 +6177,8 @@ "version": "7.0.2", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "agent-base": "^7.1.0", "debug": "^4.3.4" @@ -9062,6 +6191,8 @@ "version": "7.0.4", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "agent-base": "^7.0.2", "debug": "4" @@ -9074,6 +6205,8 @@ "version": "7.18.3", "dev": true, "license": "ISC", + "optional": true, + "peer": true, "engines": { "node": ">=12" } @@ -9081,7 +6214,9 @@ "../../../node_modules/proxy-from-env": { "version": "1.1.0", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/psl": { "version": "1.9.0", @@ -9091,6 +6226,8 @@ "version": "3.0.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -9107,6 +6244,8 @@ "version": "20.9.0", "dev": true, "license": "Apache-2.0", + "optional": true, + "peer": true, "dependencies": { "@puppeteer/browsers": "1.4.6", "chromium-bidi": "0.4.16", @@ -9130,12 +6269,16 @@ "../../../node_modules/puppeteer-core/node_modules/devtools-protocol": { "version": "0.0.1147663", "dev": true, - "license": "BSD-3-Clause" + "license": "BSD-3-Clause", + "optional": true, + "peer": true }, "../../../node_modules/puppeteer-core/node_modules/ws": { "version": "8.13.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=10.0.0" }, @@ -9162,14 +6305,14 @@ "../../../node_modules/query-selector-shadow-dom": { "version": "1.0.1", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/querystringify": { "version": "2.2.0", "dev": true, - "license": "MIT", - "optional": true, - "peer": true + "license": "MIT" }, "../../../node_modules/queue-microtask": { "version": "1.2.3", @@ -9193,12 +6336,16 @@ "../../../node_modules/queue-tick": { "version": "1.0.1", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/quick-lru": { "version": "5.1.1", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=10" }, @@ -9206,64 +6353,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "../../../node_modules/quote-stream": { - "version": "1.0.2", - "license": "MIT", - "dependencies": { - "buffer-equal": "0.0.1", - "minimist": "^1.1.3", - "through2": "^2.0.0" - }, - "bin": { - "quote-stream": "bin/cmd.js" - } - }, - "../../../node_modules/quote-stream/node_modules/through2": { - "version": "2.0.5", - "license": "MIT", - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, "../../../node_modules/randombytes": { "version": "2.1.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "safe-buffer": "^5.1.0" } }, - "../../../node_modules/range-parser": { - "version": "1.2.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "../../../node_modules/raw-body": { - "version": "2.5.2", - "dev": true, - "license": "MIT", - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "../../../node_modules/raw-body/node_modules/bytes": { - "version": "3.1.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, "../../../node_modules/react-is": { "version": "18.2.0", "dev": true, @@ -9271,7 +6370,10 @@ }, "../../../node_modules/readable-stream": { "version": "2.3.8", + "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -9284,16 +6386,24 @@ }, "../../../node_modules/readable-stream/node_modules/isarray": { "version": "1.0.0", - "license": "MIT" + "dev": true, + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/readable-stream/node_modules/safe-buffer": { "version": "5.1.2", - "license": "MIT" + "dev": true, + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/readdir-glob": { "version": "1.1.3", "dev": true, "license": "Apache-2.0", + "optional": true, + "peer": true, "dependencies": { "minimatch": "^5.1.0" } @@ -9302,6 +6412,8 @@ "version": "5.1.6", "dev": true, "license": "ISC", + "optional": true, + "peer": true, "dependencies": { "brace-expansion": "^2.0.1" }, @@ -9309,28 +6421,6 @@ "node": ">=10" } }, - "../../../node_modules/readdirp": { - "version": "3.6.0", - "dev": true, - "license": "MIT", - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "../../../node_modules/rechoir": { - "version": "0.8.0", - "dev": true, - "license": "MIT", - "dependencies": { - "resolve": "^1.20.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, "../../../node_modules/regexp.prototype.flags": { "version": "1.5.1", "dev": true, @@ -9347,26 +6437,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "../../../node_modules/relateurl": { - "version": "0.2.7", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.10" - } - }, - "../../../node_modules/renderkid": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "css-select": "^4.1.3", - "dom-converter": "^0.2.0", - "htmlparser2": "^6.1.0", - "lodash": "^4.17.21", - "strip-ansi": "^6.0.1" - } - }, "../../../node_modules/request": { "version": "2.88.2", "license": "Apache-2.0", @@ -9466,14 +6536,6 @@ "node": ">=0.10.0" } }, - "../../../node_modules/require-from-string": { - "version": "2.0.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "../../../node_modules/requires-port": { "version": "1.0.0", "dev": true, @@ -9481,6 +6543,7 @@ }, "../../../node_modules/resolve": { "version": "1.22.8", + "dev": true, "license": "MIT", "dependencies": { "is-core-module": "^2.13.0", @@ -9497,26 +6560,9 @@ "../../../node_modules/resolve-alpn": { "version": "1.2.1", "dev": true, - "license": "MIT" - }, - "../../../node_modules/resolve-cwd": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "../../../node_modules/resolve-cwd/node_modules/resolve-from": { - "version": "5.0.0", - "dev": true, "license": "MIT", - "engines": { - "node": ">=8" - } + "optional": true, + "peer": true }, "../../../node_modules/resolve-from": { "version": "4.0.0", @@ -9538,6 +6584,8 @@ "version": "3.0.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "lowercase-keys": "^3.0.0" }, @@ -9552,6 +6600,8 @@ "version": "1.11.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "fast-deep-equal": "^2.0.1" } @@ -9559,35 +6609,9 @@ "../../../node_modules/resq/node_modules/fast-deep-equal": { "version": "2.0.1", "dev": true, - "license": "MIT" - }, - "../../../node_modules/restore-cursor": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/restore-cursor/node_modules/signal-exit": { - "version": "3.0.7", - "dev": true, - "license": "ISC" - }, - "../../../node_modules/retry": { - "version": "0.13.1", - "dev": true, "license": "MIT", - "engines": { - "node": ">= 4" - } + "optional": true, + "peer": true }, "../../../node_modules/reusify": { "version": "1.0.4", @@ -9601,7 +6625,9 @@ "../../../node_modules/rgb2hex": { "version": "0.2.5", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/rimraf": { "version": "3.0.2", @@ -9687,17 +6713,6 @@ "fsevents": "~2.3.2" } }, - "../../../node_modules/run-applescript": { - "version": "7.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "../../../node_modules/run-parallel": { "version": "1.2.0", "dev": true, @@ -9723,7 +6738,9 @@ "../../../node_modules/safaridriver": { "version": "0.1.2", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/safe-array-concat": { "version": "1.1.0", @@ -9788,8 +6805,6 @@ "version": "5.0.1", "dev": true, "license": "ISC", - "optional": true, - "peer": true, "dependencies": { "xmlchars": "^2.2.0" }, @@ -9801,6 +6816,8 @@ "version": "3.3.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@types/json-schema": "^7.0.8", "ajv": "^6.12.5", @@ -9814,23 +6831,6 @@ "url": "https://opencollective.com/webpack" } }, - "../../../node_modules/select-hose": { - "version": "2.0.0", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/selfsigned": { - "version": "2.4.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node-forge": "^1.3.0", - "node-forge": "^1" - }, - "engines": { - "node": ">=10" - } - }, "../../../node_modules/semver": { "version": "7.5.4", "license": "ISC", @@ -9841,164 +6841,43 @@ "semver": "bin/semver.js" }, "engines": { - "node": ">=10" - } - }, - "../../../node_modules/semver/node_modules/lru-cache": { - "version": "6.0.0", - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "../../../node_modules/send": { - "version": "0.18.0", - "dev": true, - "license": "MIT", - "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" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "../../../node_modules/send/node_modules/debug": { - "version": "2.6.9", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "../../../node_modules/send/node_modules/debug/node_modules/ms": { - "version": "2.0.0", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/send/node_modules/ms": { - "version": "2.1.3", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/serialize-error": { - "version": "11.0.3", - "dev": true, - "license": "MIT", - "dependencies": { - "type-fest": "^2.12.2" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/serialize-javascript": { - "version": "6.0.2", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "randombytes": "^2.1.0" - } - }, - "../../../node_modules/serve-index": { - "version": "1.9.1", - "dev": true, - "license": "MIT", - "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" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "../../../node_modules/serve-index/node_modules/debug": { - "version": "2.6.9", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "../../../node_modules/serve-index/node_modules/depd": { - "version": "1.1.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" + "node": ">=10" } }, - "../../../node_modules/serve-index/node_modules/http-errors": { - "version": "1.6.3", - "dev": true, - "license": "MIT", + "../../../node_modules/semver/node_modules/lru-cache": { + "version": "6.0.0", + "license": "ISC", "dependencies": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": ">= 1.4.0 < 2" + "yallist": "^4.0.0" }, "engines": { - "node": ">= 0.6" + "node": ">=10" } }, - "../../../node_modules/serve-index/node_modules/inherits": { - "version": "2.0.3", - "dev": true, - "license": "ISC" - }, - "../../../node_modules/serve-index/node_modules/ms": { - "version": "2.0.0", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/serve-index/node_modules/setprototypeof": { - "version": "1.1.0", - "dev": true, - "license": "ISC" - }, - "../../../node_modules/serve-index/node_modules/statuses": { - "version": "1.5.0", + "../../../node_modules/serialize-error": { + "version": "11.0.3", "dev": true, "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "type-fest": "^2.12.2" + }, "engines": { - "node": ">= 0.6" + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "../../../node_modules/serve-static": { - "version": "1.15.0", + "../../../node_modules/serialize-javascript": { + "version": "6.0.2", "dev": true, - "license": "MIT", + "license": "BSD-3-Clause", + "optional": true, + "peer": true, "dependencies": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.18.0" - }, - "engines": { - "node": ">= 0.8.0" + "randombytes": "^2.1.0" } }, "../../../node_modules/set-function-length": { @@ -10032,12 +6911,9 @@ "../../../node_modules/setimmediate": { "version": "1.0.5", "dev": true, - "license": "MIT" - }, - "../../../node_modules/setprototypeof": { - "version": "1.2.0", - "dev": true, - "license": "ISC" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/shallow-clone": { "version": "3.0.1", @@ -10058,10 +6934,6 @@ "node": ">=0.10.0" } }, - "../../../node_modules/shallow-copy": { - "version": "0.0.1", - "license": "MIT" - }, "../../../node_modules/shebang-command": { "version": "2.0.0", "license": "MIT", @@ -10079,14 +6951,6 @@ "node": ">=8" } }, - "../../../node_modules/shell-quote": { - "version": "1.8.1", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "../../../node_modules/side-channel": { "version": "1.0.4", "dev": true, @@ -10115,11 +6979,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "../../../node_modules/simple-html-tokenizer": { - "version": "0.1.1", - "dev": true, - "license": "MIT" - }, "../../../node_modules/sirv": { "version": "2.0.4", "dev": true, @@ -10133,61 +6992,23 @@ "node": ">= 10" } }, - "../../../node_modules/slash": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "../../../node_modules/slice-ansi": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" - } - }, "../../../node_modules/smart-buffer": { "version": "4.2.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">= 6.0.0", "npm": ">= 3.0.0" } }, - "../../../node_modules/sockjs": { - "version": "0.3.24", - "dev": true, - "license": "MIT", - "dependencies": { - "faye-websocket": "^0.11.3", - "uuid": "^8.3.2", - "websocket-driver": "^0.7.4" - } - }, - "../../../node_modules/sockjs/node_modules/uuid": { - "version": "8.3.2", - "dev": true, - "license": "MIT", - "bin": { - "uuid": "dist/bin/uuid" - } - }, "../../../node_modules/socks": { "version": "2.7.3", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "ip-address": "^9.0.5", "smart-buffer": "^4.2.0" @@ -10201,6 +7022,8 @@ "version": "8.0.2", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "agent-base": "^7.0.2", "debug": "^4.3.4", @@ -10214,6 +7037,8 @@ "version": "7.1.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "debug": "^4.3.4" }, @@ -10221,15 +7046,10 @@ "node": ">= 14" } }, - "../../../node_modules/source-list-map": { - "version": "2.0.1", - "dev": true, - "license": "MIT" - }, "../../../node_modules/source-map": { "version": "0.6.1", - "devOptional": true, "license": "BSD-3-Clause", + "optional": true, "engines": { "node": ">=0.10.0" } @@ -10246,56 +7066,19 @@ "version": "0.5.21", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" } }, - "../../../node_modules/spdy": { - "version": "4.0.2", - "dev": true, - "license": "MIT", - "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" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "../../../node_modules/spdy-transport": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "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_modules/spdy-transport/node_modules/readable-stream": { - "version": "3.6.2", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "../../../node_modules/split2": { "version": "4.2.0", "dev": true, "license": "ISC", + "optional": true, + "peer": true, "engines": { "node": ">= 10.x" } @@ -10303,189 +7086,43 @@ "../../../node_modules/sprintf-js": { "version": "1.1.3", "dev": true, - "license": "BSD-3-Clause" + "license": "BSD-3-Clause", + "optional": true, + "peer": true }, "../../../node_modules/sshpk": { - "version": "1.18.0", - "license": "MIT", - "dependencies": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "bin": { - "sshpk-conv": "bin/sshpk-conv", - "sshpk-sign": "bin/sshpk-sign", - "sshpk-verify": "bin/sshpk-verify" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "../../../node_modules/stackback": { - "version": "0.0.2", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/static-eval": { - "version": "2.1.1", - "license": "MIT", - "dependencies": { - "escodegen": "^2.1.0" - } - }, - "../../../node_modules/static-module": { - "version": "2.2.5", - "license": "MIT", - "dependencies": { - "concat-stream": "~1.6.0", - "convert-source-map": "^1.5.1", - "duplexer2": "~0.1.4", - "escodegen": "~1.9.0", - "falafel": "^2.1.0", - "has": "^1.0.1", - "magic-string": "^0.22.4", - "merge-source-map": "1.0.4", - "object-inspect": "~1.4.0", - "quote-stream": "~1.0.2", - "readable-stream": "~2.3.3", - "shallow-copy": "~0.0.1", - "static-eval": "^2.0.0", - "through2": "~2.0.3" - } - }, - "../../../node_modules/static-module/node_modules/escodegen": { - "version": "1.9.1", - "license": "BSD-2-Clause", - "dependencies": { - "esprima": "^3.1.3", - "estraverse": "^4.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1" - }, - "bin": { - "escodegen": "bin/escodegen.js", - "esgenerate": "bin/esgenerate.js" - }, - "engines": { - "node": ">=4.0" - }, - "optionalDependencies": { - "source-map": "~0.6.1" - } - }, - "../../../node_modules/static-module/node_modules/esprima": { - "version": "3.1.3", - "license": "BSD-2-Clause", - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "../../../node_modules/static-module/node_modules/estraverse": { - "version": "4.3.0", - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, - "../../../node_modules/static-module/node_modules/levn": { - "version": "0.3.0", - "license": "MIT", - "dependencies": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "../../../node_modules/static-module/node_modules/magic-string": { - "version": "0.22.5", - "license": "MIT", - "dependencies": { - "vlq": "^0.2.2" - } - }, - "../../../node_modules/static-module/node_modules/object-inspect": { - "version": "1.4.1", - "license": "MIT" - }, - "../../../node_modules/static-module/node_modules/optionator": { - "version": "0.8.3", - "license": "MIT", - "dependencies": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "../../../node_modules/static-module/node_modules/prelude-ls": { - "version": "1.1.2", - "engines": { - "node": ">= 0.8.0" - } - }, - "../../../node_modules/static-module/node_modules/through2": { - "version": "2.0.5", - "license": "MIT", - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "../../../node_modules/static-module/node_modules/type-check": { - "version": "0.3.2", + "version": "1.18.0", "license": "MIT", "dependencies": { - "prelude-ls": "~1.1.2" + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" }, "engines": { - "node": ">= 0.8.0" + "node": ">=0.10.0" } }, - "../../../node_modules/statuses": { - "version": "2.0.1", + "../../../node_modules/stackback": { + "version": "0.0.2", "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } + "license": "MIT" }, "../../../node_modules/std-env": { "version": "3.7.0", "dev": true, "license": "MIT" }, - "../../../node_modules/stdin-discarder": { - "version": "0.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "bl": "^5.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "../../../node_modules/stealthy-require": { "version": "1.1.1", "license": "ISC", @@ -10497,6 +7134,8 @@ "version": "2.15.6", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "fast-fifo": "^1.1.0", "queue-tick": "^1.0.1" @@ -10504,14 +7143,20 @@ }, "../../../node_modules/string_decoder": { "version": "1.1.1", + "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "safe-buffer": "~5.1.0" } }, "../../../node_modules/string_decoder/node_modules/safe-buffer": { "version": "5.1.2", - "license": "MIT" + "dev": true, + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/string-width": { "version": "5.1.2", @@ -10677,21 +7322,6 @@ "dev": true, "license": "MIT" }, - "../../../node_modules/style-loader": { - "version": "3.3.4", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.0.0" - } - }, "../../../node_modules/supports-color": { "version": "7.2.0", "dev": true, @@ -10703,20 +7333,9 @@ "node": ">=8" } }, - "../../../node_modules/supports-hyperlinks": { - "version": "2.3.0", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0", - "supports-color": "^7.0.0" - }, - "engines": { - "node": ">=8" - } - }, "../../../node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -10725,97 +7344,10 @@ "url": "https://github.com/sponsors/ljharb" } }, - "../../../node_modules/svg-inline-loader": { - "version": "0.8.2", - "dev": true, - "license": "MIT", - "dependencies": { - "loader-utils": "^1.1.0", - "object-assign": "^4.0.1", - "simple-html-tokenizer": "^0.1.1" - } - }, - "../../../node_modules/svg-inline-loader/node_modules/json5": { - "version": "1.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" - } - }, - "../../../node_modules/svg-inline-loader/node_modules/loader-utils": { - "version": "1.4.2", - "dev": true, - "license": "MIT", - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - }, - "engines": { - "node": ">=4.0.0" - } - }, "../../../node_modules/symbol-tree": { "version": "3.2.4", "license": "MIT" }, - "../../../node_modules/table": { - "version": "6.8.1", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "ajv": "^8.0.1", - "lodash.truncate": "^4.4.2", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "../../../node_modules/table/node_modules/ajv": { - "version": "8.12.0", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "../../../node_modules/table/node_modules/emoji-regex": { - "version": "8.0.0", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/table/node_modules/json-schema-traverse": { - "version": "1.0.0", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/table/node_modules/string-width": { - "version": "4.2.3", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, "../../../node_modules/tapable": { "version": "2.2.1", "dev": true, @@ -10828,6 +7360,8 @@ "version": "3.0.5", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "pump": "^3.0.0", "tar-stream": "^3.1.5" @@ -10841,31 +7375,20 @@ "version": "3.1.7", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "b4a": "^1.6.4", "fast-fifo": "^1.2.0", "streamx": "^2.15.0" } }, - "../../../node_modules/terminal-link": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-escapes": "^5.0.0", - "supports-hyperlinks": "^2.2.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "../../../node_modules/terser": { "version": "5.29.1", "dev": true, "license": "BSD-2-Clause", + "optional": true, + "peer": true, "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.8.2", @@ -10883,6 +7406,8 @@ "version": "5.3.10", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@jridgewell/trace-mapping": "^0.3.20", "jest-worker": "^27.4.5", @@ -10915,7 +7440,9 @@ "../../../node_modules/terser/node_modules/commander": { "version": "2.20.3", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/text-table": { "version": "0.2.0", @@ -10925,38 +7452,9 @@ "../../../node_modules/through": { "version": "2.3.8", "dev": true, - "license": "MIT" - }, - "../../../node_modules/through2": { - "version": "0.6.5", - "license": "MIT", - "dependencies": { - "readable-stream": ">=1.0.33-1 <1.1.0-0", - "xtend": ">=4.0.0 <4.1.0-0" - } - }, - "../../../node_modules/through2/node_modules/isarray": { - "version": "0.0.1", - "license": "MIT" - }, - "../../../node_modules/through2/node_modules/readable-stream": { - "version": "1.0.34", "license": "MIT", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "../../../node_modules/through2/node_modules/string_decoder": { - "version": "0.10.31", - "license": "MIT" - }, - "../../../node_modules/thunky": { - "version": "1.1.0", - "dev": true, - "license": "MIT" + "optional": true, + "peer": true }, "../../../node_modules/tinybench": { "version": "2.6.0", @@ -10990,14 +7488,6 @@ "node": ">=8.0" } }, - "../../../node_modules/toidentifier": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.6" - } - }, "../../../node_modules/totalist": { "version": "3.0.1", "dev": true, @@ -11010,8 +7500,6 @@ "version": "4.1.3", "dev": true, "license": "BSD-3-Clause", - "optional": true, - "peer": true, "dependencies": { "psl": "^1.1.33", "punycode": "^2.1.1", @@ -11026,8 +7514,6 @@ "version": "2.1.0", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "dependencies": { "punycode": "^2.1.1" }, @@ -11038,18 +7524,9 @@ "../../../node_modules/traverse": { "version": "0.3.9", "dev": true, - "license": "MIT/X11" - }, - "../../../node_modules/ts-api-utils": { - "version": "1.2.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=16" - }, - "peerDependencies": { - "typescript": ">=4.2.0" - } + "license": "MIT/X11", + "optional": true, + "peer": true }, "../../../node_modules/tsconfig-paths": { "version": "3.15.0", @@ -11076,7 +7553,9 @@ "../../../node_modules/tslib": { "version": "2.6.2", "dev": true, - "license": "0BSD" + "license": "0BSD", + "optional": true, + "peer": true }, "../../../node_modules/tsx": { "version": "4.7.1", @@ -11185,6 +7664,8 @@ "version": "2.19.0", "dev": true, "license": "(MIT OR CC0-1.0)", + "optional": true, + "peer": true, "engines": { "node": ">=12.20" }, @@ -11192,18 +7673,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "../../../node_modules/type-is": { - "version": "1.6.18", - "dev": true, - "license": "MIT", - "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - }, - "engines": { - "node": ">= 0.6" - } - }, "../../../node_modules/typed-array-buffer": { "version": "1.0.0", "dev": true, @@ -11265,10 +7734,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "../../../node_modules/typedarray": { - "version": "0.0.6", - "license": "MIT" - }, "../../../node_modules/typescript": { "version": "5.3.3", "dev": true, @@ -11304,6 +7769,8 @@ "version": "1.4.3", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "buffer": "^5.2.1", "through": "^2.3.8" @@ -11327,6 +7794,8 @@ } ], "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" @@ -11341,24 +7810,16 @@ "version": "0.2.0", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "engines": { "node": ">= 4.0.0" } }, - "../../../node_modules/unpipe": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, "../../../node_modules/unzipper": { "version": "0.10.14", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "big-integer": "^1.6.17", "binary": "~0.3.0", @@ -11390,6 +7851,8 @@ } ], "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "escalade": "^3.1.1", "picocolors": "^1.0.0" @@ -11412,8 +7875,6 @@ "version": "1.5.10", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "dependencies": { "querystringify": "^2.1.1", "requires-port": "^1.0.0" @@ -11422,40 +7883,22 @@ "../../../node_modules/userhome": { "version": "1.0.0", "dev": true, + "optional": true, + "peer": true, "engines": { "node": ">= 0.8.0" } }, "../../../node_modules/util-deprecate": { "version": "1.0.2", - "license": "MIT" - }, - "../../../node_modules/utila": { - "version": "0.4.0", "dev": true, "license": "MIT" }, - "../../../node_modules/utils-merge": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4.0" - } - }, "../../../node_modules/uuid": { - "version": "3.4.0", - "license": "MIT", - "bin": { - "uuid": "bin/uuid" - } - }, - "../../../node_modules/vary": { - "version": "1.1.2", - "dev": true, + "version": "3.4.0", "license": "MIT", - "engines": { - "node": ">= 0.8" + "bin": { + "uuid": "bin/uuid" } }, "../../../node_modules/verror": { @@ -11673,10 +8116,6 @@ "node": ">=0.4.0" } }, - "../../../node_modules/vlq": { - "version": "0.2.3", - "license": "MIT" - }, "../../../node_modules/w3c-hr-time": { "version": "1.0.2", "license": "MIT", @@ -11688,8 +8127,6 @@ "version": "2.0.0", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "dependencies": { "xml-name-validator": "^3.0.0" }, @@ -11701,6 +8138,8 @@ "version": "1.1.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "chalk": "^4.1.2", "commander": "^9.3.0", @@ -11717,6 +8156,8 @@ "version": "2.4.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.1.2" @@ -11725,26 +8166,12 @@ "node": ">=10.13.0" } }, - "../../../node_modules/wbuf": { - "version": "1.7.3", - "dev": true, - "license": "MIT", - "dependencies": { - "minimalistic-assert": "^1.0.0" - } - }, - "../../../node_modules/wcwidth": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "defaults": "^1.0.3" - } - }, "../../../node_modules/web-streams-polyfill": { "version": "3.3.3", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">= 8" } @@ -11753,6 +8180,8 @@ "version": "8.32.3", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@types/node": "^20.1.0", "@types/ws": "^8.5.3", @@ -11774,6 +8203,8 @@ "version": "8.32.3", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@types/node": "^20.1.0", "@wdio/config": "8.32.3", @@ -11816,8 +8247,6 @@ "version": "6.1.0", "dev": true, "license": "BSD-2-Clause", - "optional": true, - "peer": true, "engines": { "node": ">=10.4" } @@ -11826,6 +8255,8 @@ "version": "5.90.3", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@types/eslint-scope": "^3.7.3", "@types/estree": "^1.0.5", @@ -11938,260 +8369,6 @@ } } }, - "../../../node_modules/webpack-cli": { - "version": "5.1.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@discoveryjs/json-ext": "^0.5.0", - "@webpack-cli/configtest": "^2.1.1", - "@webpack-cli/info": "^2.0.2", - "@webpack-cli/serve": "^2.0.5", - "colorette": "^2.0.14", - "commander": "^10.0.1", - "cross-spawn": "^7.0.3", - "envinfo": "^7.7.3", - "fastest-levenshtein": "^1.0.12", - "import-local": "^3.0.2", - "interpret": "^3.1.1", - "rechoir": "^0.8.0", - "webpack-merge": "^5.7.3" - }, - "bin": { - "webpack-cli": "bin/cli.js" - }, - "engines": { - "node": ">=14.15.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "5.x.x" - }, - "peerDependenciesMeta": { - "@webpack-cli/generators": { - "optional": true - }, - "webpack-bundle-analyzer": { - "optional": true - }, - "webpack-dev-server": { - "optional": true - } - } - }, - "../../../node_modules/webpack-cli/node_modules/commander": { - "version": "10.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14" - } - }, - "../../../node_modules/webpack-dev-middleware": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-7.1.1.tgz", - "integrity": "sha512-NmRVq4AvRQs66dFWyDR4GsFDJggtSi2Yn38MXLk0nffgF9n/AIP4TFBg2TQKYaRAN4sHuKOTiz9BnNCENDLEVA==", - "dev": true, - "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" - }, - "engines": { - "node": ">= 18.12.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.0.0" - }, - "peerDependenciesMeta": { - "webpack": { - "optional": true - } - } - }, - "../../../node_modules/webpack-dev-middleware/node_modules/ajv": { - "version": "8.12.0", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "../../../node_modules/webpack-dev-middleware/node_modules/ajv-keywords": { - "version": "5.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, - "../../../node_modules/webpack-dev-middleware/node_modules/json-schema-traverse": { - "version": "1.0.0", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/webpack-dev-middleware/node_modules/schema-utils": { - "version": "4.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.9.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.1.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "../../../node_modules/webpack-dev-server": { - "version": "5.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/bonjour": "^3.5.13", - "@types/connect-history-api-fallback": "^1.5.4", - "@types/express": "^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", - "default-gateway": "^6.0.3", - "express": "^4.17.3", - "graceful-fs": "^4.2.6", - "html-entities": "^2.4.0", - "http-proxy-middleware": "^2.0.3", - "ipaddr.js": "^2.1.0", - "launch-editor": "^2.6.1", - "open": "^10.0.3", - "p-retry": "^6.2.0", - "rimraf": "^5.0.5", - "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.0.0", - "ws": "^8.16.0" - }, - "bin": { - "webpack-dev-server": "bin/webpack-dev-server.js" - }, - "engines": { - "node": ">= 18.12.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.0.0" - }, - "peerDependenciesMeta": { - "webpack": { - "optional": true - }, - "webpack-cli": { - "optional": true - } - } - }, - "../../../node_modules/webpack-dev-server/node_modules/ajv": { - "version": "8.12.0", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "../../../node_modules/webpack-dev-server/node_modules/ajv-keywords": { - "version": "5.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, - "../../../node_modules/webpack-dev-server/node_modules/json-schema-traverse": { - "version": "1.0.0", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/webpack-dev-server/node_modules/rimraf": { - "version": "5.0.5", - "dev": true, - "license": "ISC", - "dependencies": { - "glob": "^10.3.7" - }, - "bin": { - "rimraf": "dist/esm/bin.mjs" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "../../../node_modules/webpack-dev-server/node_modules/schema-utils": { - "version": "4.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.9.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.1.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, "../../../node_modules/webpack-merge": { "version": "5.10.0", "dev": true, @@ -12205,19 +8382,12 @@ "node": ">=10.0.0" } }, - "../../../node_modules/webpack-sources": { - "version": "1.4.3", - "dev": true, - "license": "MIT", - "dependencies": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" - } - }, "../../../node_modules/webpack/node_modules/eslint-scope": { "version": "5.1.1", "dev": true, "license": "BSD-2-Clause", + "optional": true, + "peer": true, "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^4.1.1" @@ -12230,6 +8400,8 @@ "version": "4.3.0", "dev": true, "license": "BSD-2-Clause", + "optional": true, + "peer": true, "engines": { "node": ">=4.0" } @@ -12238,6 +8410,8 @@ "version": "3.3.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=0.8.x" } @@ -12246,31 +8420,12 @@ "version": "3.2.3", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=10.13.0" } }, - "../../../node_modules/websocket-driver": { - "version": "0.7.4", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "http-parser-js": ">=0.5.1", - "safe-buffer": ">=5.1.0", - "websocket-extensions": ">=0.1.1" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "../../../node_modules/websocket-extensions": { - "version": "0.1.4", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=0.8.0" - } - }, "../../../node_modules/whatwg-encoding": { "version": "1.0.5", "license": "MIT", @@ -12286,8 +8441,6 @@ "version": "9.1.0", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "dependencies": { "tr46": "^2.1.0", "webidl-conversions": "^6.1.0" @@ -12357,20 +8510,6 @@ "node": ">=8" } }, - "../../../node_modules/widest-line": { - "version": "4.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "string-width": "^5.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "../../../node_modules/wildcard": { "version": "2.0.1", "dev": true, @@ -12495,9 +8634,7 @@ "../../../node_modules/xmlchars": { "version": "2.2.0", "dev": true, - "license": "MIT", - "optional": true, - "peer": true + "license": "MIT" }, "../../../node_modules/xmldom": { "version": "0.1.31", @@ -12506,13 +8643,6 @@ "node": ">=0.1" } }, - "../../../node_modules/xtend": { - "version": "4.0.2", - "license": "MIT", - "engines": { - "node": ">=0.4" - } - }, "../../../node_modules/y18n": { "version": "5.0.8", "dev": true, @@ -12525,14 +8655,6 @@ "version": "4.0.0", "license": "ISC" }, - "../../../node_modules/yaml": { - "version": "1.10.2", - "dev": true, - "license": "ISC", - "engines": { - "node": ">= 6" - } - }, "../../../node_modules/yargs": { "version": "17.7.2", "dev": true, @@ -12600,6 +8722,8 @@ "version": "5.0.1", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "archiver-utils": "^4.0.1", "compress-commons": "^5.0.1", @@ -12613,6 +8737,8 @@ "version": "3.6.2", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", diff --git a/examples/vite/vite-project-source/vite.config.ts b/examples/vite/vite-project-source/vite.config.ts index b8be9b45a4..2ae4893af1 100644 --- a/examples/vite/vite-project-source/vite.config.ts +++ b/examples/vite/vite-project-source/vite.config.ts @@ -11,6 +11,10 @@ export default defineConfig({ "neuroglancer/datasource/precomputed:enabled", ], }, + esbuild: { + // Needed to acommodate decorator usage in Neuroglancer TypeScript sources. + target: "es2022", + }, worker: { // Required due to use of dynamic imports in Neuroglancer. format: "es", @@ -23,8 +27,28 @@ export default defineConfig({ fs: { // Allow serving files from parent neuroglancer project, due to the local // path reference. This would not be needed for projects that depend on - // Neuroglancer normally. + // Neuroglancer normally, or when using pnpm rather than npm. allow: ["../../.."], }, }, + optimizeDeps: { + // Neuroglancer is incompatible with Vite's optimizeDeps step used for the + // dev server due to its use of `new URL` syntax (not supported by esbuild). + exclude: ["neuroglancer"], + // Some of Neuroglancer's dependencies are CommonJS modules for which the + // optimizeDeps step is mandatory. + // + // There does not seem to be a way to avoid having to specify all of these + // explicitly. + include: [ + "neuroglancer > codemirror", + "neuroglancer > codemirror/mode/javascript/javascript.js", + "neuroglancer > codemirror/addon/fold/foldcode.js", + "neuroglancer > codemirror/addon/fold/foldgutter.js", + "neuroglancer > codemirror/addon/fold/brace-fold.js", + "neuroglancer > codemirror/addon/lint/lint.js", + "neuroglancer > core-js/actual/symbol/dispose.js", + "neuroglancer > core-js/actual/symbol/async-dispose.js", + ], + }, }); diff --git a/examples/webpack/webpack-project-built/package-lock.json b/examples/webpack/webpack-project-built/package-lock.json index 557bec6cc3..1f2d085634 100644 --- a/examples/webpack/webpack-project-built/package-lock.json +++ b/examples/webpack/webpack-project-built/package-lock.json @@ -15,7 +15,6 @@ "css-loader": "^7.1.2", "html-webpack-plugin": "^5.6.0", "style-loader": "^4.0.0", - "svg-inline-loader": "^0.8.2", "webpack": "^5.93.0", "webpack-cli": "^5.1.4", "webpack-dev-server": "^5.0.4" @@ -27,16 +26,16 @@ "license": "Apache-2.0", "dependencies": { "codemirror": "^5.61.1", + "core-js": "^3.40.0", + "crc-32": "^1.2.2", "gl-matrix": "3.1.0", - "glsl-editor": "^1.0.0", "ikonate": "github:mikolajdobrucki/ikonate#a86b4107c6ec717e7877f880a930d1ccf0b59d89", "lodash-es": "^4.17.21", "nifti-reader-js": "^0.6.8", - "numcodecs": "^0.3.1", - "pako": "^2.1.0" + "numcodecs": "^0.3.2" }, "engines": { - "node": ">=20.10 <21 || >=21.2" + "node": ">=22" } }, "node_modules/@discoveryjs/json-ext": { @@ -736,14 +735,6 @@ "dev": true, "license": "MIT" }, - "node_modules/big.js": { - "version": "5.2.2", - "dev": true, - "license": "MIT", - "engines": { - "node": "*" - } - }, "node_modules/binary-extensions": { "version": "2.2.0", "dev": true, @@ -1350,14 +1341,6 @@ "dev": true, "license": "MIT" }, - "node_modules/emojis-list": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, "node_modules/encodeurl": { "version": "1.0.2", "dev": true, @@ -2308,17 +2291,6 @@ "dev": true, "license": "MIT" }, - "node_modules/json5": { - "version": "1.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" - } - }, "node_modules/kind-of": { "version": "6.0.3", "dev": true, @@ -2344,19 +2316,6 @@ "node": ">=6.11.5" } }, - "node_modules/loader-utils": { - "version": "1.4.2", - "dev": true, - "license": "MIT", - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - }, - "engines": { - "node": ">=4.0.0" - } - }, "node_modules/locate-path": { "version": "5.0.0", "dev": true, @@ -2506,14 +2465,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/minimist": { - "version": "1.2.8", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/minipass": { "version": "7.0.4", "dev": true, @@ -2625,14 +2576,6 @@ "url": "https://github.com/fb55/nth-check?sponsor=1" } }, - "node_modules/object-assign": { - "version": "4.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/object-inspect": { "version": "1.13.1", "dev": true, @@ -3439,11 +3382,6 @@ "dev": true, "license": "ISC" }, - "node_modules/simple-html-tokenizer": { - "version": "0.1.1", - "dev": true, - "license": "MIT" - }, "node_modules/sockjs": { "version": "0.3.24", "dev": true, @@ -3697,16 +3635,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/svg-inline-loader": { - "version": "0.8.2", - "dev": true, - "license": "MIT", - "dependencies": { - "loader-utils": "^1.1.0", - "object-assign": "^4.0.1", - "simple-html-tokenizer": "^0.1.1" - } - }, "node_modules/tapable": { "version": "2.2.1", "dev": true, diff --git a/examples/webpack/webpack-project-built/package.json b/examples/webpack/webpack-project-built/package.json index 8daf28813b..a56db8a6ec 100644 --- a/examples/webpack/webpack-project-built/package.json +++ b/examples/webpack/webpack-project-built/package.json @@ -20,7 +20,6 @@ "css-loader": "^7.1.2", "html-webpack-plugin": "^5.6.0", "style-loader": "^4.0.0", - "svg-inline-loader": "^0.8.2", "webpack": "^5.93.0", "webpack-cli": "^5.1.4", "webpack-dev-server": "^5.0.4" diff --git a/examples/webpack/webpack-project-source/package-lock.json b/examples/webpack/webpack-project-source/package-lock.json index 307be77270..4f42245835 100644 --- a/examples/webpack/webpack-project-source/package-lock.json +++ b/examples/webpack/webpack-project-source/package-lock.json @@ -16,65 +16,73 @@ "esbuild-loader": "^4.2.2", "html-webpack-plugin": "^5.6.0", "style-loader": "^4.0.0", - "svg-inline-loader": "^0.8.2", "webpack": "^5.93.0", "webpack-cli": "^5.1.4", "webpack-dev-server": "^5.0.4" } }, "../../..": { - "name": "neuroglancer", "version": "2.40.1", "license": "Apache-2.0", "dependencies": { "codemirror": "^5.61.1", + "core-js": "^3.40.0", + "crc-32": "^1.2.2", "gl-matrix": "3.1.0", - "glsl-editor": "^1.0.0", "ikonate": "github:mikolajdobrucki/ikonate#a86b4107c6ec717e7877f880a930d1ccf0b59d89", "lodash-es": "^4.17.21", "nifti-reader-js": "^0.6.8", - "numcodecs": "^0.3.1", - "pako": "^2.1.0" + "numcodecs": "^0.3.2" }, "devDependencies": { + "@eslint/js": "^9.18.0", + "@iodigital/vite-plugin-msw": "^2.0.0", + "@playwright/browser-chromium": "^1.49.1", + "@rspack/cli": "^1.1.8", + "@rspack/core": "^1.1.8", "@types/codemirror": "5.60.15", "@types/gl-matrix": "^2.4.5", + "@types/http-server": "^0.12.4", + "@types/jsdom": "^21.1.7", "@types/lodash-es": "^4.17.12", - "@types/node": "^20.14.12", - "@types/pako": "^2.0.3", - "@types/yargs": "^17.0.32", - "@typescript-eslint/eslint-plugin": "^7.17.0", - "@typescript-eslint/parser": "^7.17.0", - "@vitest/browser": "^2.0.4", - "@vitest/ui": "^2.0.4", + "@types/node": "^22.10.7", + "@types/nunjucks": "^3.2.6", + "@types/s3rver": "^3.7.4", + "@types/yargs": "^17.0.33", + "@vitest/browser": "^3.0.2", + "@vitest/ui": "^3.0.2", + "@vitest/web-worker": "^3.0.2", + "cookie": "^1.0.2", "css-loader": "^7.1.2", - "esbuild": "^0.23.0", - "esbuild-loader": "^4.2.2", - "eslint": "^8.56.0", + "esbuild": "^0.24.2", + "eslint": "^9.18.0", "eslint-formatter-codeframe": "^7.32.1", - "eslint-import-resolver-typescript": "^3.6.1", - "eslint-interactive": "^10.8.0", - "eslint-plugin-import": "^2.29.1", - "eslint-webpack-plugin": "^4.0.1", - "fork-ts-checker-webpack-plugin": "^6.5.3", - "glob": "^11.0.0", - "html-webpack-plugin": "^5.6.0", - "mini-css-extract-plugin": "^2.9.0", - "prettier": "3.3.3", - "style-loader": "^4.0.0", - "svg-inline-loader": "^0.8.2", - "tsx": "^4.16.2", - "typescript": "^5.5.4", - "vitest": "^2.0.4", - "webdriverio": "^8.39.1", - "webpack": "^5.93.0", + "eslint-import-resolver-typescript": "^3.7.0", + "eslint-plugin-import": "^2.31.0", + "eslint-plugin-oxlint": "^0.15.7", + "eslint-rspack-plugin": "^4.2.1", + "express": "^4.21.2", + "glob": "^11.0.1", + "http-server": "^14.1.1", + "jsdom": "^26.0.0", + "msw": "^2.7.0", + "nunjucks": "^3.2.4", + "oxlint": "^0.15.7", + "playwright": "^1.49.1", + "prettier": "3.4.2", + "s3rver": "^3.7.1", + "ts-checker-rspack-plugin": "^1.1.1", + "tsx": "^4.19.2", + "typescript": "^5.7.3", + "typescript-eslint": "^8.20.0", + "vitest": "^3.0.2", "webpack-bundle-analyzer": "^4.10.2", - "webpack-cli": "^5.1.4", - "webpack-dev-server": "^5.0.4", - "webpack-merge": "^6.0.1" + "webpack-merge": "^6.0.1", + "yargs": "^17.7.2", + "yauzl": "^3.2.0" }, "engines": { - "node": ">=20.10 <21 || >=21.2" + "node": ">=22" } }, "../../../node_modules/@aashutoshrathi/word-wrap": { @@ -85,99 +93,6 @@ "node": ">=0.10.0" } }, - "../../../node_modules/@babel/code-frame": { - "version": "7.12.11", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/highlight": "^7.10.4" - } - }, - "../../../node_modules/@babel/helper-validator-identifier": { - "version": "7.22.20", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "../../../node_modules/@babel/highlight": { - "version": "7.23.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-validator-identifier": "^7.22.20", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "../../../node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "../../../node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "../../../node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "1.1.3" - } - }, - "../../../node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/@babel/highlight/node_modules/escape-string-regexp": { - "version": "1.0.5", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, - "../../../node_modules/@babel/highlight/node_modules/has-flag": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "../../../node_modules/@babel/highlight/node_modules/supports-color": { - "version": "5.5.0", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, "../../../node_modules/@discoveryjs/json-ext": { "version": "0.5.7", "dev": true, @@ -724,26 +639,12 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "../../../node_modules/@jest/types": { - "version": "29.6.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/schemas": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, "../../../node_modules/@jridgewell/gen-mapping": { "version": "0.3.5", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -757,6 +658,8 @@ "version": "3.1.2", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=6.0.0" } @@ -765,6 +668,8 @@ "version": "1.2.1", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=6.0.0" } @@ -773,6 +678,8 @@ "version": "0.3.5", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@jridgewell/gen-mapping": "^0.3.0", "@jridgewell/trace-mapping": "^0.3.9" @@ -787,16 +694,13 @@ "version": "0.3.25", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "../../../node_modules/@leichtgewicht/ip-codec": { - "version": "2.0.4", - "dev": true, - "license": "MIT" - }, "../../../node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "dev": true, @@ -850,6 +754,8 @@ "version": "2.0.1", "dev": true, "license": "Apache-2.0", + "optional": true, + "peer": true, "dependencies": { "debug": "4.3.4", "extract-zip": "2.0.1", @@ -1083,6 +989,8 @@ "version": "5.6.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=14.16" }, @@ -1094,6 +1002,8 @@ "version": "5.0.1", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "defer-to-connect": "^2.0.1" }, @@ -1105,8 +1015,6 @@ "version": "1.1.2", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "engines": { "node": ">= 6" } @@ -1114,24 +1022,9 @@ "../../../node_modules/@tootallnate/quickjs-emscripten": { "version": "0.23.0", "dev": true, - "license": "MIT" - }, - "../../../node_modules/@types/body-parser": { - "version": "1.19.5", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/connect": "*", - "@types/node": "*" - } - }, - "../../../node_modules/@types/bonjour": { - "version": "3.5.13", - "dev": true, "license": "MIT", - "dependencies": { - "@types/node": "*" - } + "optional": true, + "peer": true }, "../../../node_modules/@types/codemirror": { "version": "5.60.15", @@ -1141,27 +1034,12 @@ "@types/tern": "*" } }, - "../../../node_modules/@types/connect": { - "version": "3.4.38", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "../../../node_modules/@types/connect-history-api-fallback": { - "version": "1.5.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/express-serve-static-core": "*", - "@types/node": "*" - } - }, "../../../node_modules/@types/eslint": { "version": "8.56.5", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@types/estree": "*", "@types/json-schema": "*" @@ -1171,6 +1049,8 @@ "version": "3.7.7", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@types/eslint": "*", "@types/estree": "*" @@ -1181,81 +1061,24 @@ "dev": true, "license": "MIT" }, - "../../../node_modules/@types/express": { - "version": "4.17.21", - "dev": true, - "license": "MIT", - "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.17.43", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*", - "@types/send": "*" - } - }, "../../../node_modules/@types/gl-matrix": { "version": "2.4.5", "dev": true, "license": "MIT" }, - "../../../node_modules/@types/html-minifier-terser": { - "version": "6.1.0", - "dev": true, - "license": "MIT" - }, "../../../node_modules/@types/http-cache-semantics": { "version": "4.0.4", "dev": true, - "license": "MIT" - }, - "../../../node_modules/@types/http-errors": { - "version": "2.0.4", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/@types/http-proxy": { - "version": "1.17.14", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "../../../node_modules/@types/istanbul-lib-coverage": { - "version": "2.0.6", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/@types/istanbul-lib-report": { - "version": "3.0.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-coverage": "*" - } - }, - "../../../node_modules/@types/istanbul-reports": { - "version": "3.0.4", - "dev": true, "license": "MIT", - "dependencies": { - "@types/istanbul-lib-report": "*" - } + "optional": true, + "peer": true }, "../../../node_modules/@types/json-schema": { "version": "7.0.15", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/@types/json5": { "version": "0.0.29", @@ -1275,11 +1098,6 @@ "@types/lodash": "*" } }, - "../../../node_modules/@types/mime": { - "version": "1.3.5", - "dev": true, - "license": "MIT" - }, "../../../node_modules/@types/node": { "version": "20.11.20", "dev": true, @@ -1288,304 +1106,54 @@ "undici-types": "~5.26.4" } }, - "../../../node_modules/@types/node-forge": { - "version": "1.3.11", + "../../../node_modules/@types/tern": { + "version": "0.23.9", "dev": true, "license": "MIT", "dependencies": { - "@types/node": "*" + "@types/estree": "*" } }, - "../../../node_modules/@types/pako": { - "version": "2.0.3", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/@types/parse-json": { - "version": "4.0.2", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/@types/qs": { - "version": "6.9.12", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/@types/range-parser": { - "version": "1.2.7", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/@types/retry": { - "version": "0.12.2", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/@types/semver": { - "version": "7.5.7", + "../../../node_modules/@types/which": { + "version": "2.0.2", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, - "../../../node_modules/@types/send": { - "version": "0.17.4", + "../../../node_modules/@types/ws": { + "version": "8.5.10", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { - "@types/mime": "^1", "@types/node": "*" } }, - "../../../node_modules/@types/serve-index": { - "version": "1.9.4", + "../../../node_modules/@types/yargs": { + "version": "17.0.32", "dev": true, "license": "MIT", "dependencies": { - "@types/express": "*" + "@types/yargs-parser": "*" } }, - "../../../node_modules/@types/serve-static": { - "version": "1.15.5", + "../../../node_modules/@types/yargs-parser": { + "version": "21.0.3", "dev": true, - "license": "MIT", - "dependencies": { - "@types/http-errors": "*", - "@types/mime": "*", - "@types/node": "*" - } + "license": "MIT" }, - "../../../node_modules/@types/sockjs": { - "version": "0.3.36", + "../../../node_modules/@types/yauzl": { + "version": "2.10.3", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@types/node": "*" } }, - "../../../node_modules/@types/tern": { - "version": "0.23.9", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/estree": "*" - } - }, - "../../../node_modules/@types/which": { - "version": "2.0.2", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/@types/ws": { - "version": "8.5.10", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "../../../node_modules/@types/yargs": { - "version": "17.0.32", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "../../../node_modules/@types/yargs-parser": { - "version": "21.0.3", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/@types/yauzl": { - "version": "2.10.3", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@types/node": "*" - } - }, - "../../../node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "7.0.2", - "@typescript-eslint/type-utils": "7.0.2", - "@typescript-eslint/utils": "7.0.2", - "@typescript-eslint/visitor-keys": "7.0.2", - "debug": "^4.3.4", - "graphemer": "^1.4.0", - "ignore": "^5.2.4", - "natural-compare": "^1.4.0", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^7.0.0", - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "../../../node_modules/@typescript-eslint/parser": { - "version": "7.0.2", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "@typescript-eslint/scope-manager": "7.0.2", - "@typescript-eslint/types": "7.0.2", - "@typescript-eslint/typescript-estree": "7.0.2", - "@typescript-eslint/visitor-keys": "7.0.2", - "debug": "^4.3.4" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "../../../node_modules/@typescript-eslint/scope-manager": { - "version": "7.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "7.0.2", - "@typescript-eslint/visitor-keys": "7.0.2" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "../../../node_modules/@typescript-eslint/type-utils": { - "version": "7.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/typescript-estree": "7.0.2", - "@typescript-eslint/utils": "7.0.2", - "debug": "^4.3.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "../../../node_modules/@typescript-eslint/types": { - "version": "7.0.2", - "dev": true, - "license": "MIT", - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "../../../node_modules/@typescript-eslint/typescript-estree": { - "version": "7.0.2", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "@typescript-eslint/types": "7.0.2", - "@typescript-eslint/visitor-keys": "7.0.2", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "9.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "../../../node_modules/@typescript-eslint/utils": { - "version": "7.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@types/json-schema": "^7.0.12", - "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "7.0.2", - "@typescript-eslint/types": "7.0.2", - "@typescript-eslint/typescript-estree": "7.0.2", - "semver": "^7.5.4" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - } - }, - "../../../node_modules/@typescript-eslint/visitor-keys": { - "version": "7.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "7.0.2", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, "../../../node_modules/@ungap/structured-clone": { "version": "1.2.0", "dev": true, @@ -1741,6 +1309,8 @@ "version": "8.32.3", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@wdio/logger": "8.28.0", "@wdio/types": "8.32.2", @@ -1758,6 +1328,8 @@ "version": "8.28.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "chalk": "^5.1.2", "loglevel": "^1.6.0", @@ -1772,6 +1344,8 @@ "version": "6.0.1", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=12" }, @@ -1783,6 +1357,8 @@ "version": "5.3.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": "^12.17.0 || ^14.13 || >=16.0.0" }, @@ -1794,6 +1370,8 @@ "version": "7.1.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "ansi-regex": "^6.0.1" }, @@ -1807,12 +1385,16 @@ "../../../node_modules/@wdio/protocols": { "version": "8.32.0", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/@wdio/repl": { "version": "8.24.12", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@types/node": "^20.1.0" }, @@ -1824,6 +1406,8 @@ "version": "8.32.2", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@types/node": "^20.1.0" }, @@ -1835,6 +1419,8 @@ "version": "8.32.3", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@puppeteer/browsers": "^1.6.0", "@wdio/logger": "8.28.0", @@ -1858,6 +1444,8 @@ "version": "1.11.6", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@webassemblyjs/helper-numbers": "1.11.6", "@webassemblyjs/helper-wasm-bytecode": "1.11.6" @@ -1866,22 +1454,30 @@ "../../../node_modules/@webassemblyjs/floating-point-hex-parser": { "version": "1.11.6", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/@webassemblyjs/helper-api-error": { "version": "1.11.6", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/@webassemblyjs/helper-buffer": { "version": "1.11.6", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/@webassemblyjs/helper-numbers": { "version": "1.11.6", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@webassemblyjs/floating-point-hex-parser": "1.11.6", "@webassemblyjs/helper-api-error": "1.11.6", @@ -1891,12 +1487,16 @@ "../../../node_modules/@webassemblyjs/helper-wasm-bytecode": { "version": "1.11.6", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/@webassemblyjs/helper-wasm-section": { "version": "1.11.6", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@webassemblyjs/ast": "1.11.6", "@webassemblyjs/helper-buffer": "1.11.6", @@ -1908,6 +1508,8 @@ "version": "1.11.6", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@xtuc/ieee754": "^1.2.0" } @@ -1916,6 +1518,8 @@ "version": "1.11.6", "dev": true, "license": "Apache-2.0", + "optional": true, + "peer": true, "dependencies": { "@xtuc/long": "4.2.2" } @@ -1923,12 +1527,16 @@ "../../../node_modules/@webassemblyjs/utf8": { "version": "1.11.6", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/@webassemblyjs/wasm-edit": { "version": "1.11.6", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@webassemblyjs/ast": "1.11.6", "@webassemblyjs/helper-buffer": "1.11.6", @@ -1944,6 +1552,8 @@ "version": "1.11.6", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@webassemblyjs/ast": "1.11.6", "@webassemblyjs/helper-wasm-bytecode": "1.11.6", @@ -1956,6 +1566,8 @@ "version": "1.11.6", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@webassemblyjs/ast": "1.11.6", "@webassemblyjs/helper-buffer": "1.11.6", @@ -1967,6 +1579,8 @@ "version": "1.11.6", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@webassemblyjs/ast": "1.11.6", "@webassemblyjs/helper-api-error": "1.11.6", @@ -1980,69 +1594,32 @@ "version": "1.11.6", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@webassemblyjs/ast": "1.11.6", "@xtuc/long": "4.2.2" } }, - "../../../node_modules/@webpack-cli/configtest": { - "version": "2.1.1", + "../../../node_modules/@xtuc/ieee754": { + "version": "1.2.0", "dev": true, - "license": "MIT", - "engines": { - "node": ">=14.15.0" - }, - "peerDependencies": { - "webpack": "5.x.x", - "webpack-cli": "5.x.x" - } + "license": "BSD-3-Clause", + "optional": true, + "peer": true }, - "../../../node_modules/@webpack-cli/info": { - "version": "2.0.2", + "../../../node_modules/@xtuc/long": { + "version": "4.2.2", "dev": true, - "license": "MIT", - "engines": { - "node": ">=14.15.0" - }, - "peerDependencies": { - "webpack": "5.x.x", - "webpack-cli": "5.x.x" - } + "license": "Apache-2.0", + "optional": true, + "peer": true }, - "../../../node_modules/@webpack-cli/serve": { - "version": "2.0.5", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14.15.0" - }, - "peerDependencies": { - "webpack": "5.x.x", - "webpack-cli": "5.x.x" - }, - "peerDependenciesMeta": { - "webpack-dev-server": { - "optional": true - } - } - }, - "../../../node_modules/@xtuc/ieee754": { - "version": "1.2.0", + "../../../node_modules/abab": { + "version": "2.0.6", "dev": true, "license": "BSD-3-Clause" }, - "../../../node_modules/@xtuc/long": { - "version": "4.2.2", - "dev": true, - "license": "Apache-2.0" - }, - "../../../node_modules/abab": { - "version": "2.0.6", - "dev": true, - "license": "BSD-3-Clause", - "optional": true, - "peer": true - }, "../../../node_modules/abbrev": { "version": "2.0.0", "license": "ISC", @@ -2050,18 +1627,6 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "../../../node_modules/accepts": { - "version": "1.3.8", - "dev": true, - "license": "MIT", - "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - }, - "engines": { - "node": ">= 0.6" - } - }, "../../../node_modules/acorn": { "version": "8.11.3", "dev": true, @@ -2077,8 +1642,6 @@ "version": "6.0.0", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "dependencies": { "acorn": "^7.1.1", "acorn-walk": "^7.1.1" @@ -2088,8 +1651,6 @@ "version": "7.4.1", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -2101,6 +1662,8 @@ "version": "1.9.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "peerDependencies": { "acorn": "^8" } @@ -2117,8 +1680,6 @@ "version": "7.2.0", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "engines": { "node": ">=0.4.0" } @@ -2127,8 +1688,6 @@ "version": "6.0.2", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "dependencies": { "debug": "4" }, @@ -2150,120 +1709,16 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "../../../node_modules/ajv-formats": { - "version": "2.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } - } - }, - "../../../node_modules/ajv-formats/node_modules/ajv": { - "version": "8.12.0", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "../../../node_modules/ajv-formats/node_modules/json-schema-traverse": { - "version": "1.0.0", - "dev": true, - "license": "MIT" - }, "../../../node_modules/ajv-keywords": { "version": "3.5.2", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "peerDependencies": { "ajv": "^6.9.1" } }, - "../../../node_modules/ansi-align": { - "version": "3.0.1", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^4.1.0" - } - }, - "../../../node_modules/ansi-align/node_modules/emoji-regex": { - "version": "8.0.0", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/ansi-align/node_modules/string-width": { - "version": "4.2.3", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "../../../node_modules/ansi-colors": { - "version": "4.1.3", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "../../../node_modules/ansi-escapes": { - "version": "5.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "type-fest": "^1.0.2" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/ansi-escapes/node_modules/type-fest": { - "version": "1.4.0", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/ansi-html-community": { - "version": "0.0.8", - "dev": true, - "engines": [ - "node >= 0.8.0" - ], - "license": "Apache-2.0", - "bin": { - "ansi-html": "bin/ansi-html" - } - }, "../../../node_modules/ansi-regex": { "version": "5.0.1", "license": "MIT", @@ -2284,22 +1739,12 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "../../../node_modules/anymatch": { - "version": "3.1.3", - "dev": true, - "license": "ISC", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, "../../../node_modules/archiver": { "version": "6.0.1", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "archiver-utils": "^4.0.1", "async": "^3.2.4", @@ -2317,6 +1762,8 @@ "version": "4.0.1", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "glob": "^8.0.0", "graceful-fs": "^4.2.0", @@ -2333,6 +1780,8 @@ "version": "8.1.0", "dev": true, "license": "ISC", + "optional": true, + "peer": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -2351,6 +1800,8 @@ "version": "5.1.6", "dev": true, "license": "ISC", + "optional": true, + "peer": true, "dependencies": { "brace-expansion": "^2.0.1" }, @@ -2362,6 +1813,8 @@ "version": "3.6.2", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -2375,6 +1828,8 @@ "version": "3.6.2", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -2393,6 +1848,8 @@ "version": "5.3.0", "dev": true, "license": "Apache-2.0", + "optional": true, + "peer": true, "dependencies": { "dequal": "^2.0.3" } @@ -2416,11 +1873,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "../../../node_modules/array-flatten": { - "version": "1.1.1", - "dev": true, - "license": "MIT" - }, "../../../node_modules/array-includes": { "version": "3.1.7", "dev": true, @@ -2439,14 +1891,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "../../../node_modules/array-union": { - "version": "2.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "../../../node_modules/array.prototype.findlastindex": { "version": "1.2.3", "dev": true, @@ -2545,6 +1989,8 @@ "version": "0.13.4", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "tslib": "^2.0.1" }, @@ -2552,18 +1998,12 @@ "node": ">=4" } }, - "../../../node_modules/astral-regex": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "../../../node_modules/async": { "version": "3.2.5", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/async-limiter": { "version": "1.0.1", @@ -2573,14 +2013,6 @@ "version": "0.4.0", "license": "MIT" }, - "../../../node_modules/at-least-node": { - "version": "1.0.0", - "dev": true, - "license": "ISC", - "engines": { - "node": ">= 4.0.0" - } - }, "../../../node_modules/available-typed-arrays": { "version": "1.0.5", "dev": true, @@ -2606,7 +2038,9 @@ "../../../node_modules/b4a": { "version": "1.6.4", "dev": true, - "license": "ISC" + "license": "ISC", + "optional": true, + "peer": true }, "../../../node_modules/balanced-match": { "version": "1.0.2", @@ -2616,13 +2050,15 @@ "version": "2.2.0", "dev": true, "license": "Apache-2.0", - "optional": true + "optional": true, + "peer": true }, "../../../node_modules/bare-fs": { "version": "2.1.5", "dev": true, "license": "Apache-2.0", "optional": true, + "peer": true, "dependencies": { "bare-events": "^2.0.0", "bare-os": "^2.0.0", @@ -2634,13 +2070,15 @@ "version": "2.2.0", "dev": true, "license": "Apache-2.0", - "optional": true + "optional": true, + "peer": true }, "../../../node_modules/bare-path": { "version": "2.1.0", "dev": true, "license": "Apache-2.0", "optional": true, + "peer": true, "dependencies": { "bare-os": "^2.1.0" } @@ -2662,21 +2100,20 @@ "url": "https://feross.org/support" } ], - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/basic-ftp": { "version": "5.0.4", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=10.0.0" } }, - "../../../node_modules/batch": { - "version": "0.6.1", - "dev": true, - "license": "MIT" - }, "../../../node_modules/bcrypt-pbkdf": { "version": "1.0.2", "license": "BSD-3-Clause", @@ -2688,204 +2125,46 @@ "version": "1.6.52", "dev": true, "license": "Unlicense", + "optional": true, + "peer": true, "engines": { "node": ">=0.6" } }, - "../../../node_modules/big.js": { - "version": "5.2.2", - "dev": true, - "license": "MIT", - "engines": { - "node": "*" - } - }, "../../../node_modules/binary": { "version": "0.3.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "buffers": "~0.1.1", "chainsaw": "~0.1.0" } }, - "../../../node_modules/binary-extensions": { - "version": "2.2.0", + "../../../node_modules/bluebird": { + "version": "3.4.7", "dev": true, "license": "MIT", - "engines": { - "node": ">=8" - } + "optional": true, + "peer": true }, - "../../../node_modules/bl": { - "version": "5.1.0", - "dev": true, + "../../../node_modules/brace-expansion": { + "version": "2.0.1", "license": "MIT", "dependencies": { - "buffer": "^6.0.3", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" + "balanced-match": "^1.0.0" } }, - "../../../node_modules/bl/node_modules/readable-stream": { - "version": "3.6.2", + "../../../node_modules/braces": { + "version": "3.0.2", "dev": true, "license": "MIT", "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" + "fill-range": "^7.0.1" }, "engines": { - "node": ">= 6" - } - }, - "../../../node_modules/bluebird": { - "version": "3.4.7", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/body-parser": { - "version": "1.20.2", - "dev": true, - "license": "MIT", - "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.11.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/bytes": { - "version": "3.1.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "../../../node_modules/body-parser/node_modules/debug": { - "version": "2.6.9", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "../../../node_modules/body-parser/node_modules/ms": { - "version": "2.0.0", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/body-parser/node_modules/qs": { - "version": "6.11.0", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "../../../node_modules/bonjour-service": { - "version": "1.2.1", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "multicast-dns": "^7.2.5" - } - }, - "../../../node_modules/boolbase": { - "version": "1.0.0", - "dev": true, - "license": "ISC" - }, - "../../../node_modules/boxen": { - "version": "7.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-align": "^3.0.1", - "camelcase": "^7.0.1", - "chalk": "^5.2.0", - "cli-boxes": "^3.0.0", - "string-width": "^5.1.2", - "type-fest": "^2.13.0", - "widest-line": "^4.0.1", - "wrap-ansi": "^8.1.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/boxen/node_modules/chalk": { - "version": "5.3.0", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "../../../node_modules/brace-expansion": { - "version": "2.0.1", - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "../../../node_modules/braces": { - "version": "3.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "../../../node_modules/brfs": { - "version": "1.6.1", - "license": "MIT", - "dependencies": { - "quote-stream": "^1.0.1", - "resolve": "^1.1.5", - "static-module": "^2.2.0", - "through2": "^2.0.0" - }, - "bin": { - "brfs": "bin/cmd.js" - } - }, - "../../../node_modules/brfs/node_modules/through2": { - "version": "2.0.5", - "license": "MIT", - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" + "node": ">=8" } }, "../../../node_modules/browser-process-hrtime": { @@ -2910,6 +2189,8 @@ } ], "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "caniuse-lite": "^1.0.30001587", "electron-to-chromium": "^1.4.668", @@ -2923,29 +2204,6 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "../../../node_modules/buffer": { - "version": "6.0.3", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, "../../../node_modules/buffer-crc32": { "version": "0.2.13", "dev": true, @@ -2954,21 +2212,19 @@ "node": "*" } }, - "../../../node_modules/buffer-equal": { - "version": "0.0.1", - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, "../../../node_modules/buffer-from": { "version": "1.1.2", - "license": "MIT" + "dev": true, + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/buffer-indexof-polyfill": { "version": "1.0.2", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=0.10" } @@ -2976,32 +2232,12 @@ "../../../node_modules/buffers": { "version": "0.1.1", "dev": true, + "optional": true, + "peer": true, "engines": { "node": ">=0.2.0" } }, - "../../../node_modules/bundle-name": { - "version": "4.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "run-applescript": "^7.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/bytes": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, "../../../node_modules/cac": { "version": "6.7.14", "dev": true, @@ -3014,6 +2250,8 @@ "version": "7.0.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=14.16" } @@ -3022,6 +2260,8 @@ "version": "10.2.14", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@types/http-cache-semantics": "^4.0.2", "get-stream": "^6.0.1", @@ -3039,6 +2279,8 @@ "version": "6.0.1", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=10" }, @@ -3067,26 +2309,6 @@ "node": ">=6" } }, - "../../../node_modules/camel-case": { - "version": "4.1.2", - "dev": true, - "license": "MIT", - "dependencies": { - "pascal-case": "^3.1.2", - "tslib": "^2.0.3" - } - }, - "../../../node_modules/camelcase": { - "version": "7.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "../../../node_modules/caniuse-lite": { "version": "1.0.30001596", "dev": true, @@ -3104,7 +2326,9 @@ "url": "https://github.com/sponsors/ai" } ], - "license": "CC-BY-4.0" + "license": "CC-BY-4.0", + "optional": true, + "peer": true }, "../../../node_modules/caseless": { "version": "0.12.0", @@ -3131,6 +2355,8 @@ "version": "0.1.0", "dev": true, "license": "MIT/X11", + "optional": true, + "peer": true, "dependencies": { "traverse": ">=0.3.0 <0.4" } @@ -3161,44 +2387,12 @@ "node": "*" } }, - "../../../node_modules/chokidar": { - "version": "3.6.0", - "dev": true, - "license": "MIT", - "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" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "../../../node_modules/chokidar/node_modules/glob-parent": { - "version": "5.1.2", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "../../../node_modules/chrome-trace-event": { "version": "1.0.3", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=6.0" } @@ -3207,6 +2401,8 @@ "version": "0.4.16", "dev": true, "license": "Apache-2.0", + "optional": true, + "peer": true, "dependencies": { "mitt": "3.0.0" }, @@ -3214,69 +2410,8 @@ "devtools-protocol": "*" } }, - "../../../node_modules/ci-info": { - "version": "3.9.0", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "../../../node_modules/clean-css": { - "version": "5.3.3", - "dev": true, - "license": "MIT", - "dependencies": { - "source-map": "~0.6.0" - }, - "engines": { - "node": ">= 10.0" - } - }, - "../../../node_modules/cli-boxes": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/cli-cursor": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "restore-cursor": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/cli-spinners": { - "version": "2.9.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/cliui": { - "version": "8.0.1", + "../../../node_modules/cliui": { + "version": "8.0.1", "dev": true, "license": "ISC", "dependencies": { @@ -3361,11 +2496,6 @@ "version": "1.1.4", "license": "MIT" }, - "../../../node_modules/colorette": { - "version": "2.0.20", - "dev": true, - "license": "MIT" - }, "../../../node_modules/combined-stream": { "version": "1.0.8", "license": "MIT", @@ -3376,28 +2506,22 @@ "node": ">= 0.8" } }, - "../../../node_modules/comlink": { - "version": "4.4.1", - "dev": true, - "license": "Apache-2.0" - }, "../../../node_modules/commander": { "version": "9.5.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": "^12.20.0 || >=14" } }, - "../../../node_modules/common-path-prefix": { - "version": "3.0.0", - "dev": true, - "license": "ISC" - }, "../../../node_modules/compress-commons": { "version": "5.0.1", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "crc-32": "^1.2.0", "crc32-stream": "^5.0.0", @@ -3412,6 +2536,8 @@ "version": "3.6.2", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -3421,70 +2547,11 @@ "node": ">= 6" } }, - "../../../node_modules/compressible": { - "version": "2.0.18", - "dev": true, - "license": "MIT", - "dependencies": { - "mime-db": ">= 1.43.0 < 2" - }, - "engines": { - "node": ">= 0.6" - } - }, - "../../../node_modules/compression": { - "version": "1.7.4", - "dev": true, - "license": "MIT", - "dependencies": { - "accepts": "~1.3.5", - "bytes": "3.0.0", - "compressible": "~2.0.16", - "debug": "2.6.9", - "on-headers": "~1.0.2", - "safe-buffer": "5.1.2", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "../../../node_modules/compression/node_modules/debug": { - "version": "2.6.9", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "../../../node_modules/compression/node_modules/ms": { - "version": "2.0.0", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/compression/node_modules/safe-buffer": { - "version": "5.1.2", - "dev": true, - "license": "MIT" - }, "../../../node_modules/concat-map": { "version": "0.0.1", "dev": true, "license": "MIT" }, - "../../../node_modules/concat-stream": { - "version": "1.6.2", - "engines": [ - "node >= 0.8" - ], - "license": "MIT", - "dependencies": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, "../../../node_modules/condense-newlines": { "version": "0.2.1", "license": "MIT", @@ -3509,73 +2576,15 @@ "version": "1.3.8", "license": "ISC" }, - "../../../node_modules/connect-history-api-fallback": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8" - } - }, - "../../../node_modules/content-disposition": { - "version": "0.5.4", - "dev": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "5.2.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "../../../node_modules/content-type": { - "version": "1.0.5", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "../../../node_modules/convert-source-map": { - "version": "1.9.0", - "license": "MIT" - }, - "../../../node_modules/cookie": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "../../../node_modules/cookie-signature": { - "version": "1.0.6", - "dev": true, - "license": "MIT" - }, "../../../node_modules/core-util-is": { "version": "1.0.3", - "license": "MIT" - }, - "../../../node_modules/cosmiconfig": { - "version": "6.0.0", "dev": true, "license": "MIT", - "dependencies": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.1.0", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.7.2" - }, - "engines": { - "node": ">=8" - } + "optional": true, + "peer": true }, "../../../node_modules/crc-32": { "version": "1.2.2", - "dev": true, "license": "Apache-2.0", "bin": { "crc32": "bin/crc32.njs" @@ -3588,6 +2597,8 @@ "version": "5.0.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "crc-32": "^1.2.0", "readable-stream": "^3.4.0" @@ -3600,6 +2611,8 @@ "version": "3.6.2", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -3613,6 +2626,8 @@ "version": "4.0.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "node-fetch": "^2.6.12" } @@ -3621,6 +2636,8 @@ "version": "2.7.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "whatwg-url": "^5.0.0" }, @@ -3639,17 +2656,23 @@ "../../../node_modules/cross-fetch/node_modules/tr46": { "version": "0.0.3", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/cross-fetch/node_modules/webidl-conversions": { "version": "3.0.1", "dev": true, - "license": "BSD-2-Clause" + "license": "BSD-2-Clause", + "optional": true, + "peer": true }, "../../../node_modules/cross-fetch/node_modules/whatwg-url": { "version": "5.0.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" @@ -3701,39 +2724,17 @@ } } }, - "../../../node_modules/css-select": { - "version": "4.3.0", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^6.0.1", - "domhandler": "^4.3.1", - "domutils": "^2.8.0", - "nth-check": "^2.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, "../../../node_modules/css-shorthand-properties": { "version": "1.1.1", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "../../../node_modules/css-value": { "version": "0.0.1", - "dev": true - }, - "../../../node_modules/css-what": { - "version": "6.1.0", "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">= 6" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } + "optional": true, + "peer": true }, "../../../node_modules/cssesc": { "version": "3.0.0", @@ -3749,16 +2750,12 @@ "../../../node_modules/cssom": { "version": "0.5.0", "dev": true, - "license": "MIT", - "optional": true, - "peer": true + "license": "MIT" }, "../../../node_modules/cssstyle": { "version": "2.3.0", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "dependencies": { "cssom": "~0.3.6" }, @@ -3769,9 +2766,7 @@ "../../../node_modules/cssstyle/node_modules/cssom": { "version": "0.3.8", "dev": true, - "license": "MIT", - "optional": true, - "peer": true + "license": "MIT" }, "../../../node_modules/dashdash": { "version": "1.14.1", @@ -3787,6 +2782,8 @@ "version": "4.0.1", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">= 12" } @@ -3795,8 +2792,6 @@ "version": "3.0.2", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "dependencies": { "abab": "^2.0.6", "whatwg-mimetype": "^3.0.0", @@ -3810,8 +2805,6 @@ "version": "3.0.0", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "dependencies": { "punycode": "^2.1.1" }, @@ -3823,8 +2816,6 @@ "version": "7.0.0", "dev": true, "license": "BSD-2-Clause", - "optional": true, - "peer": true, "engines": { "node": ">=12" } @@ -3833,8 +2824,6 @@ "version": "3.0.0", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "engines": { "node": ">=12" } @@ -3843,8 +2832,6 @@ "version": "11.0.0", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "dependencies": { "tr46": "^3.0.0", "webidl-conversions": "^7.0.0" @@ -3878,6 +2865,8 @@ "version": "6.0.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, @@ -3888,14 +2877,14 @@ "../../../node_modules/decimal.js": { "version": "10.4.3", "dev": true, - "license": "MIT", - "optional": true, - "peer": true + "license": "MIT" }, "../../../node_modules/decompress-response": { "version": "6.0.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "mimic-response": "^3.1.0" }, @@ -3910,6 +2899,8 @@ "version": "3.1.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=10" }, @@ -3932,147 +2923,22 @@ "version": "0.1.4", "license": "MIT" }, - "../../../node_modules/deepmerge": { - "version": "4.3.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "../../../node_modules/deepmerge-ts": { "version": "5.1.0", "dev": true, "license": "BSD-3-Clause", + "optional": true, + "peer": true, "engines": { "node": ">=16.0.0" } }, - "../../../node_modules/default-browser": { - "version": "5.2.1", - "dev": true, - "license": "MIT", - "dependencies": { - "bundle-name": "^4.1.0", - "default-browser-id": "^5.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/default-browser-id": { - "version": "5.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/default-gateway": { - "version": "6.0.3", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "execa": "^5.0.0" - }, - "engines": { - "node": ">= 10" - } - }, - "../../../node_modules/default-gateway/node_modules/execa": { - "version": "5.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "../../../node_modules/default-gateway/node_modules/get-stream": { - "version": "6.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/default-gateway/node_modules/human-signals": { - "version": "2.1.0", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=10.17.0" - } - }, - "../../../node_modules/default-gateway/node_modules/is-stream": { - "version": "2.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/default-gateway/node_modules/signal-exit": { - "version": "3.0.7", - "dev": true, - "license": "ISC" - }, - "../../../node_modules/default-gateway/node_modules/strip-final-newline": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "../../../node_modules/defaults": { - "version": "1.0.4", - "dev": true, - "license": "MIT", - "dependencies": { - "clone": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/defaults/node_modules/clone": { - "version": "1.0.4", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8" - } - }, - "../../../node_modules/defer-to-connect": { - "version": "2.0.1", + "../../../node_modules/defer-to-connect": { + "version": "2.0.1", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=10" } @@ -4090,17 +2956,6 @@ "node": ">= 0.4" } }, - "../../../node_modules/define-lazy-prop": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "../../../node_modules/define-properties": { "version": "1.2.1", "dev": true, @@ -4121,6 +2976,8 @@ "version": "5.0.1", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "ast-types": "^0.13.4", "escodegen": "^2.1.0", @@ -4137,31 +2994,16 @@ "node": ">=0.4.0" } }, - "../../../node_modules/depd": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, "../../../node_modules/dequal": { "version": "2.0.3", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=6" } }, - "../../../node_modules/destroy": { - "version": "1.2.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, "../../../node_modules/detect-libc": { "version": "1.0.3", "dev": true, @@ -4175,15 +3017,12 @@ "node": ">=0.10" } }, - "../../../node_modules/detect-node": { - "version": "2.1.0", - "dev": true, - "license": "MIT" - }, "../../../node_modules/devtools-protocol": { "version": "0.0.1262051", "dev": true, - "license": "BSD-3-Clause" + "license": "BSD-3-Clause", + "optional": true, + "peer": true }, "../../../node_modules/diff-sequences": { "version": "29.6.3", @@ -4193,28 +3032,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "../../../node_modules/dir-glob": { - "version": "3.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "../../../node_modules/dns-packet": { - "version": "5.6.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@leichtgewicht/ip-codec": "^2.0.1" - }, - "engines": { - "node": ">=6" - } - }, "../../../node_modules/doctrine": { "version": "3.0.0", "dev": true, @@ -4226,44 +3043,10 @@ "node": ">=6.0.0" } }, - "../../../node_modules/dom-converter": { - "version": "0.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "utila": "~0.4" - } - }, - "../../../node_modules/dom-serializer": { - "version": "1.4.1", - "dev": true, - "license": "MIT", - "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.0", - "entities": "^2.0.0" - }, - "funding": { - "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" - } - }, - "../../../node_modules/domelementtype": { - "version": "2.3.0", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "license": "BSD-2-Clause" - }, "../../../node_modules/domexception": { "version": "2.0.1", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "dependencies": { "webidl-conversions": "^5.0.0" }, @@ -4275,48 +3058,10 @@ "version": "5.0.0", "dev": true, "license": "BSD-2-Clause", - "optional": true, - "peer": true, "engines": { "node": ">=8" } }, - "../../../node_modules/domhandler": { - "version": "4.3.1", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "domelementtype": "^2.2.0" - }, - "engines": { - "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" - } - }, - "../../../node_modules/domutils": { - "version": "2.8.0", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "dom-serializer": "^1.0.1", - "domelementtype": "^2.2.0", - "domhandler": "^4.2.0" - }, - "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" - } - }, - "../../../node_modules/dot-case": { - "version": "3.0.4", - "dev": true, - "license": "MIT", - "dependencies": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, "../../../node_modules/duplexer": { "version": "0.1.2", "dev": true, @@ -4324,7 +3069,10 @@ }, "../../../node_modules/duplexer2": { "version": "0.1.4", + "dev": true, "license": "BSD-3-Clause", + "optional": true, + "peer": true, "dependencies": { "readable-stream": "^2.0.2" } @@ -4345,6 +3093,8 @@ "version": "3.0.5", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@types/which": "^2.0.1", "which": "^2.0.2" @@ -4361,6 +3111,8 @@ "dev": true, "hasInstallScript": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@wdio/logger": "^8.28.0", "decamelize": "^6.0.0", @@ -4377,6 +3129,8 @@ "version": "3.1.1", "dev": true, "license": "ISC", + "optional": true, + "peer": true, "engines": { "node": ">=16" } @@ -4385,6 +3139,8 @@ "version": "4.0.0", "dev": true, "license": "ISC", + "optional": true, + "peer": true, "dependencies": { "isexe": "^3.1.1" }, @@ -4431,44 +3187,23 @@ "url": "https://github.com/sponsors/isaacs" } }, - "../../../node_modules/ee-first": { - "version": "1.1.1", - "dev": true, - "license": "MIT" - }, "../../../node_modules/electron-to-chromium": { "version": "1.4.699", "dev": true, - "license": "ISC" - }, - "../../../node_modules/element-size": { - "version": "1.1.1", - "license": "MIT" + "license": "ISC", + "optional": true, + "peer": true }, "../../../node_modules/emoji-regex": { "version": "9.2.2", "license": "MIT" }, - "../../../node_modules/emojis-list": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "../../../node_modules/encodeurl": { - "version": "1.0.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, "../../../node_modules/end-of-stream": { "version": "1.4.4", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "once": "^1.4.0" } @@ -4485,45 +3220,6 @@ "node": ">=10.13.0" } }, - "../../../node_modules/enquirer": { - "version": "2.4.1", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-colors": "^4.1.1", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "../../../node_modules/entities": { - "version": "2.2.0", - "dev": true, - "license": "BSD-2-Clause", - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "../../../node_modules/envinfo": { - "version": "7.11.1", - "dev": true, - "license": "MIT", - "bin": { - "envinfo": "dist/cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "../../../node_modules/error-ex": { - "version": "1.3.2", - "dev": true, - "license": "MIT", - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, "../../../node_modules/es-abstract": { "version": "1.22.3", "dev": true, @@ -4579,7 +3275,9 @@ "../../../node_modules/es-module-lexer": { "version": "1.4.1", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/es-set-tostringtag": { "version": "2.0.2", @@ -4655,23 +3353,6 @@ "@esbuild/win32-x64": "0.20.1" } }, - "../../../node_modules/esbuild-loader": { - "version": "4.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "esbuild": "^0.20.0", - "get-tsconfig": "^4.7.0", - "loader-utils": "^2.0.4", - "webpack-sources": "^1.4.3" - }, - "funding": { - "url": "https://github.com/privatenumber/esbuild-loader?sponsor=1" - }, - "peerDependencies": { - "webpack": "^4.40.0 || ^5.0.0" - } - }, "../../../node_modules/esbuild/node_modules/@esbuild/aix-ppc64": { "version": "0.20.1", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.1.tgz", @@ -5032,11 +3713,6 @@ "node": ">=6" } }, - "../../../node_modules/escape-html": { - "version": "1.0.3", - "dev": true, - "license": "MIT" - }, "../../../node_modules/escape-string-regexp": { "version": "4.0.0", "dev": true, @@ -5050,6 +3726,7 @@ }, "../../../node_modules/escodegen": { "version": "2.1.0", + "dev": true, "license": "BSD-2-Clause", "dependencies": { "esprima": "^4.0.1", @@ -5121,18 +3798,6 @@ "url": "https://opencollective.com/eslint" } }, - "../../../node_modules/eslint-formatter-codeframe": { - "version": "7.32.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "7.12.11", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, "../../../node_modules/eslint-import-resolver-node": { "version": "0.3.9", "dev": true, @@ -5175,71 +3840,6 @@ "eslint-plugin-import": "*" } }, - "../../../node_modules/eslint-interactive": { - "version": "10.8.0", - "dev": true, - "license": "MIT", - "dependencies": { - "boxen": "^7.0.2", - "chalk": "^5.0.1", - "comlink": "^4.3.1", - "enquirer": "^2.3.6", - "eslint-formatter-codeframe": "^7.32.1", - "estraverse": "^5.3.0", - "find-cache-dir": "^4.0.0", - "is-installed-globally": "^0.4.0", - "ora": "^6.1.2", - "strip-ansi": "^7.0.1", - "table": "^6.8.1", - "terminal-link": "^3.0.0", - "yargs": "^17.5.1" - }, - "bin": { - "eslint-interactive": "bin/eslint-interactive.js" - }, - "engines": { - "node": "^14.13.1 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" - } - }, - "../../../node_modules/eslint-interactive/node_modules/ansi-regex": { - "version": "6.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "../../../node_modules/eslint-interactive/node_modules/chalk": { - "version": "5.3.0", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "../../../node_modules/eslint-interactive/node_modules/strip-ansi": { - "version": "7.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, "../../../node_modules/eslint-module-utils": { "version": "2.8.0", "dev": true, @@ -5367,106 +3967,6 @@ "url": "https://opencollective.com/eslint" } }, - "../../../node_modules/eslint-webpack-plugin": { - "version": "4.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/eslint": "^8.37.0", - "jest-worker": "^29.5.0", - "micromatch": "^4.0.5", - "normalize-path": "^3.0.0", - "schema-utils": "^4.0.0" - }, - "engines": { - "node": ">= 14.15.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "eslint": "^8.0.0", - "webpack": "^5.0.0" - } - }, - "../../../node_modules/eslint-webpack-plugin/node_modules/ajv": { - "version": "8.12.0", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "../../../node_modules/eslint-webpack-plugin/node_modules/ajv-keywords": { - "version": "5.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, - "../../../node_modules/eslint-webpack-plugin/node_modules/jest-worker": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*", - "jest-util": "^29.7.0", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "../../../node_modules/eslint-webpack-plugin/node_modules/json-schema-traverse": { - "version": "1.0.0", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/eslint-webpack-plugin/node_modules/schema-utils": { - "version": "4.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.9.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.1.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "../../../node_modules/eslint-webpack-plugin/node_modules/supports-color": { - "version": "8.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, "../../../node_modules/eslint/node_modules/brace-expansion": { "version": "1.1.11", "dev": true, @@ -5538,6 +4038,7 @@ }, "../../../node_modules/estraverse": { "version": "5.3.0", + "dev": true, "license": "BSD-2-Clause", "engines": { "node": ">=4.0" @@ -5550,26 +4051,6 @@ "node": ">=0.10.0" } }, - "../../../node_modules/etag": { - "version": "1.8.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "../../../node_modules/eventemitter3": { - "version": "4.0.7", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/events": { - "version": "1.1.1", - "license": "MIT", - "engines": { - "node": ">=0.4.x" - } - }, "../../../node_modules/execa": { "version": "8.0.1", "dev": true, @@ -5642,93 +4123,26 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "../../../node_modules/express": { - "version": "4.19.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", - "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", + "../../../node_modules/extend": { + "version": "3.0.2", + "license": "MIT" + }, + "../../../node_modules/extend-shallow": { + "version": "2.0.1", + "license": "MIT", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "../../../node_modules/extract-zip": { + "version": "2.0.1", "dev": true, - "dependencies": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.2", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.6.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.2.0", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.7", - "qs": "6.11.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "../../../node_modules/express/node_modules/debug": { - "version": "2.6.9", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "../../../node_modules/express/node_modules/ms": { - "version": "2.0.0", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/express/node_modules/qs": { - "version": "6.11.0", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "../../../node_modules/extend": { - "version": "3.0.2", - "license": "MIT" - }, - "../../../node_modules/extend-shallow": { - "version": "2.0.1", - "license": "MIT", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "../../../node_modules/extract-zip": { - "version": "2.0.1", - "dev": true, - "license": "BSD-2-Clause", + "license": "BSD-2-Clause", + "optional": true, + "peer": true, "dependencies": { "debug": "^4.1.1", "get-stream": "^5.1.0", @@ -5748,6 +4162,8 @@ "version": "5.2.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "pump": "^3.0.0" }, @@ -5765,27 +4181,6 @@ ], "license": "MIT" }, - "../../../node_modules/falafel": { - "version": "2.2.5", - "license": "MIT", - "dependencies": { - "acorn": "^7.1.1", - "isarray": "^2.0.1" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "../../../node_modules/falafel/node_modules/acorn": { - "version": "7.4.1", - "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, "../../../node_modules/fast-deep-equal": { "version": "3.1.3", "license": "MIT" @@ -5793,7 +4188,9 @@ "../../../node_modules/fast-fifo": { "version": "1.3.2", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/fast-glob": { "version": "3.3.2", @@ -5829,14 +4226,6 @@ "version": "2.0.6", "license": "MIT" }, - "../../../node_modules/fastest-levenshtein": { - "version": "1.0.16", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4.9.1" - } - }, "../../../node_modules/fastq": { "version": "1.17.0", "dev": true, @@ -5845,17 +4234,6 @@ "reusify": "^1.0.4" } }, - "../../../node_modules/faye-websocket": { - "version": "0.11.4", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "websocket-driver": ">=0.5.1" - }, - "engines": { - "node": ">=0.8.0" - } - }, "../../../node_modules/fd-slicer": { "version": "1.1.0", "dev": true, @@ -5878,6 +4256,8 @@ } ], "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "node-domexception": "^1.0.0", "web-streams-polyfill": "^3.0.3" @@ -5912,51 +4292,6 @@ "node": ">=8" } }, - "../../../node_modules/finalhandler": { - "version": "1.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "../../../node_modules/finalhandler/node_modules/debug": { - "version": "2.6.9", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "../../../node_modules/finalhandler/node_modules/ms": { - "version": "2.0.0", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/find-cache-dir": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "common-path-prefix": "^3.0.0", - "pkg-dir": "^7.0.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "../../../node_modules/find-up": { "version": "5.0.0", "dev": true, @@ -5998,26 +4333,6 @@ "dev": true, "license": "ISC" }, - "../../../node_modules/follow-redirects": { - "version": "1.15.6", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", - "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, "../../../node_modules/for-each": { "version": "0.3.3", "dev": true, @@ -6047,316 +4362,92 @@ "node": "*" } }, - "../../../node_modules/fork-ts-checker-webpack-plugin": { - "version": "6.5.3", + "../../../node_modules/form-data": { + "version": "4.0.0", "dev": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.8.3", - "@types/json-schema": "^7.0.5", - "chalk": "^4.1.0", - "chokidar": "^3.4.2", - "cosmiconfig": "^6.0.0", - "deepmerge": "^4.2.2", - "fs-extra": "^9.0.0", - "glob": "^7.1.6", - "memfs": "^3.1.2", - "minimatch": "^3.0.4", - "schema-utils": "2.7.0", - "semver": "^7.3.2", - "tapable": "^1.0.0" + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" }, "engines": { - "node": ">=10", - "yarn": ">=1.0.0" - }, - "peerDependencies": { - "eslint": ">= 6", - "typescript": ">= 2.7", - "vue-template-compiler": "*", - "webpack": ">= 4" - }, - "peerDependenciesMeta": { - "eslint": { - "optional": true - }, - "vue-template-compiler": { - "optional": true - } + "node": ">= 6" } }, - "../../../node_modules/fork-ts-checker-webpack-plugin/node_modules/@babel/code-frame": { - "version": "7.23.5", + "../../../node_modules/form-data-encoder": { + "version": "2.1.4", "dev": true, "license": "MIT", - "dependencies": { - "@babel/highlight": "^7.23.4", - "chalk": "^2.4.2" - }, + "optional": true, + "peer": true, "engines": { - "node": ">=6.9.0" + "node": ">= 14.17" } }, - "../../../node_modules/fork-ts-checker-webpack-plugin/node_modules/@babel/code-frame/node_modules/chalk": { - "version": "2.4.2", + "../../../node_modules/formdata-polyfill": { + "version": "4.0.10", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "fetch-blob": "^3.1.2" }, "engines": { - "node": ">=4" + "node": ">=12.20.0" } }, - "../../../node_modules/fork-ts-checker-webpack-plugin/node_modules/ansi-styles": { - "version": "3.2.1", + "../../../node_modules/fs-extra": { + "version": "11.2.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { - "color-convert": "^1.9.0" + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" }, "engines": { - "node": ">=4" - } - }, - "../../../node_modules/fork-ts-checker-webpack-plugin/node_modules/brace-expansion": { - "version": "1.1.11", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "node": ">=14.14" } }, - "../../../node_modules/fork-ts-checker-webpack-plugin/node_modules/color-convert": { - "version": "1.9.3", + "../../../node_modules/fs-extra/node_modules/universalify": { + "version": "2.0.1", "dev": true, "license": "MIT", - "dependencies": { - "color-name": "1.1.3" + "optional": true, + "peer": true, + "engines": { + "node": ">= 10.0.0" } }, - "../../../node_modules/fork-ts-checker-webpack-plugin/node_modules/color-name": { - "version": "1.1.3", + "../../../node_modules/fs.realpath": { + "version": "1.0.0", "dev": true, - "license": "MIT" + "license": "ISC" }, - "../../../node_modules/fork-ts-checker-webpack-plugin/node_modules/escape-string-regexp": { - "version": "1.0.5", + "../../../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, - "license": "MIT", + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=0.8.0" + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "../../../node_modules/fork-ts-checker-webpack-plugin/node_modules/fs-extra": { - "version": "9.1.0", + "../../../node_modules/fstream": { + "version": "1.0.12", "dev": true, - "license": "MIT", - "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "../../../node_modules/fork-ts-checker-webpack-plugin/node_modules/glob": { - "version": "7.2.3", - "dev": true, - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "../../../node_modules/fork-ts-checker-webpack-plugin/node_modules/has-flag": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "../../../node_modules/fork-ts-checker-webpack-plugin/node_modules/memfs": { - "version": "3.5.3", - "dev": true, - "license": "Unlicense", - "dependencies": { - "fs-monkey": "^1.0.4" - }, - "engines": { - "node": ">= 4.0.0" - } - }, - "../../../node_modules/fork-ts-checker-webpack-plugin/node_modules/minimatch": { - "version": "3.1.2", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "../../../node_modules/fork-ts-checker-webpack-plugin/node_modules/schema-utils": { - "version": "2.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/json-schema": "^7.0.4", - "ajv": "^6.12.2", - "ajv-keywords": "^3.4.1" - }, - "engines": { - "node": ">= 8.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "../../../node_modules/fork-ts-checker-webpack-plugin/node_modules/supports-color": { - "version": "5.5.0", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "../../../node_modules/fork-ts-checker-webpack-plugin/node_modules/tapable": { - "version": "1.1.3", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "../../../node_modules/fork-ts-checker-webpack-plugin/node_modules/universalify": { - "version": "2.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 10.0.0" - } - }, - "../../../node_modules/form-data": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "../../../node_modules/form-data-encoder": { - "version": "2.1.4", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 14.17" - } - }, - "../../../node_modules/formdata-polyfill": { - "version": "4.0.10", - "dev": true, - "license": "MIT", - "dependencies": { - "fetch-blob": "^3.1.2" - }, - "engines": { - "node": ">=12.20.0" - } - }, - "../../../node_modules/forwarded": { - "version": "0.2.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "../../../node_modules/fresh": { - "version": "0.5.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "../../../node_modules/fs-extra": { - "version": "11.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=14.14" - } - }, - "../../../node_modules/fs-extra/node_modules/universalify": { - "version": "2.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 10.0.0" - } - }, - "../../../node_modules/fs-monkey": { - "version": "1.0.5", - "dev": true, - "license": "Unlicense" - }, - "../../../node_modules/fs.realpath": { - "version": "1.0.0", - "dev": true, - "license": "ISC" - }, - "../../../node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "../../../node_modules/fstream": { - "version": "1.0.12", - "dev": true, - "license": "ISC", + "license": "ISC", + "optional": true, + "peer": true, "dependencies": { "graceful-fs": "^4.1.2", "inherits": "~2.0.0", @@ -6371,6 +4462,8 @@ "version": "1.1.11", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -6380,6 +4473,8 @@ "version": "7.2.3", "dev": true, "license": "ISC", + "optional": true, + "peer": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -6399,6 +4494,8 @@ "version": "3.1.2", "dev": true, "license": "ISC", + "optional": true, + "peer": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -6410,6 +4507,8 @@ "version": "2.7.1", "dev": true, "license": "ISC", + "optional": true, + "peer": true, "dependencies": { "glob": "^7.1.3" }, @@ -6419,6 +4518,7 @@ }, "../../../node_modules/function-bind": { "version": "1.1.2", + "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" @@ -6454,6 +4554,8 @@ "dev": true, "hasInstallScript": true, "license": "MPL-2.0", + "optional": true, + "peer": true, "dependencies": { "@wdio/logger": "^8.28.0", "decamelize": "^6.0.0", @@ -6475,6 +4577,8 @@ "version": "7.1.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "debug": "^4.3.4" }, @@ -6486,6 +4590,8 @@ "version": "7.0.2", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "agent-base": "^7.1.0", "debug": "^4.3.4" @@ -6498,6 +4604,8 @@ "version": "7.0.4", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "agent-base": "^7.0.2", "debug": "4" @@ -6510,6 +4618,8 @@ "version": "3.1.1", "dev": true, "license": "ISC", + "optional": true, + "peer": true, "engines": { "node": ">=16" } @@ -6518,6 +4628,8 @@ "version": "4.0.0", "dev": true, "license": "ISC", + "optional": true, + "peer": true, "dependencies": { "isexe": "^3.1.1" }, @@ -6562,6 +4674,8 @@ "version": "7.0.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=16" }, @@ -6610,6 +4724,8 @@ "version": "6.0.3", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "basic-ftp": "^5.0.2", "data-uri-to-buffer": "^6.0.2", @@ -6624,6 +4740,8 @@ "version": "6.0.2", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">= 14" } @@ -6673,21 +4791,9 @@ "../../../node_modules/glob-to-regexp": { "version": "0.4.1", "dev": true, - "license": "BSD-2-Clause" - }, - "../../../node_modules/global-dirs": { - "version": "3.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "ini": "2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } + "license": "BSD-2-Clause", + "optional": true, + "peer": true }, "../../../node_modules/globals": { "version": "13.24.0", @@ -6728,42 +4834,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "../../../node_modules/globby": { - "version": "11.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/glsl-editor": { - "version": "1.0.0", - "license": "MIT", - "dependencies": { - "brfs": "^1.2.0", - "codemirror": "^4.5.0", - "element-size": "^1.1.1", - "events": "^1.0.2", - "inherits": "^2.0.1", - "insert-css": "^0.2.0", - "through2": "^0.6.1", - "xtend": "^4.0.0" - } - }, - "../../../node_modules/glsl-editor/node_modules/codemirror": { - "version": "4.13.0" - }, "../../../node_modules/gopd": { "version": "1.0.1", "dev": true, @@ -6779,6 +4849,8 @@ "version": "12.6.1", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@sindresorhus/is": "^5.2.0", "@szmarczak/http-timer": "^5.0.1", @@ -6803,6 +4875,8 @@ "version": "6.0.1", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=10" }, @@ -6818,7 +4892,9 @@ "../../../node_modules/grapheme-splitter": { "version": "1.0.4", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/graphemer": { "version": "1.4.0", @@ -6839,11 +4915,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "../../../node_modules/handle-thing": { - "version": "2.0.1", - "dev": true, - "license": "MIT" - }, "../../../node_modules/har-schema": { "version": "2.0.0", "license": "ISC", @@ -6862,13 +4933,6 @@ "node": ">=6" } }, - "../../../node_modules/has": { - "version": "1.0.4", - "license": "MIT", - "engines": { - "node": ">= 0.4.0" - } - }, "../../../node_modules/has-bigints": { "version": "1.0.2", "dev": true, @@ -6934,6 +4998,7 @@ }, "../../../node_modules/hasown": { "version": "2.0.0", + "dev": true, "license": "MIT", "dependencies": { "function-bind": "^1.1.2" @@ -6942,31 +5007,10 @@ "node": ">= 0.4" } }, - "../../../node_modules/he": { - "version": "1.2.0", - "dev": true, - "license": "MIT", - "bin": { - "he": "bin/he" - } - }, - "../../../node_modules/hpack.js": { - "version": "2.1.6", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.1", - "obuf": "^1.0.0", - "readable-stream": "^2.0.1", - "wbuf": "^1.1.0" - } - }, "../../../node_modules/html-encoding-sniffer": { "version": "2.0.1", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "dependencies": { "whatwg-encoding": "^1.0.5" }, @@ -6974,152 +5018,22 @@ "node": ">=10" } }, - "../../../node_modules/html-entities": { - "version": "2.5.2", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/mdevils" - }, - { - "type": "patreon", - "url": "https://patreon.com/mdevils" - } - ], - "license": "MIT" - }, "../../../node_modules/html-escaper": { "version": "2.0.2", "dev": true, "license": "MIT" }, - "../../../node_modules/html-minifier-terser": { - "version": "6.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "camel-case": "^4.1.2", - "clean-css": "^5.2.2", - "commander": "^8.3.0", - "he": "^1.2.0", - "param-case": "^3.0.4", - "relateurl": "^0.2.7", - "terser": "^5.10.0" - }, - "bin": { - "html-minifier-terser": "cli.js" - }, - "engines": { - "node": ">=12" - } - }, - "../../../node_modules/html-minifier-terser/node_modules/commander": { - "version": "8.3.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 12" - } - }, - "../../../node_modules/html-webpack-plugin": { - "version": "5.6.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/html-minifier-terser": "^6.0.0", - "html-minifier-terser": "^6.0.2", - "lodash": "^4.17.21", - "pretty-error": "^4.0.0", - "tapable": "^2.0.0" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/html-webpack-plugin" - }, - "peerDependencies": { - "@rspack/core": "0.x || 1.x", - "webpack": "^5.20.0" - }, - "peerDependenciesMeta": { - "@rspack/core": { - "optional": true - }, - "webpack": { - "optional": true - } - } - }, - "../../../node_modules/htmlparser2": { - "version": "6.1.0", - "dev": true, - "funding": [ - "https://github.com/fb55/htmlparser2?sponsor=1", - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "license": "MIT", - "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.0.0", - "domutils": "^2.5.2", - "entities": "^2.0.0" - } - }, "../../../node_modules/http-cache-semantics": { "version": "4.1.1", "dev": true, - "license": "BSD-2-Clause" - }, - "../../../node_modules/http-deceiver": { - "version": "1.2.7", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/http-errors": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "../../../node_modules/http-parser-js": { - "version": "0.5.8", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/http-proxy": { - "version": "1.18.1", - "dev": true, - "license": "MIT", - "dependencies": { - "eventemitter3": "^4.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" - }, - "engines": { - "node": ">=8.0.0" - } + "license": "BSD-2-Clause", + "optional": true, + "peer": true }, "../../../node_modules/http-proxy-agent": { "version": "4.0.1", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "dependencies": { "@tootallnate/once": "1", "agent-base": "6", @@ -7129,40 +5043,6 @@ "node": ">= 6" } }, - "../../../node_modules/http-proxy-middleware": { - "version": "2.0.6", - "dev": true, - "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" - }, - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "@types/express": "^4.17.13" - }, - "peerDependenciesMeta": { - "@types/express": { - "optional": true - } - } - }, - "../../../node_modules/http-proxy-middleware/node_modules/is-plain-obj": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "../../../node_modules/http-signature": { "version": "1.2.0", "license": "MIT", @@ -7180,6 +5060,8 @@ "version": "2.2.1", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "quick-lru": "^5.1.1", "resolve-alpn": "^1.2.0" @@ -7192,8 +5074,6 @@ "version": "5.0.1", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "dependencies": { "agent-base": "6", "debug": "4" @@ -7248,7 +5128,9 @@ "url": "https://feross.org/support" } ], - "license": "BSD-3-Clause" + "license": "BSD-3-Clause", + "optional": true, + "peer": true }, "../../../node_modules/ignore": { "version": "5.3.0", @@ -7516,170 +5398,72 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "../../../node_modules/import-local": { - "version": "3.1.0", + "../../../node_modules/import-meta-resolve": { + "version": "4.0.0", "dev": true, "license": "MIT", - "dependencies": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - }, - "bin": { - "import-local-fixture": "fixtures/cli.js" - }, - "engines": { - "node": ">=8" - }, + "optional": true, + "peer": true, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "../../../node_modules/import-local/node_modules/find-up": { - "version": "4.1.0", + "../../../node_modules/imurmurhash": { + "version": "0.1.4", "dev": true, "license": "MIT", - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, "engines": { - "node": ">=8" + "node": ">=0.8.19" } }, - "../../../node_modules/import-local/node_modules/locate-path": { - "version": "5.0.0", + "../../../node_modules/inflight": { + "version": "1.0.6", "dev": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" + "once": "^1.3.0", + "wrappy": "1" } }, - "../../../node_modules/import-local/node_modules/p-limit": { - "version": "2.3.0", + "../../../node_modules/inherits": { + "version": "2.0.4", + "dev": true, + "license": "ISC" + }, + "../../../node_modules/internal-slot": { + "version": "1.0.6", "dev": true, "license": "MIT", "dependencies": { - "p-try": "^2.0.0" + "get-intrinsic": "^1.2.2", + "hasown": "^2.0.0", + "side-channel": "^1.0.4" }, "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 0.4" } }, - "../../../node_modules/import-local/node_modules/p-locate": { - "version": "4.1.0", + "../../../node_modules/ip-address": { + "version": "9.0.5", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { - "p-limit": "^2.2.0" + "jsbn": "1.1.0", + "sprintf-js": "^1.1.3" }, "engines": { - "node": ">=8" - } - }, - "../../../node_modules/import-local/node_modules/pkg-dir": { - "version": "4.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "find-up": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "../../../node_modules/import-meta-resolve": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "../../../node_modules/imurmurhash": { - "version": "0.1.4", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.19" - } - }, - "../../../node_modules/inflight": { - "version": "1.0.6", - "dev": true, - "license": "ISC", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "../../../node_modules/inherits": { - "version": "2.0.4", - "license": "ISC" - }, - "../../../node_modules/ini": { - "version": "2.0.0", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "../../../node_modules/insert-css": { - "version": "0.2.0", - "license": "MIT" - }, - "../../../node_modules/internal-slot": { - "version": "1.0.6", - "dev": true, - "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.2.2", - "hasown": "^2.0.0", - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "../../../node_modules/interpret": { - "version": "3.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10.13.0" - } - }, - "../../../node_modules/ip-address": { - "version": "9.0.5", - "dev": true, - "license": "MIT", - "dependencies": { - "jsbn": "1.1.0", - "sprintf-js": "^1.1.3" - }, - "engines": { - "node": ">= 12" + "node": ">= 12" } }, "../../../node_modules/ip-address/node_modules/jsbn": { "version": "1.1.0", "dev": true, - "license": "MIT" - }, - "../../../node_modules/ipaddr.js": { - "version": "2.1.0", - "dev": true, "license": "MIT", - "engines": { - "node": ">= 10" - } + "optional": true, + "peer": true }, "../../../node_modules/is-array-buffer": { "version": "3.0.2", @@ -7694,11 +5478,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "../../../node_modules/is-arrayish": { - "version": "0.2.1", - "dev": true, - "license": "MIT" - }, "../../../node_modules/is-bigint": { "version": "1.0.4", "dev": true, @@ -7710,17 +5489,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "../../../node_modules/is-binary-path": { - "version": "2.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, "../../../node_modules/is-boolean-object": { "version": "1.1.2", "dev": true, @@ -7753,6 +5521,7 @@ }, "../../../node_modules/is-core-module": { "version": "2.13.1", + "dev": true, "license": "MIT", "dependencies": { "hasown": "^2.0.0" @@ -7775,20 +5544,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "../../../node_modules/is-docker": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "../../../node_modules/is-extendable": { "version": "0.1.1", "license": "MIT", @@ -7822,49 +5577,6 @@ "node": ">=0.10.0" } }, - "../../../node_modules/is-inside-container": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "is-docker": "^3.0.0" - }, - "bin": { - "is-inside-container": "cli.js" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/is-installed-globally": { - "version": "0.4.0", - "dev": true, - "license": "MIT", - "dependencies": { - "global-dirs": "^3.0.0", - "is-path-inside": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/is-interactive": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "../../../node_modules/is-negative-zero": { "version": "2.0.2", "dev": true, @@ -7876,17 +5588,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "../../../node_modules/is-network-error": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "../../../node_modules/is-number": { "version": "7.0.0", "dev": true, @@ -7921,6 +5622,8 @@ "version": "4.1.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=12" }, @@ -7942,9 +5645,7 @@ "../../../node_modules/is-potential-custom-element-name": { "version": "1.0.1", "dev": true, - "license": "MIT", - "optional": true, - "peer": true + "license": "MIT" }, "../../../node_modules/is-regex": { "version": "1.1.4", @@ -8029,17 +5730,6 @@ "version": "1.0.0", "license": "MIT" }, - "../../../node_modules/is-unicode-supported": { - "version": "1.3.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "../../../node_modules/is-weakref": { "version": "1.0.2", "dev": true, @@ -8058,22 +5748,9 @@ "node": ">=0.10.0" } }, - "../../../node_modules/is-wsl": { - "version": "3.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "is-inside-container": "^1.0.0" - }, - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "../../../node_modules/isarray": { "version": "2.0.5", + "dev": true, "license": "MIT" }, "../../../node_modules/isexe": { @@ -8108,26 +5785,12 @@ "@pkgjs/parseargs": "^0.11.0" } }, - "../../../node_modules/jest-util": { - "version": "29.7.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, "../../../node_modules/jest-worker": { "version": "27.5.1", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@types/node": "*", "merge-stream": "^2.0.0", @@ -8141,6 +5804,8 @@ "version": "8.1.1", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -8169,11 +5834,6 @@ "node": ">=14" } }, - "../../../node_modules/js-tokens": { - "version": "4.0.0", - "dev": true, - "license": "MIT" - }, "../../../node_modules/js-yaml": { "version": "4.1.0", "dev": true, @@ -8193,8 +5853,6 @@ "version": "17.0.0", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "dependencies": { "abab": "^2.0.5", "acorn": "^8.4.1", @@ -8244,7 +5902,9 @@ "../../../node_modules/json-parse-even-better-errors": { "version": "2.3.1", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/json-schema": { "version": "0.4.0", @@ -8263,17 +5923,6 @@ "version": "5.0.1", "license": "ISC" }, - "../../../node_modules/json5": { - "version": "2.2.3", - "dev": true, - "license": "MIT", - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, "../../../node_modules/jsonc-parser": { "version": "3.2.1", "dev": true, @@ -8283,6 +5932,8 @@ "version": "6.1.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "universalify": "^2.0.0" }, @@ -8294,6 +5945,8 @@ "version": "2.0.1", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">= 10.0.0" } @@ -8333,6 +5986,8 @@ "version": "0.33.3", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=14.16" }, @@ -8340,19 +5995,12 @@ "url": "https://github.com/sindresorhus/ky?sponsor=1" } }, - "../../../node_modules/launch-editor": { - "version": "2.6.1", - "dev": true, - "license": "MIT", - "dependencies": { - "picocolors": "^1.0.0", - "shell-quote": "^1.8.1" - } - }, "../../../node_modules/lazystream": { "version": "1.0.1", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "readable-stream": "^2.0.5" }, @@ -8444,37 +6092,23 @@ "url": "https://opencollective.com/parcel" } }, - "../../../node_modules/lines-and-columns": { - "version": "1.2.4", - "dev": true, - "license": "MIT" - }, "../../../node_modules/listenercount": { "version": "1.0.1", "dev": true, - "license": "ISC" - }, - "../../../node_modules/loader-runner": { + "license": "ISC", + "optional": true, + "peer": true + }, + "../../../node_modules/loader-runner": { "version": "4.3.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=6.11.5" } }, - "../../../node_modules/loader-utils": { - "version": "2.0.4", - "dev": true, - "license": "MIT", - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - }, - "engines": { - "node": ">=8.9.0" - } - }, "../../../node_modules/local-pkg": { "version": "0.5.0", "dev": true, @@ -8494,6 +6128,8 @@ "version": "2.2.20", "dev": true, "license": "SEE LICENSE IN LICENSE", + "optional": true, + "peer": true, "dependencies": { "n12": "1.8.23", "type-fest": "2.13.0", @@ -8504,6 +6140,8 @@ "version": "2.13.0", "dev": true, "license": "(MIT OR CC0-1.0)", + "optional": true, + "peer": true, "engines": { "node": ">=12.20" }, @@ -8536,7 +6174,9 @@ "../../../node_modules/lodash.clonedeep": { "version": "4.5.0", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/lodash.merge": { "version": "4.6.2", @@ -8547,46 +6187,19 @@ "version": "4.7.0", "license": "MIT" }, - "../../../node_modules/lodash.truncate": { - "version": "4.4.2", - "dev": true, - "license": "MIT" - }, "../../../node_modules/lodash.zip": { "version": "4.2.0", "dev": true, - "license": "MIT" - }, - "../../../node_modules/log-symbols": { - "version": "5.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^5.0.0", - "is-unicode-supported": "^1.1.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/log-symbols/node_modules/chalk": { - "version": "5.3.0", - "dev": true, "license": "MIT", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } + "optional": true, + "peer": true }, "../../../node_modules/loglevel": { "version": "1.9.1", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">= 0.6.0" }, @@ -8598,7 +6211,9 @@ "../../../node_modules/loglevel-plugin-prefix": { "version": "0.8.4", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/loupe": { "version": "2.3.7", @@ -8608,18 +6223,12 @@ "get-func-name": "^2.0.1" } }, - "../../../node_modules/lower-case": { - "version": "2.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "tslib": "^2.0.3" - } - }, "../../../node_modules/lowercase-keys": { "version": "3.0.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, @@ -8645,48 +6254,6 @@ "node": ">=12" } }, - "../../../node_modules/media-typer": { - "version": "0.3.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "../../../node_modules/memfs": { - "version": "4.7.7", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.0.0" - }, - "engines": { - "node": ">= 4.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - } - }, - "../../../node_modules/merge-descriptors": { - "version": "1.0.1", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/merge-source-map": { - "version": "1.0.4", - "license": "MIT", - "dependencies": { - "source-map": "^0.5.6" - } - }, - "../../../node_modules/merge-source-map/node_modules/source-map": { - "version": "0.5.7", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, "../../../node_modules/merge-stream": { "version": "2.0.0", "dev": true, @@ -8700,14 +6267,6 @@ "node": ">= 8" } }, - "../../../node_modules/methods": { - "version": "1.1.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, "../../../node_modules/micromatch": { "version": "4.0.5", "dev": true, @@ -8720,17 +6279,6 @@ "node": ">=8.6" } }, - "../../../node_modules/mime": { - "version": "1.6.0", - "dev": true, - "license": "MIT", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, "../../../node_modules/mime-db": { "version": "1.52.0", "license": "MIT", @@ -8748,18 +6296,12 @@ "node": ">= 0.6" } }, - "../../../node_modules/mimic-fn": { - "version": "2.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "../../../node_modules/mimic-response": { "version": "4.0.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, @@ -8767,79 +6309,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "../../../node_modules/mini-css-extract-plugin": { - "version": "2.8.1", - "dev": true, - "license": "MIT", - "dependencies": { - "schema-utils": "^4.0.0", - "tapable": "^2.2.1" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.0.0" - } - }, - "../../../node_modules/mini-css-extract-plugin/node_modules/ajv": { - "version": "8.12.0", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "../../../node_modules/mini-css-extract-plugin/node_modules/ajv-keywords": { - "version": "5.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, - "../../../node_modules/mini-css-extract-plugin/node_modules/json-schema-traverse": { - "version": "1.0.0", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/mini-css-extract-plugin/node_modules/schema-utils": { - "version": "4.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.9.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.1.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "../../../node_modules/minimalistic-assert": { - "version": "1.0.1", - "dev": true, - "license": "ISC" - }, "../../../node_modules/minimatch": { "version": "9.0.3", "license": "ISC", @@ -8855,6 +6324,7 @@ }, "../../../node_modules/minimist": { "version": "1.2.8", + "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" @@ -8870,12 +6340,16 @@ "../../../node_modules/mitt": { "version": "3.0.0", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/mkdirp": { "version": "0.5.6", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "minimist": "^1.2.6" }, @@ -8907,22 +6381,12 @@ "dev": true, "license": "MIT" }, - "../../../node_modules/multicast-dns": { - "version": "7.2.5", - "dev": true, - "license": "MIT", - "dependencies": { - "dns-packet": "^5.2.2", - "thunky": "^1.0.2" - }, - "bin": { - "multicast-dns": "cli.js" - } - }, "../../../node_modules/n12": { "version": "1.8.23", "dev": true, - "license": "SEE LICENSE IN LICENSE" + "license": "SEE LICENSE IN LICENSE", + "optional": true, + "peer": true }, "../../../node_modules/nanoid": { "version": "3.3.7", @@ -8946,23 +6410,19 @@ "dev": true, "license": "MIT" }, - "../../../node_modules/negotiator": { - "version": "0.6.3", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, "../../../node_modules/neo-async": { "version": "2.6.2", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/netmask": { "version": "2.0.2", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">= 0.4.0" } @@ -8974,15 +6434,6 @@ "fflate": "*" } }, - "../../../node_modules/no-case": { - "version": "3.0.4", - "dev": true, - "license": "MIT", - "dependencies": { - "lower-case": "^2.0.2", - "tslib": "^2.0.3" - } - }, "../../../node_modules/node-domexception": { "version": "1.0.0", "dev": true, @@ -8997,6 +6448,8 @@ } ], "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=10.5.0" } @@ -9005,6 +6458,8 @@ "version": "3.3.2", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "data-uri-to-buffer": "^4.0.0", "fetch-blob": "^3.1.4", @@ -9018,18 +6473,12 @@ "url": "https://opencollective.com/node-fetch" } }, - "../../../node_modules/node-forge": { - "version": "1.3.1", - "dev": true, - "license": "(BSD-3-Clause OR GPL-2.0)", - "engines": { - "node": ">= 6.13.0" - } - }, "../../../node_modules/node-releases": { "version": "2.0.14", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/nopt": { "version": "7.2.0", @@ -9048,6 +6497,8 @@ "version": "3.0.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=0.10.0" } @@ -9056,6 +6507,8 @@ "version": "8.0.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=14.16" }, @@ -9063,28 +6516,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "../../../node_modules/npm-run-path": { - "version": "4.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "path-key": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "../../../node_modules/nth-check": { - "version": "2.1.1", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "boolbase": "^1.0.0" - }, - "funding": { - "url": "https://github.com/fb55/nth-check?sponsor=1" - } - }, "../../../node_modules/numcodecs": { "version": "0.3.1", "license": "MIT", @@ -9099,9 +6530,7 @@ "../../../node_modules/nwsapi": { "version": "2.2.7", "dev": true, - "license": "MIT", - "optional": true, - "peer": true + "license": "MIT" }, "../../../node_modules/oauth-sign": { "version": "0.9.0", @@ -9110,14 +6539,6 @@ "node": "*" } }, - "../../../node_modules/object-assign": { - "version": "4.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "../../../node_modules/object-inspect": { "version": "1.13.1", "dev": true, @@ -9194,30 +6615,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "../../../node_modules/obuf": { - "version": "1.1.2", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/on-finished": { - "version": "2.4.1", - "dev": true, - "license": "MIT", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "../../../node_modules/on-headers": { - "version": "1.0.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, "../../../node_modules/once": { "version": "1.4.0", "dev": true, @@ -9226,37 +6623,6 @@ "wrappy": "1" } }, - "../../../node_modules/onetime": { - "version": "5.1.2", - "dev": true, - "license": "MIT", - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/open": { - "version": "10.1.0", - "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" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "../../../node_modules/opener": { "version": "1.5.2", "dev": true, @@ -9281,68 +6647,12 @@ "node": ">= 0.8.0" } }, - "../../../node_modules/ora": { - "version": "6.3.1", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^5.0.0", - "cli-cursor": "^4.0.0", - "cli-spinners": "^2.6.1", - "is-interactive": "^2.0.0", - "is-unicode-supported": "^1.1.0", - "log-symbols": "^5.1.0", - "stdin-discarder": "^0.1.0", - "strip-ansi": "^7.0.1", - "wcwidth": "^1.0.1" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/ora/node_modules/ansi-regex": { - "version": "6.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "../../../node_modules/ora/node_modules/chalk": { - "version": "5.3.0", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "../../../node_modules/ora/node_modules/strip-ansi": { - "version": "7.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, "../../../node_modules/p-cancelable": { "version": "3.0.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=12.20" } @@ -9375,34 +6685,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "../../../node_modules/p-retry": { - "version": "6.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/retry": "0.12.2", - "is-network-error": "^1.0.0", - "retry": "^0.13.1" - }, - "engines": { - "node": ">=16.17" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/p-try": { - "version": "2.2.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "../../../node_modules/pac-proxy-agent": { "version": "7.0.1", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@tootallnate/quickjs-emscripten": "^0.23.0", "agent-base": "^7.0.2", @@ -9421,6 +6709,8 @@ "version": "7.1.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "debug": "^4.3.4" }, @@ -9432,6 +6722,8 @@ "version": "7.0.2", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "agent-base": "^7.1.0", "debug": "^4.3.4" @@ -9444,6 +6736,8 @@ "version": "7.0.4", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "agent-base": "^7.0.2", "debug": "4" @@ -9456,6 +6750,8 @@ "version": "7.0.1", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "degenerator": "^5.0.0", "netmask": "^2.0.2" @@ -9464,19 +6760,6 @@ "node": ">= 14" } }, - "../../../node_modules/pako": { - "version": "2.1.0", - "license": "(MIT AND Zlib)" - }, - "../../../node_modules/param-case": { - "version": "3.0.4", - "dev": true, - "license": "MIT", - "dependencies": { - "dot-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, "../../../node_modules/parent-module": { "version": "1.0.1", "dev": true, @@ -9488,46 +6771,10 @@ "node": ">=6" } }, - "../../../node_modules/parse-json": { - "version": "5.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "../../../node_modules/parse5": { "version": "6.0.1", "dev": true, - "license": "MIT", - "optional": true, - "peer": true - }, - "../../../node_modules/parseurl": { - "version": "1.3.3", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "../../../node_modules/pascal-case": { - "version": "3.1.2", - "dev": true, - "license": "MIT", - "dependencies": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } + "license": "MIT" }, "../../../node_modules/path-exists": { "version": "4.0.0", @@ -9554,6 +6801,7 @@ }, "../../../node_modules/path-parse": { "version": "1.0.7", + "dev": true, "license": "MIT" }, "../../../node_modules/path-scurry": { @@ -9570,19 +6818,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "../../../node_modules/path-to-regexp": { - "version": "0.1.7", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/path-type": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "../../../node_modules/pathe": { "version": "1.1.2", "dev": true, @@ -9622,136 +6857,46 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "../../../node_modules/pkg-dir": { - "version": "7.0.0", + "../../../node_modules/pkg-types": { + "version": "1.0.3", "dev": true, "license": "MIT", "dependencies": { - "find-up": "^6.3.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "jsonc-parser": "^3.2.0", + "mlly": "^1.2.0", + "pathe": "^1.1.0" } }, - "../../../node_modules/pkg-dir/node_modules/find-up": { - "version": "6.3.0", + "../../../node_modules/pn": { + "version": "1.1.0", + "license": "MIT" + }, + "../../../node_modules/postcss": { + "version": "8.4.39", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz", + "integrity": "sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==", "dev": true, - "license": "MIT", + "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": { - "locate-path": "^7.1.0", - "path-exists": "^5.0.0" + "nanoid": "^3.3.7", + "picocolors": "^1.0.1", + "source-map-js": "^1.2.0" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/pkg-dir/node_modules/locate-path": { - "version": "7.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^6.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/pkg-dir/node_modules/p-limit": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "yocto-queue": "^1.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/pkg-dir/node_modules/p-locate": { - "version": "6.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/pkg-dir/node_modules/path-exists": { - "version": "5.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - } - }, - "../../../node_modules/pkg-dir/node_modules/yocto-queue": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/pkg-types": { - "version": "1.0.3", - "dev": true, - "license": "MIT", - "dependencies": { - "jsonc-parser": "^3.2.0", - "mlly": "^1.2.0", - "pathe": "^1.1.0" - } - }, - "../../../node_modules/pn": { - "version": "1.1.0", - "license": "MIT" - }, - "../../../node_modules/postcss": { - "version": "8.4.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz", - "integrity": "sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==", - "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.7", - "picocolors": "^1.0.1", - "source-map-js": "^1.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14" + "node": "^10 || ^12 || >=14" } }, "../../../node_modules/postcss-modules-extract-imports": { @@ -9860,15 +7005,6 @@ "node": ">=0.10.0" } }, - "../../../node_modules/pretty-error": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "lodash": "^4.17.20", - "renderkid": "^3.0.0" - } - }, "../../../node_modules/pretty-format": { "version": "29.7.0", "dev": true, @@ -9895,12 +7031,17 @@ }, "../../../node_modules/process-nextick-args": { "version": "2.0.1", - "license": "MIT" + "dev": true, + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/progress": { "version": "2.0.3", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=0.4.0" } @@ -9909,30 +7050,12 @@ "version": "1.2.4", "license": "ISC" }, - "../../../node_modules/proxy-addr": { - "version": "2.0.7", - "dev": true, - "license": "MIT", - "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "../../../node_modules/proxy-addr/node_modules/ipaddr.js": { - "version": "1.9.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.10" - } - }, "../../../node_modules/proxy-agent": { "version": "6.4.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "agent-base": "^7.0.2", "debug": "^4.3.4", @@ -9951,6 +7074,8 @@ "version": "7.1.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "debug": "^4.3.4" }, @@ -9962,6 +7087,8 @@ "version": "7.0.2", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "agent-base": "^7.1.0", "debug": "^4.3.4" @@ -9974,6 +7101,8 @@ "version": "7.0.4", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "agent-base": "^7.0.2", "debug": "4" @@ -9986,6 +7115,8 @@ "version": "7.18.3", "dev": true, "license": "ISC", + "optional": true, + "peer": true, "engines": { "node": ">=12" } @@ -9993,7 +7124,9 @@ "../../../node_modules/proxy-from-env": { "version": "1.1.0", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/psl": { "version": "1.9.0", @@ -10003,6 +7136,8 @@ "version": "3.0.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -10019,6 +7154,8 @@ "version": "20.9.0", "dev": true, "license": "Apache-2.0", + "optional": true, + "peer": true, "dependencies": { "@puppeteer/browsers": "1.4.6", "chromium-bidi": "0.4.16", @@ -10042,12 +7179,16 @@ "../../../node_modules/puppeteer-core/node_modules/devtools-protocol": { "version": "0.0.1147663", "dev": true, - "license": "BSD-3-Clause" + "license": "BSD-3-Clause", + "optional": true, + "peer": true }, "../../../node_modules/puppeteer-core/node_modules/ws": { "version": "8.13.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=10.0.0" }, @@ -10074,14 +7215,14 @@ "../../../node_modules/query-selector-shadow-dom": { "version": "1.0.1", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/querystringify": { "version": "2.2.0", "dev": true, - "license": "MIT", - "optional": true, - "peer": true + "license": "MIT" }, "../../../node_modules/queue-microtask": { "version": "1.2.3", @@ -10105,12 +7246,16 @@ "../../../node_modules/queue-tick": { "version": "1.0.1", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/quick-lru": { "version": "5.1.1", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=10" }, @@ -10118,64 +7263,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "../../../node_modules/quote-stream": { - "version": "1.0.2", - "license": "MIT", - "dependencies": { - "buffer-equal": "0.0.1", - "minimist": "^1.1.3", - "through2": "^2.0.0" - }, - "bin": { - "quote-stream": "bin/cmd.js" - } - }, - "../../../node_modules/quote-stream/node_modules/through2": { - "version": "2.0.5", - "license": "MIT", - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, "../../../node_modules/randombytes": { "version": "2.1.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "safe-buffer": "^5.1.0" } }, - "../../../node_modules/range-parser": { - "version": "1.2.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "../../../node_modules/raw-body": { - "version": "2.5.2", - "dev": true, - "license": "MIT", - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "../../../node_modules/raw-body/node_modules/bytes": { - "version": "3.1.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, "../../../node_modules/react-is": { "version": "18.2.0", "dev": true, @@ -10183,7 +7280,10 @@ }, "../../../node_modules/readable-stream": { "version": "2.3.8", + "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -10196,16 +7296,24 @@ }, "../../../node_modules/readable-stream/node_modules/isarray": { "version": "1.0.0", - "license": "MIT" + "dev": true, + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/readable-stream/node_modules/safe-buffer": { "version": "5.1.2", - "license": "MIT" + "dev": true, + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/readdir-glob": { "version": "1.1.3", "dev": true, "license": "Apache-2.0", + "optional": true, + "peer": true, "dependencies": { "minimatch": "^5.1.0" } @@ -10214,6 +7322,8 @@ "version": "5.1.6", "dev": true, "license": "ISC", + "optional": true, + "peer": true, "dependencies": { "brace-expansion": "^2.0.1" }, @@ -10221,28 +7331,6 @@ "node": ">=10" } }, - "../../../node_modules/readdirp": { - "version": "3.6.0", - "dev": true, - "license": "MIT", - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "../../../node_modules/rechoir": { - "version": "0.8.0", - "dev": true, - "license": "MIT", - "dependencies": { - "resolve": "^1.20.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, "../../../node_modules/regexp.prototype.flags": { "version": "1.5.1", "dev": true, @@ -10259,26 +7347,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "../../../node_modules/relateurl": { - "version": "0.2.7", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.10" - } - }, - "../../../node_modules/renderkid": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "css-select": "^4.1.3", - "dom-converter": "^0.2.0", - "htmlparser2": "^6.1.0", - "lodash": "^4.17.21", - "strip-ansi": "^6.0.1" - } - }, "../../../node_modules/request": { "version": "2.88.2", "license": "Apache-2.0", @@ -10378,14 +7446,6 @@ "node": ">=0.10.0" } }, - "../../../node_modules/require-from-string": { - "version": "2.0.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "../../../node_modules/requires-port": { "version": "1.0.0", "dev": true, @@ -10393,6 +7453,7 @@ }, "../../../node_modules/resolve": { "version": "1.22.8", + "dev": true, "license": "MIT", "dependencies": { "is-core-module": "^2.13.0", @@ -10409,26 +7470,9 @@ "../../../node_modules/resolve-alpn": { "version": "1.2.1", "dev": true, - "license": "MIT" - }, - "../../../node_modules/resolve-cwd": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "../../../node_modules/resolve-cwd/node_modules/resolve-from": { - "version": "5.0.0", - "dev": true, "license": "MIT", - "engines": { - "node": ">=8" - } + "optional": true, + "peer": true }, "../../../node_modules/resolve-from": { "version": "4.0.0", @@ -10450,6 +7494,8 @@ "version": "3.0.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "lowercase-keys": "^3.0.0" }, @@ -10464,6 +7510,8 @@ "version": "1.11.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "fast-deep-equal": "^2.0.1" } @@ -10471,35 +7519,9 @@ "../../../node_modules/resq/node_modules/fast-deep-equal": { "version": "2.0.1", "dev": true, - "license": "MIT" - }, - "../../../node_modules/restore-cursor": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "../../../node_modules/restore-cursor/node_modules/signal-exit": { - "version": "3.0.7", - "dev": true, - "license": "ISC" - }, - "../../../node_modules/retry": { - "version": "0.13.1", - "dev": true, "license": "MIT", - "engines": { - "node": ">= 4" - } + "optional": true, + "peer": true }, "../../../node_modules/reusify": { "version": "1.0.4", @@ -10513,7 +7535,9 @@ "../../../node_modules/rgb2hex": { "version": "0.2.5", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/rimraf": { "version": "3.0.2", @@ -10603,17 +7627,6 @@ "fsevents": "~2.3.2" } }, - "../../../node_modules/run-applescript": { - "version": "7.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "../../../node_modules/run-parallel": { "version": "1.2.0", "dev": true, @@ -10639,7 +7652,9 @@ "../../../node_modules/safaridriver": { "version": "0.1.2", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/safe-array-concat": { "version": "1.1.0", @@ -10704,8 +7719,6 @@ "version": "5.0.1", "dev": true, "license": "ISC", - "optional": true, - "peer": true, "dependencies": { "xmlchars": "^2.2.0" }, @@ -10717,6 +7730,8 @@ "version": "3.3.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@types/json-schema": "^7.0.8", "ajv": "^6.12.5", @@ -10730,23 +7745,6 @@ "url": "https://opencollective.com/webpack" } }, - "../../../node_modules/select-hose": { - "version": "2.0.0", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/selfsigned": { - "version": "2.4.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node-forge": "^1.3.0", - "node-forge": "^1" - }, - "engines": { - "node": ">=10" - } - }, "../../../node_modules/semver": { "version": "7.5.4", "license": "ISC", @@ -10770,51 +7768,12 @@ "node": ">=10" } }, - "../../../node_modules/send": { - "version": "0.18.0", - "dev": true, - "license": "MIT", - "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" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "../../../node_modules/send/node_modules/debug": { - "version": "2.6.9", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "../../../node_modules/send/node_modules/debug/node_modules/ms": { - "version": "2.0.0", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/send/node_modules/ms": { - "version": "2.1.3", - "dev": true, - "license": "MIT" - }, "../../../node_modules/serialize-error": { "version": "11.0.3", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "type-fest": "^2.12.2" }, @@ -10829,94 +7788,12 @@ "version": "6.0.2", "dev": true, "license": "BSD-3-Clause", + "optional": true, + "peer": true, "dependencies": { "randombytes": "^2.1.0" } }, - "../../../node_modules/serve-index": { - "version": "1.9.1", - "dev": true, - "license": "MIT", - "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" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "../../../node_modules/serve-index/node_modules/debug": { - "version": "2.6.9", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "../../../node_modules/serve-index/node_modules/depd": { - "version": "1.1.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "../../../node_modules/serve-index/node_modules/http-errors": { - "version": "1.6.3", - "dev": true, - "license": "MIT", - "dependencies": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": ">= 1.4.0 < 2" - }, - "engines": { - "node": ">= 0.6" - } - }, - "../../../node_modules/serve-index/node_modules/inherits": { - "version": "2.0.3", - "dev": true, - "license": "ISC" - }, - "../../../node_modules/serve-index/node_modules/ms": { - "version": "2.0.0", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/serve-index/node_modules/setprototypeof": { - "version": "1.1.0", - "dev": true, - "license": "ISC" - }, - "../../../node_modules/serve-index/node_modules/statuses": { - "version": "1.5.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "../../../node_modules/serve-static": { - "version": "1.15.0", - "dev": true, - "license": "MIT", - "dependencies": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.18.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, "../../../node_modules/set-function-length": { "version": "1.2.0", "dev": true, @@ -10948,12 +7825,9 @@ "../../../node_modules/setimmediate": { "version": "1.0.5", "dev": true, - "license": "MIT" - }, - "../../../node_modules/setprototypeof": { - "version": "1.2.0", - "dev": true, - "license": "ISC" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/shallow-clone": { "version": "3.0.1", @@ -10974,10 +7848,6 @@ "node": ">=0.10.0" } }, - "../../../node_modules/shallow-copy": { - "version": "0.0.1", - "license": "MIT" - }, "../../../node_modules/shebang-command": { "version": "2.0.0", "license": "MIT", @@ -10995,14 +7865,6 @@ "node": ">=8" } }, - "../../../node_modules/shell-quote": { - "version": "1.8.1", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "../../../node_modules/side-channel": { "version": "1.0.4", "dev": true, @@ -11031,11 +7893,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "../../../node_modules/simple-html-tokenizer": { - "version": "0.1.1", - "dev": true, - "license": "MIT" - }, "../../../node_modules/sirv": { "version": "2.0.4", "dev": true, @@ -11049,64 +7906,26 @@ "node": ">= 10" } }, - "../../../node_modules/slash": { - "version": "3.0.0", + "../../../node_modules/smart-buffer": { + "version": "4.2.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { - "node": ">=8" + "node": ">= 6.0.0", + "npm": ">= 3.0.0" } }, - "../../../node_modules/slice-ansi": { - "version": "4.0.0", + "../../../node_modules/socks": { + "version": "2.7.3", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" - } - }, - "../../../node_modules/smart-buffer": { - "version": "4.2.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6.0.0", - "npm": ">= 3.0.0" - } - }, - "../../../node_modules/sockjs": { - "version": "0.3.24", - "dev": true, - "license": "MIT", - "dependencies": { - "faye-websocket": "^0.11.3", - "uuid": "^8.3.2", - "websocket-driver": "^0.7.4" - } - }, - "../../../node_modules/sockjs/node_modules/uuid": { - "version": "8.3.2", - "dev": true, - "license": "MIT", - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "../../../node_modules/socks": { - "version": "2.7.3", - "dev": true, - "license": "MIT", - "dependencies": { - "ip-address": "^9.0.5", - "smart-buffer": "^4.2.0" + "ip-address": "^9.0.5", + "smart-buffer": "^4.2.0" }, "engines": { "node": ">= 10.0.0", @@ -11117,6 +7936,8 @@ "version": "8.0.2", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "agent-base": "^7.0.2", "debug": "^4.3.4", @@ -11130,6 +7951,8 @@ "version": "7.1.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "debug": "^4.3.4" }, @@ -11137,15 +7960,10 @@ "node": ">= 14" } }, - "../../../node_modules/source-list-map": { - "version": "2.0.1", - "dev": true, - "license": "MIT" - }, "../../../node_modules/source-map": { "version": "0.6.1", - "devOptional": true, "license": "BSD-3-Clause", + "optional": true, "engines": { "node": ">=0.10.0" } @@ -11163,56 +7981,19 @@ "version": "0.5.21", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" } }, - "../../../node_modules/spdy": { - "version": "4.0.2", - "dev": true, - "license": "MIT", - "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" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "../../../node_modules/spdy-transport": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "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_modules/spdy-transport/node_modules/readable-stream": { - "version": "3.6.2", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "../../../node_modules/split2": { "version": "4.2.0", "dev": true, "license": "ISC", + "optional": true, + "peer": true, "engines": { "node": ">= 10.x" } @@ -11220,7 +8001,9 @@ "../../../node_modules/sprintf-js": { "version": "1.1.3", "dev": true, - "license": "BSD-3-Clause" + "license": "BSD-3-Clause", + "optional": true, + "peer": true }, "../../../node_modules/sshpk": { "version": "1.18.0", @@ -11250,159 +8033,11 @@ "dev": true, "license": "MIT" }, - "../../../node_modules/static-eval": { - "version": "2.1.1", - "license": "MIT", - "dependencies": { - "escodegen": "^2.1.0" - } - }, - "../../../node_modules/static-module": { - "version": "2.2.5", - "license": "MIT", - "dependencies": { - "concat-stream": "~1.6.0", - "convert-source-map": "^1.5.1", - "duplexer2": "~0.1.4", - "escodegen": "~1.9.0", - "falafel": "^2.1.0", - "has": "^1.0.1", - "magic-string": "^0.22.4", - "merge-source-map": "1.0.4", - "object-inspect": "~1.4.0", - "quote-stream": "~1.0.2", - "readable-stream": "~2.3.3", - "shallow-copy": "~0.0.1", - "static-eval": "^2.0.0", - "through2": "~2.0.3" - } - }, - "../../../node_modules/static-module/node_modules/escodegen": { - "version": "1.9.1", - "license": "BSD-2-Clause", - "dependencies": { - "esprima": "^3.1.3", - "estraverse": "^4.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1" - }, - "bin": { - "escodegen": "bin/escodegen.js", - "esgenerate": "bin/esgenerate.js" - }, - "engines": { - "node": ">=4.0" - }, - "optionalDependencies": { - "source-map": "~0.6.1" - } - }, - "../../../node_modules/static-module/node_modules/esprima": { - "version": "3.1.3", - "license": "BSD-2-Clause", - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "../../../node_modules/static-module/node_modules/estraverse": { - "version": "4.3.0", - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, - "../../../node_modules/static-module/node_modules/levn": { - "version": "0.3.0", - "license": "MIT", - "dependencies": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "../../../node_modules/static-module/node_modules/magic-string": { - "version": "0.22.5", - "license": "MIT", - "dependencies": { - "vlq": "^0.2.2" - } - }, - "../../../node_modules/static-module/node_modules/object-inspect": { - "version": "1.4.1", - "license": "MIT" - }, - "../../../node_modules/static-module/node_modules/optionator": { - "version": "0.8.3", - "license": "MIT", - "dependencies": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "../../../node_modules/static-module/node_modules/prelude-ls": { - "version": "1.1.2", - "engines": { - "node": ">= 0.8.0" - } - }, - "../../../node_modules/static-module/node_modules/through2": { - "version": "2.0.5", - "license": "MIT", - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "../../../node_modules/static-module/node_modules/type-check": { - "version": "0.3.2", - "license": "MIT", - "dependencies": { - "prelude-ls": "~1.1.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "../../../node_modules/statuses": { - "version": "2.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, "../../../node_modules/std-env": { "version": "3.7.0", "dev": true, "license": "MIT" }, - "../../../node_modules/stdin-discarder": { - "version": "0.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "bl": "^5.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "../../../node_modules/stealthy-require": { "version": "1.1.1", "license": "ISC", @@ -11414,6 +8049,8 @@ "version": "2.15.6", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "fast-fifo": "^1.1.0", "queue-tick": "^1.0.1" @@ -11421,14 +8058,20 @@ }, "../../../node_modules/string_decoder": { "version": "1.1.1", + "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "safe-buffer": "~5.1.0" } }, "../../../node_modules/string_decoder/node_modules/safe-buffer": { "version": "5.1.2", - "license": "MIT" + "dev": true, + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/string-width": { "version": "5.1.2", @@ -11594,21 +8237,6 @@ "dev": true, "license": "MIT" }, - "../../../node_modules/style-loader": { - "version": "3.3.4", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.0.0" - } - }, "../../../node_modules/supports-color": { "version": "7.2.0", "dev": true, @@ -11620,20 +8248,9 @@ "node": ">=8" } }, - "../../../node_modules/supports-hyperlinks": { - "version": "2.3.0", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0", - "supports-color": "^7.0.0" - }, - "engines": { - "node": ">=8" - } - }, "../../../node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -11642,112 +8259,27 @@ "url": "https://github.com/sponsors/ljharb" } }, - "../../../node_modules/svg-inline-loader": { - "version": "0.8.2", + "../../../node_modules/symbol-tree": { + "version": "3.2.4", + "license": "MIT" + }, + "../../../node_modules/tapable": { + "version": "2.2.1", "dev": true, "license": "MIT", - "dependencies": { - "loader-utils": "^1.1.0", - "object-assign": "^4.0.1", - "simple-html-tokenizer": "^0.1.1" + "engines": { + "node": ">=6" } }, - "../../../node_modules/svg-inline-loader/node_modules/json5": { - "version": "1.0.2", + "../../../node_modules/tar-fs": { + "version": "3.0.5", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" - } - }, - "../../../node_modules/svg-inline-loader/node_modules/loader-utils": { - "version": "1.4.2", - "dev": true, - "license": "MIT", - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "../../../node_modules/symbol-tree": { - "version": "3.2.4", - "license": "MIT" - }, - "../../../node_modules/table": { - "version": "6.8.1", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "ajv": "^8.0.1", - "lodash.truncate": "^4.4.2", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "../../../node_modules/table/node_modules/ajv": { - "version": "8.12.0", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "../../../node_modules/table/node_modules/emoji-regex": { - "version": "8.0.0", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/table/node_modules/json-schema-traverse": { - "version": "1.0.0", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/table/node_modules/string-width": { - "version": "4.2.3", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "../../../node_modules/tapable": { - "version": "2.2.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "../../../node_modules/tar-fs": { - "version": "3.0.5", - "dev": true, - "license": "MIT", - "dependencies": { - "pump": "^3.0.0", - "tar-stream": "^3.1.5" + "pump": "^3.0.0", + "tar-stream": "^3.1.5" }, "optionalDependencies": { "bare-fs": "^2.1.1", @@ -11758,31 +8290,20 @@ "version": "3.1.7", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "b4a": "^1.6.4", "fast-fifo": "^1.2.0", "streamx": "^2.15.0" } }, - "../../../node_modules/terminal-link": { - "version": "3.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-escapes": "^5.0.0", - "supports-hyperlinks": "^2.2.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "../../../node_modules/terser": { "version": "5.29.1", "dev": true, "license": "BSD-2-Clause", + "optional": true, + "peer": true, "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.8.2", @@ -11800,6 +8321,8 @@ "version": "5.3.10", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@jridgewell/trace-mapping": "^0.3.20", "jest-worker": "^27.4.5", @@ -11832,7 +8355,9 @@ "../../../node_modules/terser/node_modules/commander": { "version": "2.20.3", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "../../../node_modules/text-table": { "version": "0.2.0", @@ -11842,38 +8367,9 @@ "../../../node_modules/through": { "version": "2.3.8", "dev": true, - "license": "MIT" - }, - "../../../node_modules/through2": { - "version": "0.6.5", - "license": "MIT", - "dependencies": { - "readable-stream": ">=1.0.33-1 <1.1.0-0", - "xtend": ">=4.0.0 <4.1.0-0" - } - }, - "../../../node_modules/through2/node_modules/isarray": { - "version": "0.0.1", - "license": "MIT" - }, - "../../../node_modules/through2/node_modules/readable-stream": { - "version": "1.0.34", "license": "MIT", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "../../../node_modules/through2/node_modules/string_decoder": { - "version": "0.10.31", - "license": "MIT" - }, - "../../../node_modules/thunky": { - "version": "1.1.0", - "dev": true, - "license": "MIT" + "optional": true, + "peer": true }, "../../../node_modules/tinybench": { "version": "2.6.0", @@ -11907,14 +8403,6 @@ "node": ">=8.0" } }, - "../../../node_modules/toidentifier": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.6" - } - }, "../../../node_modules/totalist": { "version": "3.0.1", "dev": true, @@ -11927,8 +8415,6 @@ "version": "4.1.3", "dev": true, "license": "BSD-3-Clause", - "optional": true, - "peer": true, "dependencies": { "psl": "^1.1.33", "punycode": "^2.1.1", @@ -11943,8 +8429,6 @@ "version": "2.1.0", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "dependencies": { "punycode": "^2.1.1" }, @@ -11955,18 +8439,9 @@ "../../../node_modules/traverse": { "version": "0.3.9", "dev": true, - "license": "MIT/X11" - }, - "../../../node_modules/ts-api-utils": { - "version": "1.2.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=16" - }, - "peerDependencies": { - "typescript": ">=4.2.0" - } + "license": "MIT/X11", + "optional": true, + "peer": true }, "../../../node_modules/tsconfig-paths": { "version": "3.15.0", @@ -11993,7 +8468,9 @@ "../../../node_modules/tslib": { "version": "2.6.2", "dev": true, - "license": "0BSD" + "license": "0BSD", + "optional": true, + "peer": true }, "../../../node_modules/tsx": { "version": "4.7.1", @@ -12454,6 +8931,8 @@ "version": "2.19.0", "dev": true, "license": "(MIT OR CC0-1.0)", + "optional": true, + "peer": true, "engines": { "node": ">=12.20" }, @@ -12461,18 +8940,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "../../../node_modules/type-is": { - "version": "1.6.18", - "dev": true, - "license": "MIT", - "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - }, - "engines": { - "node": ">= 0.6" - } - }, "../../../node_modules/typed-array-buffer": { "version": "1.0.0", "dev": true, @@ -12534,10 +9001,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "../../../node_modules/typedarray": { - "version": "0.0.6", - "license": "MIT" - }, "../../../node_modules/typescript": { "version": "5.3.3", "dev": true, @@ -12573,6 +9036,8 @@ "version": "1.4.3", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "buffer": "^5.2.1", "through": "^2.3.8" @@ -12596,6 +9061,8 @@ } ], "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" @@ -12610,24 +9077,16 @@ "version": "0.2.0", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "engines": { "node": ">= 4.0.0" } }, - "../../../node_modules/unpipe": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, "../../../node_modules/unzipper": { "version": "0.10.14", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "big-integer": "^1.6.17", "binary": "~0.3.0", @@ -12659,6 +9118,8 @@ } ], "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "escalade": "^3.1.1", "picocolors": "^1.0.0" @@ -12681,8 +9142,6 @@ "version": "1.5.10", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "dependencies": { "querystringify": "^2.1.1", "requires-port": "^1.0.0" @@ -12691,27 +9150,17 @@ "../../../node_modules/userhome": { "version": "1.0.0", "dev": true, + "optional": true, + "peer": true, "engines": { "node": ">= 0.8.0" } }, "../../../node_modules/util-deprecate": { "version": "1.0.2", - "license": "MIT" - }, - "../../../node_modules/utila": { - "version": "0.4.0", "dev": true, "license": "MIT" }, - "../../../node_modules/utils-merge": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4.0" - } - }, "../../../node_modules/uuid": { "version": "3.4.0", "license": "MIT", @@ -12719,14 +9168,6 @@ "uuid": "bin/uuid" } }, - "../../../node_modules/vary": { - "version": "1.1.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, "../../../node_modules/verror": { "version": "1.10.0", "engines": [ @@ -12945,10 +9386,6 @@ "node": ">=0.4.0" } }, - "../../../node_modules/vlq": { - "version": "0.2.3", - "license": "MIT" - }, "../../../node_modules/w3c-hr-time": { "version": "1.0.2", "license": "MIT", @@ -12960,8 +9397,6 @@ "version": "2.0.0", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "dependencies": { "xml-name-validator": "^3.0.0" }, @@ -12973,6 +9408,8 @@ "version": "1.1.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "chalk": "^4.1.2", "commander": "^9.3.0", @@ -12989,6 +9426,8 @@ "version": "2.4.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.1.2" @@ -12997,26 +9436,12 @@ "node": ">=10.13.0" } }, - "../../../node_modules/wbuf": { - "version": "1.7.3", - "dev": true, - "license": "MIT", - "dependencies": { - "minimalistic-assert": "^1.0.0" - } - }, - "../../../node_modules/wcwidth": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "defaults": "^1.0.3" - } - }, "../../../node_modules/web-streams-polyfill": { "version": "3.3.3", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">= 8" } @@ -13025,6 +9450,8 @@ "version": "8.32.3", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@types/node": "^20.1.0", "@types/ws": "^8.5.3", @@ -13046,6 +9473,8 @@ "version": "8.32.3", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@types/node": "^20.1.0", "@wdio/config": "8.32.3", @@ -13078,390 +9507,136 @@ "peerDependencies": { "devtools": "^8.14.0" }, - "peerDependenciesMeta": { - "devtools": { - "optional": true - } - } - }, - "../../../node_modules/webidl-conversions": { - "version": "6.1.0", - "dev": true, - "license": "BSD-2-Clause", - "optional": true, - "peer": true, - "engines": { - "node": ">=10.4" - } - }, - "../../../node_modules/webpack": { - "version": "5.90.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/eslint-scope": "^3.7.3", - "@types/estree": "^1.0.5", - "@webassemblyjs/ast": "^1.11.5", - "@webassemblyjs/wasm-edit": "^1.11.5", - "@webassemblyjs/wasm-parser": "^1.11.5", - "acorn": "^8.7.1", - "acorn-import-assertions": "^1.9.0", - "browserslist": "^4.21.10", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.15.0", - "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.9", - "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": "^3.2.0", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.3.10", - "watchpack": "^2.4.0", - "webpack-sources": "^3.2.3" - }, - "bin": { - "webpack": "bin/webpack.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependenciesMeta": { - "webpack-cli": { - "optional": true - } - } - }, - "../../../node_modules/webpack-bundle-analyzer": { - "version": "4.10.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@discoveryjs/json-ext": "0.5.7", - "acorn": "^8.0.4", - "acorn-walk": "^8.0.0", - "commander": "^7.2.0", - "debounce": "^1.2.1", - "escape-string-regexp": "^4.0.0", - "gzip-size": "^6.0.0", - "html-escaper": "^2.0.2", - "is-plain-object": "^5.0.0", - "opener": "^1.5.2", - "picocolors": "^1.0.0", - "sirv": "^2.0.3", - "ws": "^7.3.1" - }, - "bin": { - "webpack-bundle-analyzer": "lib/bin/analyzer.js" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "../../../node_modules/webpack-bundle-analyzer/node_modules/acorn-walk": { - "version": "8.3.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, - "../../../node_modules/webpack-bundle-analyzer/node_modules/commander": { - "version": "7.2.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 10" - } - }, - "../../../node_modules/webpack-bundle-analyzer/node_modules/is-plain-object": { - "version": "5.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "../../../node_modules/webpack-bundle-analyzer/node_modules/ws": { - "version": "7.5.9", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "../../../node_modules/webpack-cli": { - "version": "5.1.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@discoveryjs/json-ext": "^0.5.0", - "@webpack-cli/configtest": "^2.1.1", - "@webpack-cli/info": "^2.0.2", - "@webpack-cli/serve": "^2.0.5", - "colorette": "^2.0.14", - "commander": "^10.0.1", - "cross-spawn": "^7.0.3", - "envinfo": "^7.7.3", - "fastest-levenshtein": "^1.0.12", - "import-local": "^3.0.2", - "interpret": "^3.1.1", - "rechoir": "^0.8.0", - "webpack-merge": "^5.7.3" - }, - "bin": { - "webpack-cli": "bin/cli.js" - }, - "engines": { - "node": ">=14.15.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "5.x.x" - }, - "peerDependenciesMeta": { - "@webpack-cli/generators": { - "optional": true - }, - "webpack-bundle-analyzer": { - "optional": true - }, - "webpack-dev-server": { - "optional": true - } - } - }, - "../../../node_modules/webpack-cli/node_modules/commander": { - "version": "10.0.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14" - } - }, - "../../../node_modules/webpack-dev-middleware": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-7.1.1.tgz", - "integrity": "sha512-NmRVq4AvRQs66dFWyDR4GsFDJggtSi2Yn38MXLk0nffgF9n/AIP4TFBg2TQKYaRAN4sHuKOTiz9BnNCENDLEVA==", - "dev": true, - "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" - }, - "engines": { - "node": ">= 18.12.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.0.0" - }, - "peerDependenciesMeta": { - "webpack": { - "optional": true - } - } - }, - "../../../node_modules/webpack-dev-middleware/node_modules/ajv": { - "version": "8.12.0", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "../../../node_modules/webpack-dev-middleware/node_modules/ajv-keywords": { - "version": "5.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, - "../../../node_modules/webpack-dev-middleware/node_modules/json-schema-traverse": { - "version": "1.0.0", - "dev": true, - "license": "MIT" - }, - "../../../node_modules/webpack-dev-middleware/node_modules/schema-utils": { - "version": "4.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.9.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.1.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "../../../node_modules/webpack-dev-server": { - "version": "5.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/bonjour": "^3.5.13", - "@types/connect-history-api-fallback": "^1.5.4", - "@types/express": "^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", - "default-gateway": "^6.0.3", - "express": "^4.17.3", - "graceful-fs": "^4.2.6", - "html-entities": "^2.4.0", - "http-proxy-middleware": "^2.0.3", - "ipaddr.js": "^2.1.0", - "launch-editor": "^2.6.1", - "open": "^10.0.3", - "p-retry": "^6.2.0", - "rimraf": "^5.0.5", - "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.0.0", - "ws": "^8.16.0" - }, + "peerDependenciesMeta": { + "devtools": { + "optional": true + } + } + }, + "../../../node_modules/webidl-conversions": { + "version": "6.1.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=10.4" + } + }, + "../../../node_modules/webpack": { + "version": "5.90.3", + "dev": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@types/eslint-scope": "^3.7.3", + "@types/estree": "^1.0.5", + "@webassemblyjs/ast": "^1.11.5", + "@webassemblyjs/wasm-edit": "^1.11.5", + "@webassemblyjs/wasm-parser": "^1.11.5", + "acorn": "^8.7.1", + "acorn-import-assertions": "^1.9.0", + "browserslist": "^4.21.10", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.15.0", + "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.9", + "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": "^3.2.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.10", + "watchpack": "^2.4.0", + "webpack-sources": "^3.2.3" + }, "bin": { - "webpack-dev-server": "bin/webpack-dev-server.js" + "webpack": "bin/webpack.js" }, "engines": { - "node": ">= 18.12.0" + "node": ">=10.13.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/webpack" }, - "peerDependencies": { - "webpack": "^5.0.0" - }, "peerDependenciesMeta": { - "webpack": { - "optional": true - }, "webpack-cli": { "optional": true } } }, - "../../../node_modules/webpack-dev-server/node_modules/ajv": { - "version": "8.12.0", + "../../../node_modules/webpack-bundle-analyzer": { + "version": "4.10.1", "dev": true, "license": "MIT", "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" + "@discoveryjs/json-ext": "0.5.7", + "acorn": "^8.0.4", + "acorn-walk": "^8.0.0", + "commander": "^7.2.0", + "debounce": "^1.2.1", + "escape-string-regexp": "^4.0.0", + "gzip-size": "^6.0.0", + "html-escaper": "^2.0.2", + "is-plain-object": "^5.0.0", + "opener": "^1.5.2", + "picocolors": "^1.0.0", + "sirv": "^2.0.3", + "ws": "^7.3.1" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "bin": { + "webpack-bundle-analyzer": "lib/bin/analyzer.js" + }, + "engines": { + "node": ">= 10.13.0" } }, - "../../../node_modules/webpack-dev-server/node_modules/ajv-keywords": { - "version": "5.1.0", + "../../../node_modules/webpack-bundle-analyzer/node_modules/acorn-walk": { + "version": "8.3.2", "dev": true, "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" + "engines": { + "node": ">=0.4.0" } }, - "../../../node_modules/webpack-dev-server/node_modules/json-schema-traverse": { - "version": "1.0.0", + "../../../node_modules/webpack-bundle-analyzer/node_modules/commander": { + "version": "7.2.0", "dev": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": ">= 10" + } }, - "../../../node_modules/webpack-dev-server/node_modules/rimraf": { - "version": "5.0.5", + "../../../node_modules/webpack-bundle-analyzer/node_modules/is-plain-object": { + "version": "5.0.0", "dev": true, - "license": "ISC", - "dependencies": { - "glob": "^10.3.7" - }, - "bin": { - "rimraf": "dist/esm/bin.mjs" - }, + "license": "MIT", "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": ">=0.10.0" } }, - "../../../node_modules/webpack-dev-server/node_modules/schema-utils": { - "version": "4.2.0", + "../../../node_modules/webpack-bundle-analyzer/node_modules/ws": { + "version": "7.5.9", "dev": true, "license": "MIT", - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.9.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.1.0" - }, "engines": { - "node": ">= 12.13.0" + "node": ">=8.3.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } } }, "../../../node_modules/webpack-merge": { @@ -13477,19 +9652,12 @@ "node": ">=10.0.0" } }, - "../../../node_modules/webpack-sources": { - "version": "1.4.3", - "dev": true, - "license": "MIT", - "dependencies": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" - } - }, "../../../node_modules/webpack/node_modules/eslint-scope": { "version": "5.1.1", "dev": true, "license": "BSD-2-Clause", + "optional": true, + "peer": true, "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^4.1.1" @@ -13502,6 +9670,8 @@ "version": "4.3.0", "dev": true, "license": "BSD-2-Clause", + "optional": true, + "peer": true, "engines": { "node": ">=4.0" } @@ -13510,6 +9680,8 @@ "version": "3.3.0", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=0.8.x" } @@ -13518,31 +9690,12 @@ "version": "3.2.3", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "engines": { "node": ">=10.13.0" } }, - "../../../node_modules/websocket-driver": { - "version": "0.7.4", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "http-parser-js": ">=0.5.1", - "safe-buffer": ">=5.1.0", - "websocket-extensions": ">=0.1.1" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "../../../node_modules/websocket-extensions": { - "version": "0.1.4", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=0.8.0" - } - }, "../../../node_modules/whatwg-encoding": { "version": "1.0.5", "license": "MIT", @@ -13558,8 +9711,6 @@ "version": "9.1.0", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "dependencies": { "tr46": "^2.1.0", "webidl-conversions": "^6.1.0" @@ -13629,20 +9780,6 @@ "node": ">=8" } }, - "../../../node_modules/widest-line": { - "version": "4.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "string-width": "^5.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "../../../node_modules/wildcard": { "version": "2.0.1", "dev": true, @@ -13767,9 +9904,7 @@ "../../../node_modules/xmlchars": { "version": "2.2.0", "dev": true, - "license": "MIT", - "optional": true, - "peer": true + "license": "MIT" }, "../../../node_modules/xmldom": { "version": "0.1.31", @@ -13778,13 +9913,6 @@ "node": ">=0.1" } }, - "../../../node_modules/xtend": { - "version": "4.0.2", - "license": "MIT", - "engines": { - "node": ">=0.4" - } - }, "../../../node_modules/y18n": { "version": "5.0.8", "dev": true, @@ -13797,14 +9925,6 @@ "version": "4.0.0", "license": "ISC" }, - "../../../node_modules/yaml": { - "version": "1.10.2", - "dev": true, - "license": "ISC", - "engines": { - "node": ">= 6" - } - }, "../../../node_modules/yargs": { "version": "17.7.2", "dev": true, @@ -13872,6 +9992,8 @@ "version": "5.0.1", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "archiver-utils": "^4.0.1", "compress-commons": "^5.0.1", @@ -13885,6 +10007,8 @@ "version": "3.6.2", "dev": true, "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -16609,17 +12733,6 @@ "dev": true, "license": "MIT" }, - "node_modules/json5": { - "version": "1.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" - } - }, "node_modules/kind-of": { "version": "6.0.3", "dev": true, @@ -16645,19 +12758,6 @@ "node": ">=6.11.5" } }, - "node_modules/loader-utils": { - "version": "1.4.2", - "dev": true, - "license": "MIT", - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - }, - "engines": { - "node": ">=4.0.0" - } - }, "node_modules/locate-path": { "version": "5.0.0", "dev": true, @@ -16804,14 +12904,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/minimist": { - "version": "1.2.8", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/minipass": { "version": "7.0.4", "dev": true, @@ -16923,14 +13015,6 @@ "url": "https://github.com/fb55/nth-check?sponsor=1" } }, - "node_modules/object-assign": { - "version": "4.1.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/object-inspect": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", @@ -17757,11 +13841,6 @@ "dev": true, "license": "ISC" }, - "node_modules/simple-html-tokenizer": { - "version": "0.1.1", - "dev": true, - "license": "MIT" - }, "node_modules/sockjs": { "version": "0.3.24", "dev": true, @@ -18020,16 +14099,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/svg-inline-loader": { - "version": "0.8.2", - "dev": true, - "license": "MIT", - "dependencies": { - "loader-utils": "^1.1.0", - "object-assign": "^4.0.1", - "simple-html-tokenizer": "^0.1.1" - } - }, "node_modules/tapable": { "version": "2.2.1", "dev": true, diff --git a/examples/webpack/webpack-project-source/package.json b/examples/webpack/webpack-project-source/package.json index 3be4ac1393..910d2524ea 100644 --- a/examples/webpack/webpack-project-source/package.json +++ b/examples/webpack/webpack-project-source/package.json @@ -19,7 +19,6 @@ "devDependencies": { "css-loader": "^7.1.2", "style-loader": "^4.0.0", - "svg-inline-loader": "^0.8.2", "esbuild-loader": "^4.2.2", "html-webpack-plugin": "^5.6.0", "webpack": "^5.93.0", diff --git a/ngauth_server/.gitignore b/ngauth_server/.gitignore index 6ea7ac4955..56c6e9f6d7 100644 --- a/ngauth_server/.gitignore +++ b/ngauth_server/.gitignore @@ -1,2 +1,3 @@ .envrc /secrets +/ngauth diff --git a/ngauth_server/go.mod b/ngauth_server/go.mod index 600017f987..a9b29cac17 100644 --- a/ngauth_server/go.mod +++ b/ngauth_server/go.mod @@ -22,9 +22,9 @@ require ( github.com/google/go-cmp v0.5.9 // indirect github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect go.opencensus.io v0.24.0 // indirect - golang.org/x/net v0.23.0 // indirect - golang.org/x/sys v0.18.0 // indirect - golang.org/x/text v0.14.0 // indirect + golang.org/x/net v0.33.0 // indirect + golang.org/x/sys v0.28.0 // indirect + golang.org/x/text v0.21.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/grpc v1.56.3 // indirect ) diff --git a/ngauth_server/go.sum b/ngauth_server/go.sum index 54f4b5e72d..dc233604da 100644 --- a/ngauth_server/go.sum +++ b/ngauth_server/go.sum @@ -79,8 +79,8 @@ golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= -golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= +golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.7.0 h1:qe6s0zUXlPX80/dITx3440hWZ7GwMwgDDyrSGTPJG/g= golang.org/x/oauth2 v0.7.0/go.mod h1:hPLQkd9LyjfXTiRohC/41GhcFqxisoUQ99sCUOHO9x4= @@ -91,13 +91,13 @@ golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= -golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= diff --git a/package-lock.json b/package-lock.json index 86d4707d0d..52a790c9e3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,53 +10,63 @@ "license": "Apache-2.0", "dependencies": { "codemirror": "^5.61.1", + "core-js": "^3.40.0", + "crc-32": "^1.2.2", "gl-matrix": "3.1.0", - "glsl-editor": "^1.0.0", "ikonate": "github:mikolajdobrucki/ikonate#a86b4107c6ec717e7877f880a930d1ccf0b59d89", "lodash-es": "^4.17.21", "nifti-reader-js": "^0.6.8", - "numcodecs": "^0.3.2", - "pako": "^2.1.0" + "numcodecs": "^0.3.2" }, "devDependencies": { + "@eslint/js": "^9.18.0", + "@iodigital/vite-plugin-msw": "^2.0.0", + "@playwright/browser-chromium": "^1.49.1", + "@rspack/cli": "^1.1.8", + "@rspack/core": "^1.1.8", "@types/codemirror": "5.60.15", "@types/gl-matrix": "^2.4.5", + "@types/http-server": "^0.12.4", + "@types/jsdom": "^21.1.7", "@types/lodash-es": "^4.17.12", - "@types/node": "^20.14.12", - "@types/pako": "^2.0.3", - "@types/yargs": "^17.0.32", - "@typescript-eslint/eslint-plugin": "^7.17.0", - "@typescript-eslint/parser": "^7.17.0", - "@vitest/browser": "^2.0.4", - "@vitest/ui": "^2.0.4", + "@types/node": "^22.10.7", + "@types/nunjucks": "^3.2.6", + "@types/s3rver": "^3.7.4", + "@types/yargs": "^17.0.33", + "@vitest/browser": "^3.0.2", + "@vitest/ui": "^3.0.2", + "@vitest/web-worker": "^3.0.2", + "cookie": "^1.0.2", "css-loader": "^7.1.2", - "esbuild": "^0.23.0", - "esbuild-loader": "^4.2.2", - "eslint": "^8.56.0", + "esbuild": "^0.24.2", + "eslint": "^9.18.0", "eslint-formatter-codeframe": "^7.32.1", - "eslint-import-resolver-typescript": "^3.6.1", - "eslint-interactive": "^10.8.0", - "eslint-plugin-import": "^2.29.1", - "eslint-webpack-plugin": "^4.0.1", - "fork-ts-checker-webpack-plugin": "^6.5.3", - "glob": "^11.0.0", - "html-webpack-plugin": "^5.6.0", - "mini-css-extract-plugin": "^2.9.0", - "prettier": "3.3.3", - "style-loader": "^4.0.0", - "svg-inline-loader": "^0.8.2", - "tsx": "^4.16.2", - "typescript": "^5.5.4", - "vitest": "^2.0.4", - "webdriverio": "^8.39.1", - "webpack": "^5.93.0", + "eslint-import-resolver-typescript": "^3.7.0", + "eslint-plugin-import": "^2.31.0", + "eslint-plugin-oxlint": "^0.15.7", + "eslint-rspack-plugin": "^4.2.1", + "express": "^4.21.2", + "glob": "^11.0.1", + "http-server": "^14.1.1", + "jsdom": "^26.0.0", + "msw": "^2.7.0", + "nunjucks": "^3.2.4", + "oxlint": "^0.15.7", + "playwright": "^1.49.1", + "prettier": "3.4.2", + "s3rver": "^3.7.1", + "ts-checker-rspack-plugin": "^1.1.1", + "tsx": "^4.19.2", + "typescript": "^5.7.3", + "typescript-eslint": "^8.20.0", + "vitest": "^3.0.2", "webpack-bundle-analyzer": "^4.10.2", - "webpack-cli": "^5.1.4", - "webpack-dev-server": "^5.0.4", - "webpack-merge": "^6.0.1" + "webpack-merge": "^6.0.1", + "yargs": "^17.7.2", + "yauzl": "^3.2.0" }, "engines": { - "node": ">=20.10 <21 || >=21.2" + "node": ">=22" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -68,46 +78,61 @@ "node": ">=0.10.0" } }, - "node_modules/@ampproject/remapping": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", - "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "node_modules/@asamuzakjp/css-color": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-2.8.3.tgz", + "integrity": "sha512-GIc76d9UI1hCvOATjZPyHFmE5qhRccp3/zGfMPapK3jBi+yocEzp6BBB0UnfRYP9NP4FANqUZYb0hnfs3TM3hw==", "dev": true, + "license": "MIT", "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" + "@csstools/css-calc": "^2.1.1", + "@csstools/css-color-parser": "^3.0.7", + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3", + "lru-cache": "^10.4.3" } }, + "node_modules/@asamuzakjp/css-color/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, + "license": "ISC" + }, "node_modules/@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", + "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", "dev": true, "dependencies": { - "@babel/highlight": "^7.10.4" + "@babel/helper-validator-identifier": "^7.25.9", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", - "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", - "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.25.9.tgz", + "integrity": "sha512-llL88JShoCsth8fF8R4SJnIn+WLvR6ccFxu1H3FlMhDontdcmZWf2HgIZ7AIqV3Xcck1idlohrN4EUBQz6klbw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.22.20", + "@babel/helper-validator-identifier": "^7.25.9", "chalk": "^2.4.2", - "js-tokens": "^4.0.0" + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" }, "engines": { "node": ">=6.9.0" @@ -118,6 +143,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, + "license": "MIT", "dependencies": { "color-convert": "^1.9.0" }, @@ -130,6 +156,7 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -144,6 +171,7 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, + "license": "MIT", "dependencies": { "color-name": "1.1.3" } @@ -152,13 +180,15 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@babel/highlight/node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8.0" } @@ -168,6 +198,7 @@ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -177,6 +208,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^3.0.0" }, @@ -185,10 +217,11 @@ } }, "node_modules/@babel/runtime": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.8.tgz", - "integrity": "sha512-5F7SDGs1T72ZczbRwbGO9lQi0NLjQxzl6i4lJxLxfW9U5UluCSyEJeniWvnhl3/euNiqQVbo8zruhsDfid0esA==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.0.tgz", + "integrity": "sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==", "dev": true, + "license": "MIT", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -197,19 +230,20 @@ } }, "node_modules/@bundled-es-modules/cookie": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@bundled-es-modules/cookie/-/cookie-2.0.0.tgz", - "integrity": "sha512-Or6YHg/kamKHpxULAdSqhGqnWFneIXu1NKvvfBBzKGwpVsYuFIQ5aBPHDnnoR3ghW1nvSkALd+EF9iMtY7Vjxw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@bundled-es-modules/cookie/-/cookie-2.0.1.tgz", + "integrity": "sha512-8o+5fRPLNbjbdGRRmJj3h6Hh1AQJf2dk3qQ/5ZFb+PXkRNiSoMGGUKlsgLfrxneb72axVJyIYji64E2+nNfYyw==", "dev": true, "dependencies": { - "cookie": "^0.5.0" + "cookie": "^0.7.2" } }, "node_modules/@bundled-es-modules/cookie/node_modules/cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -233,6 +267,141 @@ "tough-cookie": "^4.1.4" } }, + "node_modules/@colors/colors": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz", + "integrity": "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==", + "dev": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/@csstools/color-helpers": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.0.1.tgz", + "integrity": "sha512-MKtmkA0BX87PKaO1NFRTFH+UnkgnmySQOvNxJubsadusqPEC2aJ9MOQiMceZJJ6oitUl/i0L6u0M1IrmAOmgBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + } + }, + "node_modules/@csstools/css-calc": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.1.tgz", + "integrity": "sha512-rL7kaUnTkL9K+Cvo2pnCieqNpTKgQzy5f+N+5Iuko9HAoasP+xgprVh7KN/MaJVvVL1l0EzQq2MoqBHKSrDrag==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3" + } + }, + "node_modules/@csstools/css-color-parser": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.0.7.tgz", + "integrity": "sha512-nkMp2mTICw32uE5NN+EsJ4f5N+IGFeCFu4bGpiKgb2Pq/7J/MpyLBeQ5ry4KKtRFZaYs6sTmcMYrSRIyj5DFKA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "@csstools/color-helpers": "^5.0.1", + "@csstools/css-calc": "^2.1.1" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3" + } + }, + "node_modules/@csstools/css-parser-algorithms": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.4.tgz", + "integrity": "sha512-Up7rBoV77rv29d3uKHUIVubz1BTcgyUK72IvCQAbfbMv584xHcGKCKbWh7i8hPrRJ7qU4Y8IO3IY9m+iTB7P3A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-tokenizer": "^3.0.3" + } + }, + "node_modules/@csstools/css-tokenizer": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.3.tgz", + "integrity": "sha512-UJnjoFsmxfKUdNYdWgOB0mWUypuLvAfQPH1+pyvRJs6euowbFkFC6P13w1l8mJyi3vxYMxc9kld5jZEGRQs6bw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@dabh/diagnostics": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.3.tgz", + "integrity": "sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==", + "dev": true, + "dependencies": { + "colorspace": "1.1.x", + "enabled": "2.0.x", + "kuler": "^2.0.0" + } + }, "node_modules/@discoveryjs/json-ext": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", @@ -243,13 +412,14 @@ } }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.23.0.tgz", - "integrity": "sha512-3sG8Zwa5fMcA9bgqB8AfWPQ+HFke6uD3h1s3RIwUNK8EG7a4buxvuFTs3j1IMs2NXAk9F30C/FF4vxRgQCcmoQ==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.24.2.tgz", + "integrity": "sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA==", "cpu": [ "ppc64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "aix" @@ -259,13 +429,14 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.23.0.tgz", - "integrity": "sha512-+KuOHTKKyIKgEEqKbGTK8W7mPp+hKinbMBeEnNzjJGyFcWsfrXjSTNluJHCY1RqhxFurdD8uNXQDei7qDlR6+g==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.24.2.tgz", + "integrity": "sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q==", "cpu": [ "arm" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "android" @@ -275,13 +446,14 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.23.0.tgz", - "integrity": "sha512-EuHFUYkAVfU4qBdyivULuu03FhJO4IJN9PGuABGrFy4vUuzk91P2d+npxHcFdpUnfYKy0PuV+n6bKIpHOB3prQ==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.24.2.tgz", + "integrity": "sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "android" @@ -291,13 +463,14 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.23.0.tgz", - "integrity": "sha512-WRrmKidLoKDl56LsbBMhzTTBxrsVwTKdNbKDalbEZr0tcsBgCLbEtoNthOW6PX942YiYq8HzEnb4yWQMLQuipQ==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.24.2.tgz", + "integrity": "sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "android" @@ -307,13 +480,14 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.23.0.tgz", - "integrity": "sha512-YLntie/IdS31H54Ogdn+v50NuoWF5BDkEUFpiOChVa9UnKpftgwzZRrI4J132ETIi+D8n6xh9IviFV3eXdxfow==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.24.2.tgz", + "integrity": "sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -323,13 +497,14 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.23.0.tgz", - "integrity": "sha512-IMQ6eme4AfznElesHUPDZ+teuGwoRmVuuixu7sv92ZkdQcPbsNHzutd+rAfaBKo8YK3IrBEi9SLLKWJdEvJniQ==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.24.2.tgz", + "integrity": "sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -339,13 +514,14 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.23.0.tgz", - "integrity": "sha512-0muYWCng5vqaxobq6LB3YNtevDFSAZGlgtLoAc81PjUfiFz36n4KMpwhtAd4he8ToSI3TGyuhyx5xmiWNYZFyw==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.2.tgz", + "integrity": "sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "freebsd" @@ -355,13 +531,14 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.23.0.tgz", - "integrity": "sha512-XKDVu8IsD0/q3foBzsXGt/KjD/yTKBCIwOHE1XwiXmrRwrX6Hbnd5Eqn/WvDekddK21tfszBSrE/WMaZh+1buQ==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.24.2.tgz", + "integrity": "sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "freebsd" @@ -371,13 +548,14 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.23.0.tgz", - "integrity": "sha512-SEELSTEtOFu5LPykzA395Mc+54RMg1EUgXP+iw2SJ72+ooMwVsgfuwXo5Fn0wXNgWZsTVHwY2cg4Vi/bOD88qw==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.24.2.tgz", + "integrity": "sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA==", "cpu": [ "arm" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -387,13 +565,14 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.23.0.tgz", - "integrity": "sha512-j1t5iG8jE7BhonbsEg5d9qOYcVZv/Rv6tghaXM/Ug9xahM0nX/H2gfu6X6z11QRTMT6+aywOMA8TDkhPo8aCGw==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.24.2.tgz", + "integrity": "sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -403,13 +582,14 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.23.0.tgz", - "integrity": "sha512-P7O5Tkh2NbgIm2R6x1zGJJsnacDzTFcRWZyTTMgFdVit6E98LTxO+v8LCCLWRvPrjdzXHx9FEOA8oAZPyApWUA==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.24.2.tgz", + "integrity": "sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw==", "cpu": [ "ia32" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -419,13 +599,14 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.23.0.tgz", - "integrity": "sha512-InQwepswq6urikQiIC/kkx412fqUZudBO4SYKu0N+tGhXRWUqAx+Q+341tFV6QdBifpjYgUndV1hhMq3WeJi7A==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.24.2.tgz", + "integrity": "sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ==", "cpu": [ "loong64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -435,13 +616,14 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.23.0.tgz", - "integrity": "sha512-J9rflLtqdYrxHv2FqXE2i1ELgNjT+JFURt/uDMoPQLcjWQA5wDKgQA4t/dTqGa88ZVECKaD0TctwsUfHbVoi4w==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.24.2.tgz", + "integrity": "sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw==", "cpu": [ "mips64el" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -451,13 +633,14 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.23.0.tgz", - "integrity": "sha512-cShCXtEOVc5GxU0fM+dsFD10qZ5UpcQ8AM22bYj0u/yaAykWnqXJDpd77ublcX6vdDsWLuweeuSNZk4yUxZwtw==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.24.2.tgz", + "integrity": "sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw==", "cpu": [ "ppc64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -467,13 +650,14 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.23.0.tgz", - "integrity": "sha512-HEtaN7Y5UB4tZPeQmgz/UhzoEyYftbMXrBCUjINGjh3uil+rB/QzzpMshz3cNUxqXN7Vr93zzVtpIDL99t9aRw==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.24.2.tgz", + "integrity": "sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q==", "cpu": [ "riscv64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -483,13 +667,14 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.23.0.tgz", - "integrity": "sha512-WDi3+NVAuyjg/Wxi+o5KPqRbZY0QhI9TjrEEm+8dmpY9Xir8+HE/HNx2JoLckhKbFopW0RdO2D72w8trZOV+Wg==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.24.2.tgz", + "integrity": "sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw==", "cpu": [ "s390x" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -499,13 +684,14 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.23.0.tgz", - "integrity": "sha512-a3pMQhUEJkITgAw6e0bWA+F+vFtCciMjW/LPtoj99MhVt+Mfb6bbL9hu2wmTZgNd994qTAEw+U/r6k3qHWWaOQ==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.24.2.tgz", + "integrity": "sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -514,14 +700,32 @@ "node": ">=18" } }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.24.2.tgz", + "integrity": "sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.23.0.tgz", - "integrity": "sha512-cRK+YDem7lFTs2Q5nEv/HHc4LnrfBCbH5+JHu6wm2eP+d8OZNoSMYgPZJq78vqQ9g+9+nMuIsAO7skzphRXHyw==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.24.2.tgz", + "integrity": "sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "netbsd" @@ -531,13 +735,14 @@ } }, "node_modules/@esbuild/openbsd-arm64": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.23.0.tgz", - "integrity": "sha512-suXjq53gERueVWu0OKxzWqk7NxiUWSUlrxoZK7usiF50C6ipColGR5qie2496iKGYNLhDZkPxBI3erbnYkU0rQ==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.2.tgz", + "integrity": "sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "openbsd" @@ -547,13 +752,14 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.23.0.tgz", - "integrity": "sha512-6p3nHpby0DM/v15IFKMjAaayFhqnXV52aEmv1whZHX56pdkK+MEaLoQWj+H42ssFarP1PcomVhbsR4pkz09qBg==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.24.2.tgz", + "integrity": "sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "openbsd" @@ -563,13 +769,14 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.23.0.tgz", - "integrity": "sha512-BFelBGfrBwk6LVrmFzCq1u1dZbG4zy/Kp93w2+y83Q5UGYF1d8sCzeLI9NXjKyujjBBniQa8R8PzLFAUrSM9OA==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.24.2.tgz", + "integrity": "sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "sunos" @@ -579,13 +786,14 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.23.0.tgz", - "integrity": "sha512-lY6AC8p4Cnb7xYHuIxQ6iYPe6MfO2CC43XXKo9nBXDb35krYt7KGhQnOkRGar5psxYkircpCqfbNDB4uJbS2jQ==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.24.2.tgz", + "integrity": "sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" @@ -595,13 +803,14 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.23.0.tgz", - "integrity": "sha512-7L1bHlOTcO4ByvI7OXVI5pNN6HSu6pUQq9yodga8izeuB1KcT2UkHaH6118QJwopExPn0rMHIseCTx1CRo/uNA==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.24.2.tgz", + "integrity": "sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA==", "cpu": [ "ia32" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" @@ -611,13 +820,14 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.23.0.tgz", - "integrity": "sha512-Arm+WgUFLUATuoxCJcahGuk6Yj9Pzxd6l11Zb/2aAuv5kWWvvfhLFo2fni4uSK5vzlUdCGZ/BdV5tH8klj8p8g==", + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.24.2.tgz", + "integrity": "sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" @@ -642,24 +852,73 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.10.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", - "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", "dev": true, "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, + "node_modules/@eslint/config-array": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.1.tgz", + "integrity": "sha512-fo6Mtm5mWyKjA/Chy1BYTdn5mGJoDNjC7C64ug20ADsRDGrA85bN3uK3MaKbeRkRuuIEAR5N33Jr1pbm411/PA==", + "dev": true, + "dependencies": { + "@eslint/object-schema": "^2.1.5", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-array/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/core": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.10.0.tgz", + "integrity": "sha512-gFHJ+xBOo4G3WRlR1e/3G8A6/KZAH6zcE/hkLRCZTi/B9avAG365QhFA8uOGzTMqgTghpn7/fSnscW++dpMSAw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, "node_modules/@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.2.0.tgz", + "integrity": "sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w==", "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", + "espree": "^10.0.1", + "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", @@ -667,7 +926,7 @@ "strip-json-comments": "^3.1.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" @@ -696,48 +955,71 @@ } }, "node_modules/@eslint/js": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.56.0.tgz", - "integrity": "sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==", + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.18.0.tgz", + "integrity": "sha512-fK6L7rxcq6/z+AaQMtiFTkvbHkBLNlwyRxHpKawP0x3u9+NC6MQTnFW+AdpwC6gfHTW0051cokQgtTN2FqlxQA==", "dev": true, + "license": "MIT", "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.5.tgz", + "integrity": "sha512-o0bhxnL89h5Bae5T318nFoFzGy+YE5i/gGkoPAgkmTVdRKTiv3p8JHevPiPaMwoloKfEiiaHlawCqaZMqRm+XQ==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.14", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", - "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", + "node_modules/@eslint/plugin-kit": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.5.tgz", + "integrity": "sha512-lB05FkqEdUg2AA0xEbUz0SnkXT1LcCTa438W4IWTUh4hdOnVbQyOJ81OrDXsJk/LSiJHubgGEFoR5EHq1NsH1A==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@humanwhocodes/object-schema": "^2.0.2", - "debug": "^4.3.1", - "minimatch": "^3.0.5" + "@eslint/core": "^0.10.0", + "levn": "^0.4.1" }, "engines": { - "node": ">=10.10.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "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": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "engines": { + "node": ">=18.18.0" } }, - "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "node_modules/@humanfs/node": { + "version": "0.16.6", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", + "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", "dev": true, "dependencies": { - "brace-expansion": "^1.1.7" + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.3.0" }, "engines": { - "node": "*" + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", + "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", + "dev": true, + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" } }, "node_modules/@humanwhocodes/module-importer": { @@ -753,40 +1035,46 @@ "url": "https://github.com/sponsors/nzakas" } }, - "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz", - "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", - "dev": true + "node_modules/@humanwhocodes/retry": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.1.tgz", + "integrity": "sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==", + "dev": true, + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } }, "node_modules/@inquirer/confirm": { - "version": "3.1.17", - "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-3.1.17.tgz", - "integrity": "sha512-qCpt/AABzPynz8tr69VDvhcjwmzAryipWXtW8Vi6m651da4H/d0Bdn55LkxXD7Rp2gfgxvxzTdb66AhIA8gzBA==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-5.1.0.tgz", + "integrity": "sha512-osaBbIMEqVFjTX5exoqPXs6PilWQdjaLhGtMDXMXg/yxkHXNq43GlxGyTA35lK2HpzUgDN+Cjh/2AmqCN0QJpw==", "dev": true, "dependencies": { - "@inquirer/core": "^9.0.5", - "@inquirer/type": "^1.5.1" + "@inquirer/core": "^10.1.1", + "@inquirer/type": "^3.0.1" }, "engines": { "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" } }, "node_modules/@inquirer/core": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-9.0.5.tgz", - "integrity": "sha512-QWG41I7vn62O9stYKg/juKXt1PEbr/4ZZCPb4KgXDQGwgA9M5NBTQ7FnOvT1ridbxkm/wTxLCNraUs7y47pIRQ==", + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.1.1.tgz", + "integrity": "sha512-rmZVXy9iZvO3ZStEe/ayuuwIJ23LSF13aPMlLMTQARX6lGUBDHGV8UB5i9MRrfy0+mZwt5/9bdy8llszSD3NQA==", "dev": true, "dependencies": { - "@inquirer/figures": "^1.0.5", - "@inquirer/type": "^1.5.1", - "@types/mute-stream": "^0.0.4", - "@types/node": "^20.14.11", - "@types/wrap-ansi": "^3.0.0", + "@inquirer/figures": "^1.0.8", + "@inquirer/type": "^3.0.1", "ansi-escapes": "^4.3.2", - "cli-spinners": "^2.9.2", "cli-width": "^4.1.0", - "mute-stream": "^1.0.0", + "mute-stream": "^2.0.0", "signal-exit": "^4.1.0", "strip-ansi": "^6.0.1", "wrap-ansi": "^6.2.0", @@ -796,21 +1084,6 @@ "node": ">=18" } }, - "node_modules/@inquirer/core/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/@inquirer/core/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -831,18 +1104,6 @@ "node": ">=8" } }, - "node_modules/@inquirer/core/node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/@inquirer/core/node_modules/wrap-ansi": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", @@ -858,26 +1119,94 @@ } }, "node_modules/@inquirer/figures": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.5.tgz", - "integrity": "sha512-79hP/VWdZ2UVc9bFGJnoQ/lQMpL74mGgzSYX1xUqCVk7/v73vJCMw1VuyWN1jGkZ9B3z7THAbySqGbCNefcjfA==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.8.tgz", + "integrity": "sha512-tKd+jsmhq21AP1LhexC0pPwsCxEhGgAkg28byjJAd+xhmIs8LUX8JbUc3vBf3PhLxWiB5EvyBE5X7JSPAqMAqg==", "dev": true, "engines": { "node": ">=18" } }, "node_modules/@inquirer/type": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-1.5.1.tgz", - "integrity": "sha512-m3YgGQlKNS0BM+8AFiJkCsTqHEFCWn6s/Rqye3mYwvqY6LdfUv12eSwbsgNzrYyrLXiy7IrrjDLPysaSBwEfhw==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.1.tgz", + "integrity": "sha512-+ksJMIy92sOAiAccGpcKZUc3bYO07cADnscIxHBknEm3uNts3movSmBofc1908BNy5edKscxYeAdaX1NXkHS6A==", + "dev": true, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + } + }, + "node_modules/@iodigital/vite-plugin-msw": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@iodigital/vite-plugin-msw/-/vite-plugin-msw-2.0.0.tgz", + "integrity": "sha512-b4041DewCVSGKQHu5BocPzMSW94/8h59AV6n6umEXHoeqf4nX77ve+gPb/+lmMuPXOtPL1d8465CKyx0ek6Fuw==", + "dev": true, + "dependencies": { + "@mswjs/interceptors": "^0.25.7", + "body-parser": "^1.20.2", + "fs-extra": "^11.1.1", + "headers-polyfill": "^4.0.2", + "strict-event-emitter": "^0.5.1" + }, + "peerDependencies": { + "msw": "^2.0.0" + } + }, + "node_modules/@iodigital/vite-plugin-msw/node_modules/@mswjs/interceptors": { + "version": "0.25.16", + "resolved": "https://registry.npmjs.org/@mswjs/interceptors/-/interceptors-0.25.16.tgz", + "integrity": "sha512-8QC8JyKztvoGAdPgyZy49c9vSHHAZjHagwl4RY9E8carULk8ym3iTaiawrT1YoLF/qb449h48f71XDPgkUSOUg==", "dev": true, "dependencies": { - "mute-stream": "^1.0.0" + "@open-draft/deferred-promise": "^2.2.0", + "@open-draft/logger": "^0.3.0", + "@open-draft/until": "^2.0.0", + "is-node-process": "^1.2.0", + "outvariant": "^1.2.1", + "strict-event-emitter": "^0.5.1" }, "engines": { "node": ">=18" } }, + "node_modules/@iodigital/vite-plugin-msw/node_modules/fs-extra": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/@iodigital/vite-plugin-msw/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@iodigital/vite-plugin-msw/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, "node_modules/@isaacs/cliui": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", @@ -953,6 +1282,8 @@ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -967,6 +1298,8 @@ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "dev": true, + "optional": true, + "peer": true, "engines": { "node": ">=6.0.0" } @@ -976,6 +1309,8 @@ "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", "dev": true, + "optional": true, + "peer": true, "engines": { "node": ">=6.0.0" } @@ -985,15 +1320,17 @@ "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "@jridgewell/gen-mapping": "^0.3.0", "@jridgewell/trace-mapping": "^0.3.9" } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", "dev": true }, "node_modules/@jridgewell/trace-mapping": { @@ -1001,28 +1338,170 @@ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "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.1.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-1.1.1.tgz", + "integrity": "sha512-osjeBqMJ2lb/j/M8NCPjs1ylqWIcTRTycIhVB5pt6LgzgeRSb0YRZ7j9RfA8wIUrsr/medIuhVyonXRZWLyfdw==", + "dev": true, + "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" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/util": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-1.5.0.tgz", + "integrity": "sha512-ojoNsrIuPI9g6o8UxhraZQSyF2ByJanAY4cTFbc8Mf2AXEF4aQRGY1dJxyJpuyav8r9FGflEt/Ff3u5Nt6YMPA==", + "dev": true, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@koa/router": { + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/@koa/router/-/router-9.4.0.tgz", + "integrity": "sha512-dOOXgzqaDoHu5qqMEPLKEgLz5CeIA7q8+1W62mCvFVCOqeC71UoTGJ4u1xUSOpIl2J1x2pqrNULkFteUeZW3/A==", + "deprecated": "**IMPORTANT 10x+ PERFORMANCE UPGRADE**: Please upgrade to v12.0.1+ as we have fixed an issue with debuglog causing 10x slower router benchmark performance, see https://github.com/koajs/router/pull/173", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "http-errors": "^1.7.3", + "koa-compose": "^4.1.0", + "methods": "^1.1.2", + "path-to-regexp": "^6.1.0" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/@koa/router/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@koa/router/node_modules/http-errors": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", + "dev": true, + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@koa/router/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/@leichtgewicht/ip-codec": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz", "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==", "dev": true }, + "node_modules/@module-federation/runtime": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@module-federation/runtime/-/runtime-0.5.1.tgz", + "integrity": "sha512-xgiMUWwGLWDrvZc9JibuEbXIbhXg6z2oUkemogSvQ4LKvrl/n0kbqP1Blk669mXzyWbqtSp6PpvNdwaE1aN5xQ==", + "dev": true, + "dependencies": { + "@module-federation/sdk": "0.5.1" + } + }, + "node_modules/@module-federation/runtime-tools": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@module-federation/runtime-tools/-/runtime-tools-0.5.1.tgz", + "integrity": "sha512-nfBedkoZ3/SWyO0hnmaxuz0R0iGPSikHZOAZ0N/dVSQaIzlffUo35B5nlC2wgWIc0JdMZfkwkjZRrnuuDIJbzg==", + "dev": true, + "dependencies": { + "@module-federation/runtime": "0.5.1", + "@module-federation/webpack-bundler-runtime": "0.5.1" + } + }, + "node_modules/@module-federation/sdk": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@module-federation/sdk/-/sdk-0.5.1.tgz", + "integrity": "sha512-exvchtjNURJJkpqjQ3/opdbfeT2wPKvrbnGnyRkrwW5o3FH1LaST1tkiNviT6OXTexGaVc2DahbdniQHVtQ7pA==", + "dev": true + }, + "node_modules/@module-federation/webpack-bundler-runtime": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@module-federation/webpack-bundler-runtime/-/webpack-bundler-runtime-0.5.1.tgz", + "integrity": "sha512-mMhRFH0k2VjwHt3Jol9JkUsmI/4XlrAoBG3E0o7HoyoPYv1UFOWyqAflfANcUPgbYpvqmyLzDcO+3IT36LXnrA==", + "dev": true, + "dependencies": { + "@module-federation/runtime": "0.5.1", + "@module-federation/sdk": "0.5.1" + } + }, "node_modules/@mswjs/interceptors": { - "version": "0.29.1", - "resolved": "https://registry.npmjs.org/@mswjs/interceptors/-/interceptors-0.29.1.tgz", - "integrity": "sha512-3rDakgJZ77+RiQUuSK69t1F0m8BQKA8Vh5DCS5V0DWvNY67zob2JhhQrhCO0AKLGINTRSFd1tBaHcJTkhefoSw==", + "version": "0.37.3", + "resolved": "https://registry.npmjs.org/@mswjs/interceptors/-/interceptors-0.37.3.tgz", + "integrity": "sha512-USvgCL/uOGFtVa6SVyRrC8kIAedzRohxIXN5LISlg5C5vLZCn7dgMFVSNhSF9cuBEFrm/O2spDWEZeMnw4ZXYg==", "dev": true, "dependencies": { "@open-draft/deferred-promise": "^2.2.0", "@open-draft/logger": "^0.3.0", "@open-draft/until": "^2.0.0", "is-node-process": "^1.2.0", - "outvariant": "^1.2.1", + "outvariant": "^1.4.3", "strict-event-emitter": "^0.5.1" }, "engines": { @@ -1064,6 +1543,15 @@ "node": ">= 8" } }, + "node_modules/@nolyfill/is-core-module": { + "version": "1.0.39", + "resolved": "https://registry.npmjs.org/@nolyfill/is-core-module/-/is-core-module-1.0.39.tgz", + "integrity": "sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==", + "dev": true, + "engines": { + "node": ">=12.4.0" + } + }, "node_modules/@one-ini/wasm": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/@one-ini/wasm/-/wasm-0.1.1.tgz", @@ -1091,51 +1579,181 @@ "integrity": "sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==", "dev": 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==", + "node_modules/@oxlint/darwin-arm64": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/@oxlint/darwin-arm64/-/darwin-arm64-0.15.7.tgz", + "integrity": "sha512-+8jOC9MfzIhbRdmNYl+gLlGZe8dhl2hrQRLJ+mriPRXxtpfBmT5aOmEQrs9BX5GPnh6hy4ArMvjDbCCXD+bl+w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", "optional": true, - "engines": { - "node": ">=14" - } + "os": [ + "darwin" + ] }, - "node_modules/@polka/url": { - "version": "1.0.0-next.24", - "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.24.tgz", - "integrity": "sha512-2LuNTFBIO0m7kKIQvvPHN6UE63VjpmL9rnEEaOOaiSPbZK+zUOYIzBAWcED+3XYzhYsd/0mD57VdxAEqqV52CQ==", - "dev": true + "node_modules/@oxlint/darwin-x64": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/@oxlint/darwin-x64/-/darwin-x64-0.15.7.tgz", + "integrity": "sha512-4y1v3zCtQU0dv5SxwBZqtYiqtQTUSvEdK3XzWg/JxN8qEleHonQrbSvGKmlkzraEouKTIm1bXjmnrX26MX22cQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] }, - "node_modules/@promptbook/utils": { - "version": "0.58.0", - "resolved": "https://registry.npmjs.org/@promptbook/utils/-/utils-0.58.0.tgz", - "integrity": "sha512-TglWndmjikWN+OGg9eNOUaMTM7RHr8uFCtgxfWULT1BUjcohywdijf54vS1U4mZ1tBLdHD4/fIrIHtmHzPUIZQ==", + "node_modules/@oxlint/linux-arm64-gnu": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/@oxlint/linux-arm64-gnu/-/linux-arm64-gnu-0.15.7.tgz", + "integrity": "sha512-g01PWQl1+HLlMGK3lwH8G+A/5vA6H7tcKUHnx/qGz4+LM1zKfp1w2d2aoXxPqpIgtBPn19JRcBiEMv+nr40fiw==", + "cpu": [ + "arm64" + ], "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://buymeacoffee.com/hejny" - }, - { - "type": "github", - "url": "https://github.com/webgptorg/promptbook/blob/main/README.md#%EF%B8%8F-contributing" - } + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@oxlint/linux-arm64-musl": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/@oxlint/linux-arm64-musl/-/linux-arm64-musl-0.15.7.tgz", + "integrity": "sha512-8Dg7qaHXNgiZgP3TxQU8k/5fpzGfcxYVLK58Sj/vSZ3vMrI68ipkq+rkNBjAXT1Aq2/eM6L/9CLH8pex+I1Nkw==", + "cpu": [ + "arm64" ], - "dependencies": { - "spacetrim": "0.11.36" - } + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@puppeteer/browsers": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.2.4.tgz", - "integrity": "sha512-BdG2qiI1dn89OTUUsx2GZSpUzW+DRffR1wlMJyKxVHYrhnKoELSDxDd+2XImUkuWPEKk76H5FcM/gPFrEK1Tfw==", + "node_modules/@oxlint/linux-x64-gnu": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/@oxlint/linux-x64-gnu/-/linux-x64-gnu-0.15.7.tgz", + "integrity": "sha512-hLsfcOgoky/FUGF2s3v7+wd0xGGuyE7EBPSTV7BPQYEm5+P5ZeWXPlUg8uTPee6bIxHa6lZLqunRl8Jn44b/ig==", + "cpu": [ + "x64" + ], "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@oxlint/linux-x64-musl": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/@oxlint/linux-x64-musl/-/linux-x64-musl-0.15.7.tgz", + "integrity": "sha512-BW9dACxzLRZq67lPFis/NCiitQucZbbrONeK0mReBWPSM3MaegLY82kZU7sMq3fpBbzGaKFoNLp2EcsNfS5IVw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@oxlint/win32-arm64": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/@oxlint/win32-arm64/-/win32-arm64-0.15.7.tgz", + "integrity": "sha512-VvIaIdfCjcYy8cj3yAjHwj2dDFIFxdUS7G+KeDK/iH7O3uXW8wOec2wFYcd8xmVYHEcnw8fgNAXy04gXpB6KnQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@oxlint/win32-x64": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/@oxlint/win32-x64/-/win32-x64-0.15.7.tgz", + "integrity": "sha512-1WKZTgtJswATA8NYeUfMnN4ei7AUVyomrWBiPwYGMRMOo4jeGkOlOr2/iYq/vbtOCyOuqAo2JjfzN5sBOPfI/A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "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==", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@playwright/browser-chromium": { + "version": "1.49.1", + "resolved": "https://registry.npmjs.org/@playwright/browser-chromium/-/browser-chromium-1.49.1.tgz", + "integrity": "sha512-LLeyllKSucbojsJBOpdJshwW27ZXZs3oypqffkVWLUvxX2azHJMOevsOcWpjCfoYbpevkaEozM2xHeSUGF00lg==", + "dev": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "playwright-core": "1.49.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@polka/url": { + "version": "1.0.0-next.24", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.24.tgz", + "integrity": "sha512-2LuNTFBIO0m7kKIQvvPHN6UE63VjpmL9rnEEaOOaiSPbZK+zUOYIzBAWcED+3XYzhYsd/0mD57VdxAEqqV52CQ==", + "dev": true + }, + "node_modules/@promptbook/utils": { + "version": "0.69.5", + "resolved": "https://registry.npmjs.org/@promptbook/utils/-/utils-0.69.5.tgz", + "integrity": "sha512-xm5Ti/Hp3o4xHrsK9Yy3MS6KbDxYbq485hDsFvxqaNA7equHLPdo8H8faTitTeb14QCDfLW4iwCxdVYu5sn6YQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://buymeacoffee.com/hejny" + }, + { + "type": "github", + "url": "https://github.com/webgptorg/promptbook/blob/main/README.md#%EF%B8%8F-contributing" + } + ], + "optional": true, + "peer": true, + "dependencies": { + "spacetrim": "0.11.59" + } + }, + "node_modules/@puppeteer/browsers": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.6.1.tgz", + "integrity": "sha512-aBSREisdsGH890S2rQqK82qmQYU3uFpSH8wcZWHgHzl3LfzsxAKbLNiAG9mO8v1Y0UICBeClICxPJvyr0rcuxg==", + "dev": true, + "optional": true, + "peer": true, "dependencies": { - "debug": "^4.3.5", + "debug": "^4.4.0", "extract-zip": "^2.0.1", "progress": "^2.0.3", - "proxy-agent": "^6.4.0", - "semver": "^7.6.2", + "proxy-agent": "^6.5.0", + "semver": "^7.6.3", "tar-fs": "^3.0.6", "unbzip2-stream": "^1.4.3", "yargs": "^17.7.2" @@ -1147,1718 +1765,1652 @@ "node": ">=18" } }, - "node_modules/@puppeteer/browsers/node_modules/debug": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", - "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.19.0.tgz", - "integrity": "sha512-JlPfZ/C7yn5S5p0yKk7uhHTTnFlvTgLetl2VxqE518QgyM7C9bSfFTYvB/Q/ftkq0RIPY4ySxTz+/wKJ/dXC0w==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.30.1.tgz", + "integrity": "sha512-pSWY+EVt3rJ9fQ3IqlrEUtXh3cGqGtPDH1FQlNZehO2yYxCHEX1SPsz1M//NXwYfbTlcKr9WObLnJX9FsS9K1Q==", "cpu": [ "arm" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "android" ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.19.0.tgz", - "integrity": "sha512-RDxUSY8D1tWYfn00DDi5myxKgOk6RvWPxhmWexcICt/MEC6yEMr4HNCu1sXXYLw8iAsg0D44NuU+qNq7zVWCrw==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.30.1.tgz", + "integrity": "sha512-/NA2qXxE3D/BRjOJM8wQblmArQq1YoBVJjrjoTSBS09jgUisq7bqxNHJ8kjCHeV21W/9WDGwJEWSN0KQ2mtD/w==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "android" ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.19.0.tgz", - "integrity": "sha512-emvKHL4B15x6nlNTBMtIaC9tLPRpeA5jMvRLXVbl/W9Ie7HhkrE7KQjvgS9uxgatL1HmHWDXk5TTS4IaNJxbAA==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.30.1.tgz", + "integrity": "sha512-r7FQIXD7gB0WJ5mokTUgUWPl0eYIH0wnxqeSAhuIwvnnpjdVB8cRRClyKLQr7lgzjctkbp5KmswWszlwYln03Q==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.19.0.tgz", - "integrity": "sha512-fO28cWA1dC57qCd+D0rfLC4VPbh6EOJXrreBmFLWPGI9dpMlER2YwSPZzSGfq11XgcEpPukPTfEVFtw2q2nYJg==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.30.1.tgz", + "integrity": "sha512-x78BavIwSH6sqfP2xeI1hd1GpHL8J4W2BXcVM/5KYKoAD3nNsfitQhvWSw+TFtQTLZ9OmlF+FEInEHyubut2OA==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" ] }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.30.1.tgz", + "integrity": "sha512-HYTlUAjbO1z8ywxsDFWADfTRfTIIy/oUlfIDmlHYmjUP2QRDTzBuWXc9O4CXM+bo9qfiCclmHk1x4ogBjOUpUQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.30.1.tgz", + "integrity": "sha512-1MEdGqogQLccphhX5myCJqeGNYTNcmTyaic9S7CG3JhwuIByJ7J05vGbZxsizQthP1xpVx7kd3o31eOogfEirw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.19.0.tgz", - "integrity": "sha512-2Rn36Ubxdv32NUcfm0wB1tgKqkQuft00PtM23VqLuCUR4N5jcNWDoV5iBC9jeGdgS38WK66ElncprqgMUOyomw==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.30.1.tgz", + "integrity": "sha512-PaMRNBSqCx7K3Wc9QZkFx5+CX27WFpAMxJNiYGAXfmMIKC7jstlr32UhTgK6T07OtqR+wYlWm9IxzennjnvdJg==", "cpu": [ "arm" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.19.0.tgz", - "integrity": "sha512-gJuzIVdq/X1ZA2bHeCGCISe0VWqCoNT8BvkQ+BfsixXwTOndhtLUpOg0A1Fcx/+eA6ei6rMBzlOz4JzmiDw7JQ==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.30.1.tgz", + "integrity": "sha512-B8Rcyj9AV7ZlEFqvB5BubG5iO6ANDsRKlhIxySXcF1axXYUyqwBok+XZPgIYGBgs7LDXfWfifxhw0Ik57T0Yug==", "cpu": [ "arm" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.19.0.tgz", - "integrity": "sha512-0EkX2HYPkSADo9cfeGFoQ7R0/wTKb7q6DdwI4Yn/ULFE1wuRRCHybxpl2goQrx4c/yzK3I8OlgtBu4xvted0ug==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.30.1.tgz", + "integrity": "sha512-hqVyueGxAj3cBKrAI4aFHLV+h0Lv5VgWZs9CUGqr1z0fZtlADVV1YPOij6AhcK5An33EXaxnDLmJdQikcn5NEw==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.19.0.tgz", - "integrity": "sha512-GlIQRj9px52ISomIOEUq/IojLZqzkvRpdP3cLgIE1wUWaiU5Takwlzpz002q0Nxxr1y2ZgxC2obWxjr13lvxNQ==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.30.1.tgz", + "integrity": "sha512-i4Ab2vnvS1AE1PyOIGp2kXni69gU2DAUVt6FSXeIqUCPIR3ZlheMW3oP2JkukDfu3PsexYRbOiJrY+yVNSk9oA==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loongarch64-gnu": { + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.30.1.tgz", + "integrity": "sha512-fARcF5g296snX0oLGkVxPmysetwUk2zmHcca+e9ObOovBR++9ZPOhqFUM61UUZ2EYpXVPN1redgqVoBB34nTpQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.19.0.tgz", - "integrity": "sha512-N6cFJzssruDLUOKfEKeovCKiHcdwVYOT1Hs6dovDQ61+Y9n3Ek4zXvtghPPelt6U0AH4aDGnDLb83uiJMkWYzQ==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.30.1.tgz", + "integrity": "sha512-GLrZraoO3wVT4uFXh67ElpwQY0DIygxdv0BNW9Hkm3X34wu+BkqrDrkcsIapAY+N2ATEbvak0XQ9gxZtCIA5Rw==", "cpu": [ "ppc64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.19.0.tgz", - "integrity": "sha512-2DnD3mkS2uuam/alF+I7M84koGwvn3ZVD7uG+LEWpyzo/bq8+kKnus2EVCkcvh6PlNB8QPNFOz6fWd5N8o1CYg==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.30.1.tgz", + "integrity": "sha512-0WKLaAUUHKBtll0wvOmh6yh3S0wSU9+yas923JIChfxOaaBarmb/lBKPF0w/+jTVozFnOXJeRGZ8NvOxvk/jcw==", "cpu": [ "riscv64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.19.0.tgz", - "integrity": "sha512-D6pkaF7OpE7lzlTOFCB2m3Ngzu2ykw40Nka9WmKGUOTS3xcIieHe82slQlNq69sVB04ch73thKYIWz/Ian8DUA==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.30.1.tgz", + "integrity": "sha512-GWFs97Ruxo5Bt+cvVTQkOJ6TIx0xJDD/bMAOXWJg8TCSTEK8RnFeOeiFTxKniTc4vMIaWvCplMAFBt9miGxgkA==", "cpu": [ "s390x" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.19.0.tgz", - "integrity": "sha512-HBndjQLP8OsdJNSxpNIN0einbDmRFg9+UQeZV1eiYupIRuZsDEoeGU43NQsS34Pp166DtwQOnpcbV/zQxM+rWA==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.30.1.tgz", + "integrity": "sha512-UtgGb7QGgXDIO+tqqJ5oZRGHsDLO8SlpE4MhqpY9Llpzi5rJMvrK6ZGhsRCST2abZdBqIBeXW6WPD5fGK5SDwg==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.19.0.tgz", - "integrity": "sha512-HxfbvfCKJe/RMYJJn0a12eiOI9OOtAUF4G6ozrFUK95BNyoJaSiBjIOHjZskTUffUrB84IPKkFG9H9nEvJGW6A==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.30.1.tgz", + "integrity": "sha512-V9U8Ey2UqmQsBT+xTOeMzPzwDzyXmnAoO4edZhL7INkwQcaW1Ckv3WJX3qrrp/VHaDkEWIBWhRwP47r8cdrOow==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.19.0.tgz", - "integrity": "sha512-HxDMKIhmcguGTiP5TsLNolwBUK3nGGUEoV/BO9ldUBoMLBssvh4J0X8pf11i1fTV7WShWItB1bKAKjX4RQeYmg==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.30.1.tgz", + "integrity": "sha512-WabtHWiPaFF47W3PkHnjbmWawnX/aE57K47ZDT1BXTS5GgrBUEpvOzq0FI0V/UYzQJgdb8XlhVNH8/fwV8xDjw==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.19.0.tgz", - "integrity": "sha512-xItlIAZZaiG/u0wooGzRsx11rokP4qyc/79LkAOdznGRAbOFc+SfEdfUOszG1odsHNgwippUJavag/+W/Etc6Q==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.30.1.tgz", + "integrity": "sha512-pxHAU+Zv39hLUTdQQHUVHf4P+0C47y/ZloorHpzs2SXMRqeAWmGghzAhfOlzFHHwjvgokdFAhC4V+6kC1lRRfw==", "cpu": [ "ia32" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.19.0.tgz", - "integrity": "sha512-xNo5fV5ycvCCKqiZcpB65VMR11NJB+StnxHz20jdqRAktfdfzhgjTiJ2doTDQE/7dqGaV5I7ZGqKpgph6lCIag==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.30.1.tgz", + "integrity": "sha512-D6qjsXGcvhTjv0kI4fU8tUuBDF/Ueee4SVX79VfNDXZa64TfCW1Slkb6Z7O1p7vflqZjcmOVdZlqf8gvJxc6og==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" ] }, - "node_modules/@sinclair/typebox": { - "version": "0.27.8", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", - "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", - "dev": true - }, - "node_modules/@sindresorhus/is": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.6.0.tgz", - "integrity": "sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==", + "node_modules/@rspack/binding": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/@rspack/binding/-/binding-1.1.8.tgz", + "integrity": "sha512-+/JzXx1HctfgPj+XtsCTbRkxiaOfAXGZZLEvs7jgp04WgWRSZ5u97WRCePNPvy+sCfOEH/2zw2ZK36Z7oQRGhQ==", "dev": true, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sindresorhus/is?sponsor=1" - } - }, - "node_modules/@szmarczak/http-timer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", - "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==", + "license": "MIT", + "optionalDependencies": { + "@rspack/binding-darwin-arm64": "1.1.8", + "@rspack/binding-darwin-x64": "1.1.8", + "@rspack/binding-linux-arm64-gnu": "1.1.8", + "@rspack/binding-linux-arm64-musl": "1.1.8", + "@rspack/binding-linux-x64-gnu": "1.1.8", + "@rspack/binding-linux-x64-musl": "1.1.8", + "@rspack/binding-win32-arm64-msvc": "1.1.8", + "@rspack/binding-win32-ia32-msvc": "1.1.8", + "@rspack/binding-win32-x64-msvc": "1.1.8" + } + }, + "node_modules/@rspack/binding-darwin-arm64": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/@rspack/binding-darwin-arm64/-/binding-darwin-arm64-1.1.8.tgz", + "integrity": "sha512-I7avr471ghQ3LAqKm2fuXuJPLgQ9gffn5Q4nHi8rsukuZUtiLDPfYzK1QuupEp2JXRWM1gG5lIbSUOht3cD6Ug==", + "cpu": [ + "arm64" + ], "dev": true, - "dependencies": { - "defer-to-connect": "^2.0.1" - }, - "engines": { - "node": ">=14.16" - } + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] }, - "node_modules/@testing-library/dom": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.0.tgz", - "integrity": "sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==", + "node_modules/@rspack/binding-darwin-x64": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/@rspack/binding-darwin-x64/-/binding-darwin-x64-1.1.8.tgz", + "integrity": "sha512-vfqf/c+mcx8rr1M8LnqKmzDdnrgguflZnjGerBLjNerAc+dcUp3lCvNxRIvZ2TkSZZBW8BpCMgjj3n70CZ4VLQ==", + "cpu": [ + "x64" + ], "dev": true, - "dependencies": { - "@babel/code-frame": "^7.10.4", - "@babel/runtime": "^7.12.5", - "@types/aria-query": "^5.0.1", - "aria-query": "5.3.0", - "chalk": "^4.1.0", - "dom-accessibility-api": "^0.5.9", - "lz-string": "^1.5.0", - "pretty-format": "^27.0.2" - }, - "engines": { - "node": ">=18" - } + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] }, - "node_modules/@testing-library/user-event": { - "version": "14.5.2", - "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.5.2.tgz", - "integrity": "sha512-YAh82Wh4TIrxYLmfGcixwD18oIjyC1pFQC2Y01F2lzV2HTMiYrI0nze0FD0ocB//CKS/7jIUgae+adPqxK5yCQ==", + "node_modules/@rspack/binding-linux-arm64-gnu": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/@rspack/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.1.8.tgz", + "integrity": "sha512-lZlO/rAJSeozi+qtVLkGSXfe+riPawCwM4FsrflELfNlvvEXpANwtrdJ+LsaNVXcgvhh50ZX2KicTdmx9G2b6Q==", + "cpu": [ + "arm64" + ], "dev": true, - "engines": { - "node": ">=12", - "npm": ">=6" - }, - "peerDependencies": { - "@testing-library/dom": ">=7.21.4" - } - }, - "node_modules/@tootallnate/quickjs-emscripten": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz", - "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==", - "dev": true - }, - "node_modules/@types/aria-query": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", - "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", - "dev": true + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@types/body-parser": { - "version": "1.19.5", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", - "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "node_modules/@rspack/binding-linux-arm64-musl": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/@rspack/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.1.8.tgz", + "integrity": "sha512-bX7exULSZwy8xtDh6Z65b6sRC4uSxGuyvSLCEKyhmG6AnJkg0gQMxk3hoO0hWnyGEZgdJEn+jEhk0fjl+6ZRAQ==", + "cpu": [ + "arm64" + ], "dev": true, - "dependencies": { - "@types/connect": "*", - "@types/node": "*" - } + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@types/bonjour": { - "version": "3.5.13", - "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", - "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", + "node_modules/@rspack/binding-linux-x64-gnu": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/@rspack/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.1.8.tgz", + "integrity": "sha512-2Prw2USgTJ3aLdLExfik8pAwAHbX4MZrACBGEmR7Vbb56kLjC+++fXkciRc50pUDK4JFr1VQ7eNZrJuDR6GG6Q==", + "cpu": [ + "x64" + ], "dev": true, - "dependencies": { - "@types/node": "*" - } + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@types/codemirror": { - "version": "5.60.15", - "resolved": "https://registry.npmjs.org/@types/codemirror/-/codemirror-5.60.15.tgz", - "integrity": "sha512-dTOvwEQ+ouKJ/rE9LT1Ue2hmP6H1mZv5+CCnNWu2qtiOe2LQa9lCprEY20HxiDmV/Bxh+dXjywmy5aKvoGjULA==", - "dev": true, - "dependencies": { - "@types/tern": "*" - } - }, - "node_modules/@types/connect": { - "version": "3.4.38", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", - "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "node_modules/@rspack/binding-linux-x64-musl": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/@rspack/binding-linux-x64-musl/-/binding-linux-x64-musl-1.1.8.tgz", + "integrity": "sha512-bnVGB/mQBKEdzOU/CPmcOE3qEXxGOGGW7/i6iLl2MamVOykJq8fYjL9j86yi6L0r009ja16OgWckykQGc4UqGw==", + "cpu": [ + "x64" + ], "dev": true, - "dependencies": { - "@types/node": "*" - } + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "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==", + "node_modules/@rspack/binding-win32-arm64-msvc": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/@rspack/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.1.8.tgz", + "integrity": "sha512-u+na3gxhzeksm4xZyAzn1+XWo5a5j7hgWA/KcFPDQ8qQNkRknx4jnQMxVtcZ9pLskAYV4AcOV/AIximx7zvv8A==", + "cpu": [ + "arm64" + ], "dev": true, - "dependencies": { - "@types/express-serve-static-core": "*", - "@types/node": "*" - } - }, - "node_modules/@types/cookie": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==", - "dev": true + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] }, - "node_modules/@types/eslint": { - "version": "8.56.5", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.5.tgz", - "integrity": "sha512-u5/YPJHo1tvkSF2CE0USEkxon82Z5DBy2xR+qfyYNszpX9qcs4sT6uq2kBbj4BXY1+DBGDPnrhMZV3pKWGNukw==", + "node_modules/@rspack/binding-win32-ia32-msvc": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/@rspack/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-1.1.8.tgz", + "integrity": "sha512-FijUxym1INd5fFHwVCLuVP8XEAb4Sk1sMwEEQUlugiDra9ZsLaPw4OgPGxbxkD6SB0DeUz9Zq46Xbcf6d3OgfA==", + "cpu": [ + "ia32" + ], "dev": true, - "dependencies": { - "@types/estree": "*", - "@types/json-schema": "*" - } + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] }, - "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==", + "node_modules/@rspack/binding-win32-x64-msvc": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/@rspack/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.1.8.tgz", + "integrity": "sha512-SBzIcND4qpDt71jlu1MCDxt335tqInT3YID9V4DoQ4t8wgM/uad7EgKOWKTK6vc2RRaOIShfS2XzqjNUxPXh4w==", + "cpu": [ + "x64" + ], "dev": true, - "dependencies": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, - "node_modules/@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", - "dev": true + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] }, - "node_modules/@types/express": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", - "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", + "node_modules/@rspack/cli": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/@rspack/cli/-/cli-1.1.8.tgz", + "integrity": "sha512-LiodoRmv1eAYtGQftPHX5Cr0uBmVUywOXZvnrVipXZupRsl1DNYO6Ao2kYlvSPYi77ymhOBRoxrMqbUOUklbIg==", "dev": true, + "license": "MIT", "dependencies": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.33", - "@types/qs": "*", - "@types/serve-static": "*" + "@discoveryjs/json-ext": "^0.5.7", + "@rspack/dev-server": "1.0.9", + "colorette": "2.0.19", + "exit-hook": "^4.0.0", + "interpret": "^3.1.1", + "rechoir": "^0.8.0", + "semver": "^7.6.2", + "webpack-bundle-analyzer": "4.6.1", + "yargs": "17.6.2" + }, + "bin": { + "rspack": "bin/rspack.js" + }, + "peerDependencies": { + "@rspack/core": "^1.0.0-alpha || ^1.x" } }, - "node_modules/@types/express-serve-static-core": { - "version": "4.17.43", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.43.tgz", - "integrity": "sha512-oaYtiBirUOPQGSWNGPWnzyAFJ0BP3cwvN4oWZQY+zUBwpVIGsKUkpBpSztp74drYcjavs7SKFZ4DX1V2QeN8rg==", + "node_modules/@rspack/cli/node_modules/acorn-walk": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", + "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", "dev": true, "dependencies": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*", - "@types/send": "*" + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" } }, - "node_modules/@types/gl-matrix": { - "version": "2.4.5", - "resolved": "https://registry.npmjs.org/@types/gl-matrix/-/gl-matrix-2.4.5.tgz", - "integrity": "sha512-0L8Mq1+oaIW0oVzGUDbSW+HnTjCNb4CmoIQE5BkoHt/A7x20z0MJ1PnwfH3atty/vbWLGgvJwVu2Mz3SKFiEFw==", - "dev": true - }, - "node_modules/@types/html-minifier-terser": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", - "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==", + "node_modules/@rspack/cli/node_modules/colorette": { + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz", + "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==", "dev": true }, - "node_modules/@types/http-cache-semantics": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", - "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==", - "dev": true + "node_modules/@rspack/cli/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true, + "engines": { + "node": ">= 10" + } }, - "node_modules/@types/http-errors": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", - "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", + "node_modules/@rspack/cli/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/@types/http-proxy": { - "version": "1.17.14", - "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.14.tgz", - "integrity": "sha512-SSrD0c1OQzlFX7pGu1eXxSEjemej64aaNPRhhVYUGqXh0BtldAAx37MG8btcumvpgKyZp1F5Gn3JkktdxiFv6w==", + "node_modules/@rspack/cli/node_modules/mrmime": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-1.0.1.tgz", + "integrity": "sha512-hzzEagAgDyoU1Q6yg5uI+AorQgdvMCur3FcKf7NhMKWsaYg+RnbTyHRa/9IlLF9rf455MOCtcqqrQQ83pPP7Uw==", "dev": true, - "dependencies": { - "@types/node": "*" + "engines": { + "node": ">=10" } }, - "node_modules/@types/istanbul-lib-coverage": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", - "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", - "dev": true - }, - "node_modules/@types/istanbul-lib-report": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", - "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", + "node_modules/@rspack/cli/node_modules/sirv": { + "version": "1.0.19", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-1.0.19.tgz", + "integrity": "sha512-JuLThK3TnZG1TAKDwNIqNq6QA2afLOCcm+iE8D1Kj3GA40pSPsxQjjJl0J8X3tsR7T+CP1GavpzLwYkgVLWrZQ==", "dev": true, "dependencies": { - "@types/istanbul-lib-coverage": "*" + "@polka/url": "^1.0.0-next.20", + "mrmime": "^1.0.0", + "totalist": "^1.0.0" + }, + "engines": { + "node": ">= 10" } }, - "node_modules/@types/istanbul-reports": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", - "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", + "node_modules/@rspack/cli/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": { - "@types/istanbul-lib-report": "*" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" } }, - "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/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", - "dev": true - }, - "node_modules/@types/lodash": { - "version": "4.14.202", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.202.tgz", - "integrity": "sha512-OvlIYQK9tNneDlS0VN54LLd5uiPCBOp7gS5Z0f1mjoJYBrtStzgmJBxONW3U6OZqdtNzZPmn9BS/7WI7BFFcFQ==", - "dev": true + "node_modules/@rspack/cli/node_modules/totalist": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-1.1.0.tgz", + "integrity": "sha512-gduQwd1rOdDMGxFG1gEvhV88Oirdo2p+KjoYFU7k2g+i7n6AFFbDQ5kMPUsW0pNbfQsB/cwXvT1i4Bue0s9g5g==", + "dev": true, + "engines": { + "node": ">=6" + } }, - "node_modules/@types/lodash-es": { - "version": "4.17.12", - "resolved": "https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.12.tgz", - "integrity": "sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==", + "node_modules/@rspack/cli/node_modules/webpack-bundle-analyzer": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.6.1.tgz", + "integrity": "sha512-oKz9Oz9j3rUciLNfpGFjOb49/jEpXNmWdVH8Ls//zNcnLlQdTGXQQMsBbb/gR7Zl8WNLxVCq+0Hqbx3zv6twBw==", "dev": true, "dependencies": { - "@types/lodash": "*" + "acorn": "^8.0.4", + "acorn-walk": "^8.0.0", + "chalk": "^4.1.0", + "commander": "^7.2.0", + "gzip-size": "^6.0.0", + "lodash": "^4.17.20", + "opener": "^1.5.2", + "sirv": "^1.0.7", + "ws": "^7.3.1" + }, + "bin": { + "webpack-bundle-analyzer": "lib/bin/analyzer.js" + }, + "engines": { + "node": ">= 10.13.0" } }, - "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/@rspack/cli/node_modules/ws": { + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", + "dev": true, + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } }, - "node_modules/@types/mute-stream": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/@types/mute-stream/-/mute-stream-0.0.4.tgz", - "integrity": "sha512-CPM9nzrCPPJHQNA9keH9CVkVI+WR5kMa+7XEs5jcGQ0VoAGnLv242w8lIVgwAEfmE4oufJRaTc9PNLQl0ioAow==", + "node_modules/@rspack/cli/node_modules/yargs": { + "version": "17.6.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz", + "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==", "dev": true, "dependencies": { - "@types/node": "*" + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" } }, - "node_modules/@types/node": { - "version": "20.14.12", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.12.tgz", - "integrity": "sha512-r7wNXakLeSsGT0H1AU863vS2wa5wBOK4bWMjZz2wj+8nBx+m5PeIn0k8AloSLpRuiwdRQZwarZqHE4FNArPuJQ==", + "node_modules/@rspack/core": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/@rspack/core/-/core-1.1.8.tgz", + "integrity": "sha512-pcZtcj5iXLCuw9oElTYC47bp/RQADm/MMEb3djHdwJuSlFWfWPQi5QFgJ/lJAxIW9UNHnTFrYtytycfjpuoEcA==", "dev": true, + "license": "MIT", "dependencies": { - "undici-types": "~5.26.4" + "@module-federation/runtime-tools": "0.5.1", + "@rspack/binding": "1.1.8", + "@rspack/lite-tapable": "1.0.1", + "caniuse-lite": "^1.0.30001616" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@swc/helpers": ">=0.5.1" + }, + "peerDependenciesMeta": { + "@swc/helpers": { + "optional": true + } } }, - "node_modules/@types/node-forge": { - "version": "1.3.11", - "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.11.tgz", - "integrity": "sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==", + "node_modules/@rspack/dev-server": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@rspack/dev-server/-/dev-server-1.0.9.tgz", + "integrity": "sha512-VF+apLFfl5LWIhVbfkJ5ccU0Atl5mi+sGTkx+XtE1tbUmMJkde0nm/4+eaQCud7oGl+ZCzt4kW14uuzLSiEGDw==", "dev": true, "dependencies": { - "@types/node": "*" + "chokidar": "^3.6.0", + "connect-history-api-fallback": "^2.0.0", + "express": "^4.19.2", + "http-proxy-middleware": "^2.0.6", + "mime-types": "^2.1.35", + "p-retry": "4.6.2", + "webpack-dev-middleware": "^7.4.2", + "webpack-dev-server": "5.0.4", + "ws": "^8.16.0" + }, + "peerDependencies": { + "@rspack/core": "*" } }, - "node_modules/@types/pako": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/pako/-/pako-2.0.3.tgz", - "integrity": "sha512-bq0hMV9opAcrmE0Byyo0fY3Ew4tgOevJmQ9grUhpXQhYfyLJ1Kqg3P33JT5fdbT2AjeAjR51zqqVjAL/HMkx7Q==", - "dev": true - }, - "node_modules/@types/parse-json": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", - "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==", - "dev": true - }, - "node_modules/@types/qs": { - "version": "6.9.12", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.12.tgz", - "integrity": "sha512-bZcOkJ6uWrL0Qb2NAWKa7TBU+mJHPzhx9jjLL1KHF+XpzEcR7EXHvjbHlGtR/IsP1vyPrehuS6XqkmaePy//mg==", - "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.4", - "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", - "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", - "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.5", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.5.tgz", - "integrity": "sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==", - "dev": true, - "dependencies": { - "@types/http-errors": "*", - "@types/mime": "*", - "@types/node": "*" - } - }, - "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/statuses": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@types/statuses/-/statuses-2.0.5.tgz", - "integrity": "sha512-jmIUGWrAiwu3dZpxntxieC+1n/5c3mjrImkmOSQ2NC5uP6cYO4aAZDdSmRcI5C1oiTmqlZGHC+/NmJrKogbP5A==", - "dev": true - }, - "node_modules/@types/tern": { - "version": "0.23.9", - "resolved": "https://registry.npmjs.org/@types/tern/-/tern-0.23.9.tgz", - "integrity": "sha512-ypzHFE/wBzh+BlH6rrBgS5I/Z7RD21pGhZ2rltb/+ZrVM1awdZwjx7hE5XfuYgHWk9uvV5HLZN3SloevCAp3Bw==", - "dev": true, - "dependencies": { - "@types/estree": "*" - } - }, - "node_modules/@types/tough-cookie": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz", - "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==", - "dev": true - }, - "node_modules/@types/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@types/which/-/which-2.0.2.tgz", - "integrity": "sha512-113D3mDkZDjo+EeUEHCFy0qniNc1ZpecGiAU7WSo7YDoSzolZIQKpYFHrPpjkB2nuyahcKfrmLXeQlh7gqJYdw==", - "dev": true - }, - "node_modules/@types/wrap-ansi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/wrap-ansi/-/wrap-ansi-3.0.0.tgz", - "integrity": "sha512-ltIpx+kM7g/MLRZfkbL7EsCEjfzCcScLpkg37eXEtx5kmrAKBkTJwd1GIAjDSL8wTpM6Hzn5YO4pSb91BEwu1g==", + "node_modules/@rspack/dev-server/node_modules/@types/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==", "dev": true }, - "node_modules/@types/ws": { - "version": "8.5.10", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz", - "integrity": "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==", + "node_modules/@rspack/dev-server/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": { - "@types/node": "*" + "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/@types/yargs": { - "version": "17.0.32", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", - "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", + "node_modules/@rspack/dev-server/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": { - "@types/yargs-parser": "*" + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" } }, - "node_modules/@types/yargs-parser": { - "version": "21.0.3", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", - "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", + "node_modules/@rspack/dev-server/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/@types/yauzl": { - "version": "2.10.3", - "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", - "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", + "node_modules/@rspack/dev-server/node_modules/p-retry": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", + "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", "dev": true, - "optional": true, "dependencies": { - "@types/node": "*" + "@types/retry": "0.12.0", + "retry": "^0.13.1" + }, + "engines": { + "node": ">=8" } }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.17.0.tgz", - "integrity": "sha512-pyiDhEuLM3PuANxH7uNYan1AaFs5XE0zw1hq69JBvGvE7gSuEoQl1ydtEe/XQeoC3GQxLXyOVa5kNOATgM638A==", + "node_modules/@rspack/dev-server/node_modules/schema-utils": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.0.tgz", + "integrity": "sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==", "dev": true, "dependencies": { - "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.17.0", - "@typescript-eslint/type-utils": "7.17.0", - "@typescript-eslint/utils": "7.17.0", - "@typescript-eslint/visitor-keys": "7.17.0", - "graphemer": "^1.4.0", - "ignore": "^5.3.1", - "natural-compare": "^1.4.0", - "ts-api-utils": "^1.3.0" + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": ">= 10.13.0" }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^7.0.0", - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "url": "https://opencollective.com/webpack" } }, - "node_modules/@typescript-eslint/parser": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.17.0.tgz", - "integrity": "sha512-puiYfGeg5Ydop8eusb/Hy1k7QmOU6X3nvsqCgzrB2K4qMavK//21+PzNE8qeECgNOIoertJPUC1SpegHDI515A==", + "node_modules/@rspack/dev-server/node_modules/webpack-dev-server": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-5.0.4.tgz", + "integrity": "sha512-dljXhUgx3HqKP2d8J/fUMvhxGhzjeNVarDLcbO/EWMSgRizDkxHQDZQaLFL5VJY9tRBj2Gz+rvCEYYvhbqPHNA==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "7.17.0", - "@typescript-eslint/types": "7.17.0", - "@typescript-eslint/typescript-estree": "7.17.0", - "@typescript-eslint/visitor-keys": "7.17.0", - "debug": "^4.3.4" + "@types/bonjour": "^3.5.13", + "@types/connect-history-api-fallback": "^1.5.4", + "@types/express": "^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", + "default-gateway": "^6.0.3", + "express": "^4.17.3", + "graceful-fs": "^4.2.6", + "html-entities": "^2.4.0", + "http-proxy-middleware": "^2.0.3", + "ipaddr.js": "^2.1.0", + "launch-editor": "^2.6.1", + "open": "^10.0.3", + "p-retry": "^6.2.0", + "rimraf": "^5.0.5", + "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.1.0", + "ws": "^8.16.0" + }, + "bin": { + "webpack-dev-server": "bin/webpack-dev-server.js" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": ">= 18.12.0" }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "url": "https://opencollective.com/webpack" }, "peerDependencies": { - "eslint": "^8.56.0" + "webpack": "^5.0.0" }, "peerDependenciesMeta": { - "typescript": { + "webpack": { + "optional": true + }, + "webpack-cli": { "optional": true } } }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.17.0.tgz", - "integrity": "sha512-0P2jTTqyxWp9HiKLu/Vemr2Rg1Xb5B7uHItdVZ6iAenXmPo4SZ86yOPCJwMqpCyaMiEHTNqizHfsbmCFT1x9SA==", + "node_modules/@rspack/dev-server/node_modules/webpack-dev-server/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/@rspack/dev-server/node_modules/webpack-dev-server/node_modules/p-retry": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-6.2.1.tgz", + "integrity": "sha512-hEt02O4hUct5wtwg4H4KcWgDdm+l1bOaEy/hWzd8xtXB9BqxTWBBhb+2ImAtH4Cv4rPjV76xN3Zumqk3k3AhhQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.17.0", - "@typescript-eslint/visitor-keys": "7.17.0" + "@types/retry": "0.12.2", + "is-network-error": "^1.0.0", + "retry": "^0.13.1" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": ">=16.17" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@typescript-eslint/type-utils": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.17.0.tgz", - "integrity": "sha512-XD3aaBt+orgkM/7Cei0XNEm1vwUxQ958AOLALzPlbPqb8C1G8PZK85tND7Jpe69Wualri81PLU+Zc48GVKIMMA==", + "node_modules/@rspack/lite-tapable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@rspack/lite-tapable/-/lite-tapable-1.0.1.tgz", + "integrity": "sha512-VynGOEsVw2s8TAlLf/uESfrgfrq2+rcXB1muPJYBWbsm1Oa6r5qVQhjA5ggM6z/coYPrsVMgovl3Ff7Q7OCp1w==", + "dev": true, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@rtsao/scc": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", + "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", + "dev": true + }, + "node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true + }, + "node_modules/@testing-library/dom": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.0.tgz", + "integrity": "sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "7.17.0", - "@typescript-eslint/utils": "7.17.0", - "debug": "^4.3.4", - "ts-api-utils": "^1.3.0" + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^5.0.1", + "aria-query": "5.3.0", + "chalk": "^4.1.0", + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.5.0", + "pretty-format": "^27.0.2" }, "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "node": ">=18" } }, - "node_modules/@typescript-eslint/types": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.17.0.tgz", - "integrity": "sha512-a29Ir0EbyKTKHnZWbNsrc/gqfIBqYPwj3F2M+jWE/9bqfEHg0AMtXzkbUkOG6QgEScxh2+Pz9OXe11jHDnHR7A==", + "node_modules/@testing-library/user-event": { + "version": "14.6.0", + "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.6.0.tgz", + "integrity": "sha512-+jsfK7kVJbqnCYtLTln8Ja/NmVrZRwBJHmHR9IxIVccMWSOZ6Oy0FkDJNeyVu4QSpMNmRfy10Xb76ObRDlWWBQ==", "dev": true, + "license": "MIT", "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "node": ">=12", + "npm": ">=6" + }, + "peerDependencies": { + "@testing-library/dom": ">=7.21.4" } }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.17.0.tgz", - "integrity": "sha512-72I3TGq93t2GoSBWI093wmKo0n6/b7O4j9o8U+f65TVD0FS6bI2180X5eGEr8MA8PhKMvYe9myZJquUT2JkCZw==", + "node_modules/@tootallnate/quickjs-emscripten": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz", + "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/@types/aria-query": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", + "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/body-parser": { + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.17.0", - "@typescript-eslint/visitor-keys": "7.17.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "@types/connect": "*", + "@types/node": "*" } }, - "node_modules/@typescript-eslint/utils": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.17.0.tgz", - "integrity": "sha512-r+JFlm5NdB+JXc7aWWZ3fKSm1gn0pkswEwIYsrGPdsT2GjsRATAKXiNtp3vgAAO1xZhX8alIOEQnNMl3kbTgJw==", + "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": { - "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.17.0", - "@typescript-eslint/types": "7.17.0", - "@typescript-eslint/typescript-estree": "7.17.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" + "@types/node": "*" } }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.17.0.tgz", - "integrity": "sha512-RVGC9UhPOCsfCdI9pU++K4nD7to+jTcMIbXTSOcrLqUEW6gF2pU1UUbYJKc9cvcRSK1UDeMJ7pdMxf4bhMpV/A==", + "node_modules/@types/codemirror": { + "version": "5.60.15", + "resolved": "https://registry.npmjs.org/@types/codemirror/-/codemirror-5.60.15.tgz", + "integrity": "sha512-dTOvwEQ+ouKJ/rE9LT1Ue2hmP6H1mZv5+CCnNWu2qtiOe2LQa9lCprEY20HxiDmV/Bxh+dXjywmy5aKvoGjULA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.17.0", - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "@types/tern": "*" } }, - "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "dev": true - }, - "node_modules/@vitest/browser": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@vitest/browser/-/browser-2.0.4.tgz", - "integrity": "sha512-QsIkbqPqHsXvgxjCjjgKjuWKmrC0VJgpaDkuEmOy5gTnErhhifWIfp3HpH92K7cscfaIao+RlKv5f8nUMgjfmA==", + "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": { - "@testing-library/dom": "^10.3.1", - "@testing-library/user-event": "^14.5.2", - "@vitest/utils": "2.0.4", - "magic-string": "^0.30.10", - "msw": "^2.3.1", - "sirv": "^2.0.4", - "ws": "^8.18.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - }, - "peerDependencies": { - "playwright": "*", - "vitest": "2.0.4", - "webdriverio": "*" - }, - "peerDependenciesMeta": { - "playwright": { - "optional": true - }, - "safaridriver": { - "optional": true - }, - "webdriverio": { - "optional": true - } + "@types/node": "*" } }, - "node_modules/@vitest/expect": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.0.4.tgz", - "integrity": "sha512-39jr5EguIoanChvBqe34I8m1hJFI4+jxvdOpD7gslZrVQBKhh8H9eD7J/LJX4zakrw23W+dITQTDqdt43xVcJw==", + "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": { - "@vitest/spy": "2.0.4", - "@vitest/utils": "2.0.4", - "chai": "^5.1.1", - "tinyrainbow": "^1.2.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" + "@types/express-serve-static-core": "*", + "@types/node": "*" } }, - "node_modules/@vitest/pretty-format": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.0.4.tgz", - "integrity": "sha512-RYZl31STbNGqf4l2eQM1nvKPXE0NhC6Eq0suTTePc4mtMQ1Fn8qZmjV4emZdEdG2NOWGKSCrHZjmTqDCDoeFBw==", + "node_modules/@types/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==", + "dev": true + }, + "node_modules/@types/eslint": { + "version": "8.56.12", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.12.tgz", + "integrity": "sha512-03ruubjWyOHlmljCVoxSuNDdmfZDzsrrz0P2LeJsOXr+ZwFQ+0yQIwNCwt/GYhV7Z31fgtXJTAEs+FYlEL851g==", "dev": true, "dependencies": { - "tinyrainbow": "^1.2.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" + "@types/estree": "*", + "@types/json-schema": "*" } }, - "node_modules/@vitest/runner": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-2.0.4.tgz", - "integrity": "sha512-Gk+9Su/2H2zNfNdeJR124gZckd5st4YoSuhF1Rebi37qTXKnqYyFCd9KP4vl2cQHbtuVKjfEKrNJxHHCW8thbQ==", + "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, + "optional": true, + "peer": true, "dependencies": { - "@vitest/utils": "2.0.4", - "pathe": "^1.1.2" - }, - "funding": { - "url": "https://opencollective.com/vitest" + "@types/eslint": "*", + "@types/estree": "*" } }, - "node_modules/@vitest/snapshot": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.0.4.tgz", - "integrity": "sha512-or6Mzoz/pD7xTvuJMFYEtso1vJo1S5u6zBTinfl+7smGUhqybn6VjzCDMhmTyVOFWwkCMuNjmNNxnyXPgKDoPw==", + "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.21", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", "dev": true, "dependencies": { - "@vitest/pretty-format": "2.0.4", - "magic-string": "^0.30.10", - "pathe": "^1.1.2" - }, - "funding": { - "url": "https://opencollective.com/vitest" + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" } }, - "node_modules/@vitest/spy": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.0.4.tgz", - "integrity": "sha512-uTXU56TNoYrTohb+6CseP8IqNwlNdtPwEO0AWl+5j7NelS6x0xZZtP0bDWaLvOfUbaYwhhWp1guzXUxkC7mW7Q==", + "node_modules/@types/express-serve-static-core": { + "version": "4.17.43", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.43.tgz", + "integrity": "sha512-oaYtiBirUOPQGSWNGPWnzyAFJ0BP3cwvN4oWZQY+zUBwpVIGsKUkpBpSztp74drYcjavs7SKFZ4DX1V2QeN8rg==", "dev": true, "dependencies": { - "tinyspy": "^3.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" } }, - "node_modules/@vitest/ui": { + "node_modules/@types/gl-matrix": { + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/@types/gl-matrix/-/gl-matrix-2.4.5.tgz", + "integrity": "sha512-0L8Mq1+oaIW0oVzGUDbSW+HnTjCNb4CmoIQE5BkoHt/A7x20z0MJ1PnwfH3atty/vbWLGgvJwVu2Mz3SKFiEFw==", + "dev": true + }, + "node_modules/@types/http-errors": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@vitest/ui/-/ui-2.0.4.tgz", - "integrity": "sha512-9SNE9ve3kgDkVTxJsY7BjqSwyqDVRJbq/AHVHZs+V0vmr/0cCX6yGT6nOahSXEsXFtKAsvRtBXKlTgr+5njzZQ==", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", + "dev": true + }, + "node_modules/@types/http-proxy": { + "version": "1.17.15", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.15.tgz", + "integrity": "sha512-25g5atgiVNTIv0LBDTg1H74Hvayx0ajtJPLLcYE3whFv75J0pWNtOBzaXJQgDTmrX1bx5U9YC2w/n65BN1HwRQ==", "dev": true, "dependencies": { - "@vitest/utils": "2.0.4", - "fast-glob": "^3.3.2", - "fflate": "^0.8.2", - "flatted": "^3.3.1", - "pathe": "^1.1.2", - "sirv": "^2.0.4", - "tinyrainbow": "^1.2.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - }, - "peerDependencies": { - "vitest": "2.0.4" + "@types/node": "*" } }, - "node_modules/@vitest/utils": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.0.4.tgz", - "integrity": "sha512-Zc75QuuoJhOBnlo99ZVUkJIuq4Oj0zAkrQ2VzCqNCx6wAwViHEh5Fnp4fiJTE9rA+sAoXRf00Z9xGgfEzV6fzQ==", + "node_modules/@types/http-server": { + "version": "0.12.4", + "resolved": "https://registry.npmjs.org/@types/http-server/-/http-server-0.12.4.tgz", + "integrity": "sha512-vsn4pvP2oRFALLuM5Rca6qUmSPG7u0VNjOuqvL57l3bKldQRWdUZPeSiARhzagDxgfNCHn/o8WlWk4KinBauUg==", "dev": true, "dependencies": { - "@vitest/pretty-format": "2.0.4", - "estree-walker": "^3.0.3", - "loupe": "^3.1.1", - "tinyrainbow": "^1.2.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" + "@types/connect": "*" } }, - "node_modules/@wdio/config": { - "version": "8.39.0", - "resolved": "https://registry.npmjs.org/@wdio/config/-/config-8.39.0.tgz", - "integrity": "sha512-yNuGPMPibY91s936gnJCHWlStvIyDrwLwGfLC/NCdTin4F7HL4Gp5iJnHWkJFty1/DfFi8jjoIUBNLM8HEez+A==", + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", + "dev": true + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", + "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", "dev": true, "dependencies": { - "@wdio/logger": "8.38.0", - "@wdio/types": "8.39.0", - "@wdio/utils": "8.39.0", - "decamelize": "^6.0.0", - "deepmerge-ts": "^5.0.0", - "glob": "^10.2.2", - "import-meta-resolve": "^4.0.0" - }, - "engines": { - "node": "^16.13 || >=18" + "@types/istanbul-lib-coverage": "*" } }, - "node_modules/@wdio/config/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/@types/istanbul-reports": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", + "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", "dev": true, "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" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "@types/istanbul-lib-report": "*" } }, - "node_modules/@wdio/config/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/@types/jsdom": { + "version": "21.1.7", + "resolved": "https://registry.npmjs.org/@types/jsdom/-/jsdom-21.1.7.tgz", + "integrity": "sha512-yOriVnggzrnQ3a9OKOCxaVuSug3w3/SbOj5i7VwXWZEyUNl3bLF9V3MfxGbZKuwqJOQyRfqXyROBB1CoZLFWzA==", "dev": true, "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" + "@types/node": "*", + "@types/tough-cookie": "*", + "parse5": "^7.0.0" } }, - "node_modules/@wdio/config/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/@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/@wdio/config/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==", - "dev": true, - "dependencies": { - "lru-cache": "^10.2.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" - }, - "engines": { - "node": ">=16 || 14 >=14.18" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true }, - "node_modules/@wdio/logger": { - "version": "8.38.0", - "resolved": "https://registry.npmjs.org/@wdio/logger/-/logger-8.38.0.tgz", - "integrity": "sha512-kcHL86RmNbcQP+Gq/vQUGlArfU6IIcbbnNp32rRIraitomZow+iEoc519rdQmSVusDozMS5DZthkgDdxK+vz6Q==", + "node_modules/@types/lodash": { + "version": "4.14.202", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.202.tgz", + "integrity": "sha512-OvlIYQK9tNneDlS0VN54LLd5uiPCBOp7gS5Z0f1mjoJYBrtStzgmJBxONW3U6OZqdtNzZPmn9BS/7WI7BFFcFQ==", + "dev": true + }, + "node_modules/@types/lodash-es": { + "version": "4.17.12", + "resolved": "https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.12.tgz", + "integrity": "sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==", "dev": true, "dependencies": { - "chalk": "^5.1.2", - "loglevel": "^1.6.0", - "loglevel-plugin-prefix": "^0.8.4", - "strip-ansi": "^7.1.0" - }, - "engines": { - "node": "^16.13 || >=18" + "@types/lodash": "*" } }, - "node_modules/@wdio/logger/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } + "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/@wdio/logger/node_modules/chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "node_modules/@types/node": { + "version": "22.10.7", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.7.tgz", + "integrity": "sha512-V09KvXxFiutGp6B7XkpaDXlNadZxrzajcY50EuoLIpQ6WWYCSvf19lVIazzfIzQvhUN2HjX12spLojTnhuKlGg==", "dev": true, - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "license": "MIT", + "dependencies": { + "undici-types": "~6.20.0" } }, - "node_modules/@wdio/logger/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/@types/node-forge": { + "version": "1.3.11", + "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.11.tgz", + "integrity": "sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==", "dev": true, "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" + "@types/node": "*" } }, - "node_modules/@wdio/protocols": { - "version": "8.38.0", - "resolved": "https://registry.npmjs.org/@wdio/protocols/-/protocols-8.38.0.tgz", - "integrity": "sha512-7BPi7aXwUtnXZPeWJRmnCNFjyDvGrXlBmN9D4Pi58nILkyjVRQKEY9/qv/pcdyB0cvmIvw++Kl/1Lg+RxG++UA==", + "node_modules/@types/nunjucks": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/@types/nunjucks/-/nunjucks-3.2.6.tgz", + "integrity": "sha512-pHiGtf83na1nCzliuAdq8GowYiXvH5l931xZ0YEHaLMNFgynpEqx+IPStlu7UaDkehfvl01e4x/9Tpwhy7Ue3w==", "dev": true }, - "node_modules/@wdio/repl": { - "version": "8.24.12", - "resolved": "https://registry.npmjs.org/@wdio/repl/-/repl-8.24.12.tgz", - "integrity": "sha512-321F3sWafnlw93uRTSjEBVuvWCxTkWNDs7ektQS15drrroL3TMeFOynu4rDrIz0jXD9Vas0HCD2Tq/P0uxFLdw==", + "node_modules/@types/qs": { + "version": "6.9.12", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.12.tgz", + "integrity": "sha512-bZcOkJ6uWrL0Qb2NAWKa7TBU+mJHPzhx9jjLL1KHF+XpzEcR7EXHvjbHlGtR/IsP1vyPrehuS6XqkmaePy//mg==", + "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/s3rver": { + "version": "3.7.4", + "resolved": "https://registry.npmjs.org/@types/s3rver/-/s3rver-3.7.4.tgz", + "integrity": "sha512-CMCmdNszxS2FsIznWvBMVCl6fpvr5ueaFCaY0iSoH7Ud5maGcLghukpDvsXBnIcp92cv2HeVnVqI1p8yPcab9Q==", "dev": true, "dependencies": { - "@types/node": "^20.1.0" - }, - "engines": { - "node": "^16.13 || >=18" + "@types/node": "*" } }, - "node_modules/@wdio/types": { - "version": "8.39.0", - "resolved": "https://registry.npmjs.org/@wdio/types/-/types-8.39.0.tgz", - "integrity": "sha512-86lcYROTapOJuFd9ouomFDfzDnv3Kn+jE0RmqfvN9frZAeLVJ5IKjX9M6HjplsyTZhjGO1uCaehmzx+HJus33Q==", + "node_modules/@types/send": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", "dev": true, "dependencies": { - "@types/node": "^20.1.0" - }, - "engines": { - "node": "^16.13 || >=18" + "@types/mime": "^1", + "@types/node": "*" } }, - "node_modules/@wdio/utils": { - "version": "8.39.0", - "resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-8.39.0.tgz", - "integrity": "sha512-jY+n6jlGeK+9Tx8T659PKLwMQTGpLW5H78CSEWgZLbjbVSr2LfGR8Lx0CRktNXxAtqEVZPj16Pi74OtAhvhE6Q==", + "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": { - "@puppeteer/browsers": "^1.6.0", - "@wdio/logger": "8.38.0", - "@wdio/types": "8.39.0", - "decamelize": "^6.0.0", - "deepmerge-ts": "^5.1.0", - "edgedriver": "^5.5.0", - "geckodriver": "^4.3.1", - "get-port": "^7.0.0", - "import-meta-resolve": "^4.0.0", - "locate-app": "^2.1.0", - "safaridriver": "^0.1.0", - "split2": "^4.2.0", - "wait-port": "^1.0.4" - }, - "engines": { - "node": "^16.13 || >=18" + "@types/express": "*" } }, - "node_modules/@webassemblyjs/ast": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", - "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", + "node_modules/@types/serve-static": { + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.5.tgz", + "integrity": "sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==", "dev": true, "dependencies": { - "@webassemblyjs/helper-numbers": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6" + "@types/http-errors": "*", + "@types/mime": "*", + "@types/node": "*" } }, - "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", - "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", - "dev": true + "node_modules/@types/sinonjs__fake-timers": { + "version": "8.1.5", + "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.5.tgz", + "integrity": "sha512-mQkU2jY8jJEF7YHjHvsQO8+3ughTL1mcnn96igfhONmR+fUPSKIkefQYpSe8bsly2Ep7oQbn/6VG5/9/0qcArQ==", + "dev": true, + "optional": true, + "peer": true }, - "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", - "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", - "dev": true + "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/@webassemblyjs/helper-buffer": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", - "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==", + "node_modules/@types/statuses": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@types/statuses/-/statuses-2.0.5.tgz", + "integrity": "sha512-jmIUGWrAiwu3dZpxntxieC+1n/5c3mjrImkmOSQ2NC5uP6cYO4aAZDdSmRcI5C1oiTmqlZGHC+/NmJrKogbP5A==", "dev": true }, - "node_modules/@webassemblyjs/helper-numbers": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", - "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", + "node_modules/@types/tern": { + "version": "0.23.9", + "resolved": "https://registry.npmjs.org/@types/tern/-/tern-0.23.9.tgz", + "integrity": "sha512-ypzHFE/wBzh+BlH6rrBgS5I/Z7RD21pGhZ2rltb/+ZrVM1awdZwjx7hE5XfuYgHWk9uvV5HLZN3SloevCAp3Bw==", "dev": true, "dependencies": { - "@webassemblyjs/floating-point-hex-parser": "1.11.6", - "@webassemblyjs/helper-api-error": "1.11.6", - "@xtuc/long": "4.2.2" + "@types/estree": "*" } }, - "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", - "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", + "node_modules/@types/tough-cookie": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz", + "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==", "dev": true }, - "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", - "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", + "node_modules/@types/triple-beam": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/triple-beam/-/triple-beam-1.3.5.tgz", + "integrity": "sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==", + "dev": true + }, + "node_modules/@types/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@types/which/-/which-2.0.2.tgz", + "integrity": "sha512-113D3mDkZDjo+EeUEHCFy0qniNc1ZpecGiAU7WSo7YDoSzolZIQKpYFHrPpjkB2nuyahcKfrmLXeQlh7gqJYdw==", "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/wasm-gen": "1.12.1" - } + "optional": true, + "peer": true }, - "node_modules/@webassemblyjs/ieee754": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", - "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", + "node_modules/@types/ws": { + "version": "8.5.10", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz", + "integrity": "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==", "dev": true, "dependencies": { - "@xtuc/ieee754": "^1.2.0" + "@types/node": "*" } }, - "node_modules/@webassemblyjs/leb128": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", - "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", + "node_modules/@types/yargs": { + "version": "17.0.33", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz", + "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==", "dev": true, "dependencies": { - "@xtuc/long": "4.2.2" + "@types/yargs-parser": "*" } }, - "node_modules/@webassemblyjs/utf8": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", - "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", + "node_modules/@types/yargs-parser": { + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", "dev": true }, - "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", - "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", + "node_modules/@types/yauzl": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", + "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", "dev": true, + "optional": true, + "peer": true, "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/helper-wasm-section": "1.12.1", - "@webassemblyjs/wasm-gen": "1.12.1", - "@webassemblyjs/wasm-opt": "1.12.1", - "@webassemblyjs/wasm-parser": "1.12.1", - "@webassemblyjs/wast-printer": "1.12.1" + "@types/node": "*" } }, - "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", - "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.20.0.tgz", + "integrity": "sha512-naduuphVw5StFfqp4Gq4WhIBE2gN1GEmMUExpJYknZJdRnc+2gDzB8Z3+5+/Kv33hPQRDGzQO/0opHE72lZZ6A==", "dev": true, + "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "8.20.0", + "@typescript-eslint/type-utils": "8.20.0", + "@typescript-eslint/utils": "8.20.0", + "@typescript-eslint/visitor-keys": "8.20.0", + "graphemer": "^1.4.0", + "ignore": "^5.3.1", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" } }, - "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", - "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", + "node_modules/@typescript-eslint/parser": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.20.0.tgz", + "integrity": "sha512-gKXG7A5HMyjDIedBi6bUrDcun8GIjnI8qOwVLiY3rx6T/sHP/19XLJOnIq/FgQvWLHja5JN/LSE7eklNBr612g==", "dev": true, + "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-buffer": "1.12.1", - "@webassemblyjs/wasm-gen": "1.12.1", - "@webassemblyjs/wasm-parser": "1.12.1" + "@typescript-eslint/scope-manager": "8.20.0", + "@typescript-eslint/types": "8.20.0", + "@typescript-eslint/typescript-estree": "8.20.0", + "@typescript-eslint/visitor-keys": "8.20.0", + "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 <5.8.0" } }, - "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", - "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.20.0.tgz", + "integrity": "sha512-J7+VkpeGzhOt3FeG1+SzhiMj9NzGD/M6KoGn9f4dbz3YzK9hvbhVTmLj/HiTp9DazIzJ8B4XcM80LrR9Dm1rJw==", "dev": true, + "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@webassemblyjs/helper-api-error": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" + "@typescript-eslint/types": "8.20.0", + "@typescript-eslint/visitor-keys": "8.20.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@webassemblyjs/wast-printer": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", - "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", + "node_modules/@typescript-eslint/type-utils": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.20.0.tgz", + "integrity": "sha512-bPC+j71GGvA7rVNAHAtOjbVXbLN5PkwqMvy1cwGeaxUoRQXVuKCebRoLzm+IPW/NtFFpstn1ummSIasD5t60GA==", "dev": true, + "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.12.1", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webpack-cli/configtest": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.1.tgz", - "integrity": "sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==", - "dev": true, + "@typescript-eslint/typescript-estree": "8.20.0", + "@typescript-eslint/utils": "8.20.0", + "debug": "^4.3.4", + "ts-api-utils": "^2.0.0" + }, "engines": { - "node": ">=14.15.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "webpack": "5.x.x", - "webpack-cli": "5.x.x" + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" } }, - "node_modules/@webpack-cli/info": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.2.tgz", - "integrity": "sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==", + "node_modules/@typescript-eslint/types": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.20.0.tgz", + "integrity": "sha512-cqaMiY72CkP+2xZRrFt3ExRBu0WmVitN/rYPZErA80mHjHx/Svgp8yfbzkJmDoQ/whcytOPO9/IZXnOc+wigRA==", "dev": true, + "license": "MIT", "engines": { - "node": ">=14.15.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, - "peerDependencies": { - "webpack": "5.x.x", - "webpack-cli": "5.x.x" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@webpack-cli/serve": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.5.tgz", - "integrity": "sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==", + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.20.0.tgz", + "integrity": "sha512-Y7ncuy78bJqHI35NwzWol8E0X7XkRVS4K4P4TCyzWkOJih5NDvtoRDW4Ba9YJJoB2igm9yXDdYI/+fkiiAxPzA==", "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.20.0", + "@typescript-eslint/visitor-keys": "8.20.0", + "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.0.0" + }, "engines": { - "node": ">=14.15.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, - "peerDependencies": { - "webpack": "5.x.x", - "webpack-cli": "5.x.x" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" }, - "peerDependenciesMeta": { - "webpack-dev-server": { - "optional": true - } - } - }, - "node_modules/@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true - }, - "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/@zip.js/zip.js": { - "version": "2.7.47", - "resolved": "https://registry.npmjs.org/@zip.js/zip.js/-/zip.js-2.7.47.tgz", - "integrity": "sha512-jmtJMA3/Jl4rMzo/DZ79s6g0CJ1AZcNAO6emTy/vHfIKAB/iiFY7PLs6KmbRTJ+F8GnK2eCLnjQfCCneRxXgzg==", - "dev": true, - "engines": { - "bun": ">=0.7.0", - "deno": ">=1.0.0", - "node": ">=16.5.0" - } - }, - "node_modules/abab": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/abab/-/abab-1.0.4.tgz", - "integrity": "sha512-I+Wi+qiE2kUXyrRhNsWv6XsjUTBJjSoVSctKNBfLG5zG/Xe7Rjbxf13+vqYHNTwHaFU+FtSlVxOCTiMEVtPv0A==", - "deprecated": "Use your platform's native atob() and btoa() methods instead" - }, - "node_modules/abbrev": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-2.0.0.tgz", - "integrity": "sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "peerDependencies": { + "typescript": ">=4.8.4 <5.8.0" } }, - "node_modules/abort-controller": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "node_modules/@typescript-eslint/utils": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.20.0.tgz", + "integrity": "sha512-dq70RUw6UK9ei7vxc4KQtBRk7qkHZv447OUZ6RPQMQl71I3NZxQJX/f32Smr+iqWrB02pHKn2yAdHBb0KNrRMA==", "dev": true, + "license": "MIT", "dependencies": { - "event-target-shim": "^5.0.0" + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "8.20.0", + "@typescript-eslint/types": "8.20.0", + "@typescript-eslint/typescript-estree": "8.20.0" }, "engines": { - "node": ">=6.5" + "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 <5.8.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==", + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.20.0.tgz", + "integrity": "sha512-v/BpkeeYAsPkKCkR8BDwcno0llhzWVqPOamQrAEMdpZav2Y9OVjd9dwJyBLJWwf335B5DmlifECIkZRJCaGaHA==", "dev": true, + "license": "MIT", "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" + "@typescript-eslint/types": "8.20.0", + "eslint-visitor-keys": "^4.2.0" }, "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/acorn": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", "dev": true, - "bin": { - "acorn": "bin/acorn" - }, + "license": "Apache-2.0", "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-globals": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.4.tgz", - "integrity": "sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A==", - "dependencies": { - "acorn": "^6.0.1", - "acorn-walk": "^6.0.1" - } - }, - "node_modules/acorn-globals/node_modules/acorn": { - "version": "6.4.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", - "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", - "bin": { - "acorn": "bin/acorn" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-import-attributes": { - "version": "1.9.5", - "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", - "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", - "dev": true, - "peerDependencies": { - "acorn": "^8" + "funding": { + "url": "https://opencollective.com/eslint" } }, - "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==", + "node_modules/@vitest/browser": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@vitest/browser/-/browser-3.0.2.tgz", + "integrity": "sha512-EVXRQTEmwyCNh6qDXIf/fGWp3YXa3KtsMCOXmlD4Yeq62pJaqJ5+iUIY1XLN7TO2iXatGDdLZYbHbR6YQT4FDw==", "dev": true, + "license": "MIT", + "dependencies": { + "@testing-library/dom": "^10.4.0", + "@testing-library/user-event": "^14.6.0", + "@vitest/mocker": "3.0.2", + "@vitest/utils": "3.0.2", + "magic-string": "^0.30.17", + "msw": "^2.7.0", + "sirv": "^3.0.0", + "tinyrainbow": "^2.0.0", + "ws": "^8.18.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/acorn-walk": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.2.0.tgz", - "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==", - "engines": { - "node": ">=0.4.0" + "playwright": "*", + "vitest": "3.0.2", + "webdriverio": "*" + }, + "peerDependenciesMeta": { + "playwright": { + "optional": true + }, + "safaridriver": { + "optional": true + }, + "webdriverio": { + "optional": true + } } }, - "node_modules/agent-base": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", - "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", + "node_modules/@vitest/browser/node_modules/sirv": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-3.0.0.tgz", + "integrity": "sha512-BPwJGUeDaDCHihkORDchNyyTvWFhcusy1XMmhEVTQTwGeybFbp8YEmB+njbPnth1FibULBSBVwCQni25XlCUDg==", "dev": true, "dependencies": { - "debug": "^4.3.4" + "@polka/url": "^1.0.0-next.24", + "mrmime": "^2.0.0", + "totalist": "^3.0.0" }, "engines": { - "node": ">= 14" + "node": ">=18" } }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "node_modules/@vitest/expect": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.0.2.tgz", + "integrity": "sha512-dKSHLBcoZI+3pmP5hiZ7I5grNru2HRtEW8Z5Zp4IXog8QYcxhlox7JUPyIIFWfN53+3HW3KPLIl6nSzUGgKSuQ==", + "dev": true, + "license": "MIT", "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" + "@vitest/spy": "3.0.2", + "@vitest/utils": "3.0.2", + "chai": "^5.1.2", + "tinyrainbow": "^2.0.0" }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "url": "https://opencollective.com/vitest" } }, - "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/@vitest/mocker": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.0.2.tgz", + "integrity": "sha512-Hr09FoBf0jlwwSyzIF4Xw31OntpO3XtZjkccpcBf8FeVW3tpiyKlkeUzxS/txzHqpUCNIX157NaTySxedyZLvA==", "dev": true, + "license": "MIT", "dependencies": { - "ajv": "^8.0.0" + "@vitest/spy": "3.0.2", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.17" + }, + "funding": { + "url": "https://opencollective.com/vitest" }, "peerDependencies": { - "ajv": "^8.0.0" + "msw": "^2.4.9", + "vite": "^5.0.0 || ^6.0.0" }, "peerDependenciesMeta": { - "ajv": { + "msw": { + "optional": true + }, + "vite": { "optional": true } } }, - "node_modules/ajv-formats/node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "node_modules/@vitest/pretty-format": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.0.2.tgz", + "integrity": "sha512-yBohcBw/T/p0/JRgYD+IYcjCmuHzjC3WLAKsVE4/LwiubzZkE8N49/xIQ/KGQwDRA8PaviF8IRO8JMWMngdVVQ==", "dev": true, + "license": "MIT", "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" + "tinyrainbow": "^2.0.0" }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ajv-formats/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/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "dev": true, - "peerDependencies": { - "ajv": "^6.9.1" + "url": "https://opencollective.com/vitest" } }, - "node_modules/ansi-align": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", - "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", + "node_modules/@vitest/runner": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.0.2.tgz", + "integrity": "sha512-GHEsWoncrGxWuW8s405fVoDfSLk6RF2LCXp6XhevbtDjdDme1WV/eNmUueDfpY1IX3MJaCRelVCEXsT9cArfEg==", "dev": true, + "license": "MIT", "dependencies": { - "string-width": "^4.1.0" + "@vitest/utils": "3.0.2", + "pathe": "^2.0.1" + }, + "funding": { + "url": "https://opencollective.com/vitest" } }, - "node_modules/ansi-align/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/ansi-align/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/@vitest/snapshot": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.0.2.tgz", + "integrity": "sha512-h9s67yD4+g+JoYG0zPCo/cLTabpDqzqNdzMawmNPzDStTiwxwkyYM1v5lWE8gmGv3SVJ2DcxA2NpQJZJv9ym3g==", "dev": true, + "license": "MIT", "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" + "@vitest/pretty-format": "3.0.2", + "magic-string": "^0.30.17", + "pathe": "^2.0.1" }, - "engines": { - "node": ">=8" - } - }, - "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" + "funding": { + "url": "https://opencollective.com/vitest" } }, - "node_modules/ansi-escapes": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-5.0.0.tgz", - "integrity": "sha512-5GFMVX8HqE/TB+FuBJGuO5XG0WrsA6ptUqoODaT/n9mmUaZFkqnBueB4leqGBCmrUHnCnC4PCZTCd0E7QQ83bA==", + "node_modules/@vitest/spy": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.0.2.tgz", + "integrity": "sha512-8mI2iUn+PJFMT44e3ISA1R+K6ALVs47W6eriDTfXe6lFqlflID05MB4+rIFhmDSLBj8iBsZkzBYlgSkinxLzSQ==", "dev": true, + "license": "MIT", "dependencies": { - "type-fest": "^1.0.2" - }, - "engines": { - "node": ">=12" + "tinyspy": "^3.0.2" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://opencollective.com/vitest" } }, - "node_modules/ansi-escapes/node_modules/type-fest": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", - "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", + "node_modules/@vitest/ui": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@vitest/ui/-/ui-3.0.2.tgz", + "integrity": "sha512-R0E4nG0OAafsCKwKnENLdjpMbxAyDqT/hdbJp71eeAR1wE+C7IFv1G158sRj5gUfJ7pM7IxtcwIqa34beYzLhg==", "dev": true, - "engines": { - "node": ">=10" + "license": "MIT", + "dependencies": { + "@vitest/utils": "3.0.2", + "fflate": "^0.8.2", + "flatted": "^3.3.2", + "pathe": "^2.0.1", + "sirv": "^3.0.0", + "tinyglobby": "^0.2.10", + "tinyrainbow": "^2.0.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "vitest": "3.0.2" } }, - "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==", + "node_modules/@vitest/ui/node_modules/sirv": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-3.0.0.tgz", + "integrity": "sha512-BPwJGUeDaDCHihkORDchNyyTvWFhcusy1XMmhEVTQTwGeybFbp8YEmB+njbPnth1FibULBSBVwCQni25XlCUDg==", "dev": true, - "engines": [ - "node >= 0.8.0" - ], - "bin": { - "ansi-html": "bin/ansi-html" - } - }, - "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==", - "engines": { - "node": ">=8" - } - }, - "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==", + "license": "MIT", "dependencies": { - "color-convert": "^2.0.1" + "@polka/url": "^1.0.0-next.24", + "mrmime": "^2.0.0", + "totalist": "^3.0.0" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "node": ">=18" } }, - "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==", + "node_modules/@vitest/utils": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.0.2.tgz", + "integrity": "sha512-Qu01ZYZlgHvDP02JnMBRpX43nRaZtNpIzw3C1clDXmn8eakgX6iQVGzTQ/NjkIr64WD8ioqOjkaYRVvHQI5qiw==", "dev": true, + "license": "MIT", "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" + "@vitest/pretty-format": "3.0.2", + "loupe": "^3.1.2", + "tinyrainbow": "^2.0.0" }, - "engines": { - "node": ">= 8" + "funding": { + "url": "https://opencollective.com/vitest" } }, - "node_modules/archiver": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/archiver/-/archiver-7.0.1.tgz", - "integrity": "sha512-ZcbTaIqJOfCc03QwD468Unz/5Ir8ATtvAHsK+FdXbDIbGfihqh9mrvdcYunQzqn4HrvWWaFyaxJhGZagaJJpPQ==", + "node_modules/@vitest/web-worker": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@vitest/web-worker/-/web-worker-3.0.2.tgz", + "integrity": "sha512-38hmHAp2tB7H9VPUzFOb4rKFStjE0lRCE8k4ljunTDfkvndi68/6XK8UKADAikwDKcmEdsXldJIJxAFhr9RfVw==", "dev": true, + "license": "MIT", "dependencies": { - "archiver-utils": "^5.0.2", - "async": "^3.2.4", - "buffer-crc32": "^1.0.0", - "readable-stream": "^4.0.0", - "readdir-glob": "^1.1.2", - "tar-stream": "^3.0.0", - "zip-stream": "^6.0.1" + "debug": "^4.4.0" }, - "engines": { - "node": ">= 14" + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "vitest": "3.0.2" } }, - "node_modules/archiver-utils": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-5.0.2.tgz", - "integrity": "sha512-wuLJMmIBQYCsGZgYLTy5FIB2pF6Lfb6cXMSF8Qywwk3t20zWnAi7zLcQFdKQmIB8wyZpY5ER38x08GbwtR2cLA==", + "node_modules/@wdio/config": { + "version": "9.2.8", + "resolved": "https://registry.npmjs.org/@wdio/config/-/config-9.2.8.tgz", + "integrity": "sha512-EGMmBPGJbz6RmgMjebRWkWu3fGyeTIRcusF4UA4f2tiUEKY8nbzUO/ZyDjVQNR+YVB40q0jcqAqpszYRrIzzeg==", "dev": true, + "optional": true, + "peer": true, "dependencies": { - "glob": "^10.0.0", - "graceful-fs": "^4.2.0", - "is-stream": "^2.0.1", - "lazystream": "^1.0.0", - "lodash": "^4.17.15", - "normalize-path": "^3.0.0", - "readable-stream": "^4.0.0" + "@wdio/logger": "9.1.3", + "@wdio/types": "9.2.2", + "@wdio/utils": "9.2.8", + "decamelize": "^6.0.0", + "deepmerge-ts": "^7.0.3", + "glob": "^10.2.2", + "import-meta-resolve": "^4.0.0" }, "engines": { - "node": ">= 14" - } - }, - "node_modules/archiver-utils/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, - "engines": { - "node": ">=0.8.x" + "node": ">=18.20.0" } }, - "node_modules/archiver-utils/node_modules/glob": { + "node_modules/@wdio/config/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, + "optional": true, + "peer": true, "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", @@ -2874,23 +3426,13 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/archiver-utils/node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/archiver-utils/node_modules/jackspeak": { + "node_modules/@wdio/config/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==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "@isaacs/cliui": "^8.0.2" }, @@ -2901,17 +3443,21 @@ "@pkgjs/parseargs": "^0.11.0" } }, - "node_modules/archiver-utils/node_modules/lru-cache": { + "node_modules/@wdio/config/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 + "dev": true, + "optional": true, + "peer": true }, - "node_modules/archiver-utils/node_modules/path-scurry": { + "node_modules/@wdio/config/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==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" @@ -2923,1230 +3469,1207 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/archiver-utils/node_modules/readable-stream": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", - "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", + "node_modules/@wdio/logger": { + "version": "9.1.3", + "resolved": "https://registry.npmjs.org/@wdio/logger/-/logger-9.1.3.tgz", + "integrity": "sha512-cumRMK/gE1uedBUw3WmWXOQ7HtB6DR8EyKQioUz2P0IJtRRpglMBdZV7Svr3b++WWawOuzZHMfbTkJQmaVt8Gw==", "dev": true, + "optional": true, + "peer": true, "dependencies": { - "abort-controller": "^3.0.0", - "buffer": "^6.0.3", - "events": "^3.3.0", - "process": "^0.11.10", - "string_decoder": "^1.3.0" + "chalk": "^5.1.2", + "loglevel": "^1.6.0", + "loglevel-plugin-prefix": "^0.8.4", + "strip-ansi": "^7.1.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": ">=18.20.0" } }, - "node_modules/archiver-utils/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/@wdio/logger/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": { - "safe-buffer": "~5.2.0" + "optional": true, + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, - "node_modules/archiver/node_modules/events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "node_modules/@wdio/logger/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", "dev": true, + "optional": true, + "peer": true, "engines": { - "node": ">=0.8.x" + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/archiver/node_modules/readable-stream": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", - "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", + "node_modules/@wdio/logger/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==", "dev": true, + "optional": true, + "peer": true, "dependencies": { - "abort-controller": "^3.0.0", - "buffer": "^6.0.3", - "events": "^3.3.0", - "process": "^0.11.10", - "string_decoder": "^1.3.0" + "ansi-regex": "^6.0.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "node_modules/archiver/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/@wdio/protocols": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/@wdio/protocols/-/protocols-9.2.2.tgz", + "integrity": "sha512-0GMUSHCbYm+J+rnRU6XPtaUgVCRICsiH6W5zCXpePm3wLlbmg/mvZ+4OnNErssbpIOulZuAmC2jNmut2AEfWSw==", "dev": true, - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "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 + "optional": true, + "peer": true }, - "node_modules/aria-query": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", - "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "node_modules/@wdio/repl": { + "version": "9.0.8", + "resolved": "https://registry.npmjs.org/@wdio/repl/-/repl-9.0.8.tgz", + "integrity": "sha512-3iubjl4JX5zD21aFxZwQghqC3lgu+mSs8c3NaiYYNCC+IT5cI/8QuKlgh9s59bu+N3gG988jqMJeCYlKuUv/iw==", "dev": true, + "optional": true, + "peer": true, "dependencies": { - "dequal": "^2.0.3" + "@types/node": "^20.1.0" + }, + "engines": { + "node": ">=18.20.0" } }, - "node_modules/array-buffer-byte-length": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz", - "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==", + "node_modules/@wdio/repl/node_modules/@types/node": { + "version": "20.17.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.10.tgz", + "integrity": "sha512-/jrvh5h6NXhEauFFexRin69nA0uHJ5gwk4iDivp/DeoEua3uwCUto6PC86IpRITBOs4+6i2I56K5x5b6WYGXHA==", "dev": true, + "optional": true, + "peer": true, "dependencies": { - "call-bind": "^1.0.2", - "is-array-buffer": "^3.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array-equal": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.2.tgz", - "integrity": "sha512-gUHx76KtnhEgB3HOuFYiCm3FIdEs6ocM2asHvNTkfu/Y09qQVrrVVaOKENmS2KkSaGoxgXNqC+ZVtR/n0MOkSA==", - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "undici-types": "~6.19.2" } }, - "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==", - "dev": true + "node_modules/@wdio/repl/node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "dev": true, + "optional": true, + "peer": true }, - "node_modules/array-includes": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.7.tgz", - "integrity": "sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==", + "node_modules/@wdio/types": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/@wdio/types/-/types-9.2.2.tgz", + "integrity": "sha512-nHZ9Ne9iRQFJ1TOYKUn4Fza69IshTTzk6RYmSZ51ImGs9uMZu0+S0Jm9REdly+VLN3FzxG6g2QSe0/F3uNVPdw==", "dev": true, + "optional": true, + "peer": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "get-intrinsic": "^1.2.1", - "is-string": "^1.0.7" + "@types/node": "^20.1.0" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=18.20.0" } }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/array.prototype.findlastindex": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.3.tgz", - "integrity": "sha512-LzLoiOMAxvy+Gd3BAq3B7VeIgPdo+Q8hthvKtXybMvRV0jrXfJM/t8mw7nNlpEcVlVUnCnM2KSX4XU5HmpodOA==", + "node_modules/@wdio/types/node_modules/@types/node": { + "version": "20.17.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.10.tgz", + "integrity": "sha512-/jrvh5h6NXhEauFFexRin69nA0uHJ5gwk4iDivp/DeoEua3uwCUto6PC86IpRITBOs4+6i2I56K5x5b6WYGXHA==", "dev": true, + "optional": true, + "peer": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0", - "get-intrinsic": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "undici-types": "~6.19.2" } }, - "node_modules/array.prototype.flat": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", - "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", + "node_modules/@wdio/types/node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "optional": true, + "peer": true }, - "node_modules/array.prototype.flatmap": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", - "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", + "node_modules/@wdio/utils": { + "version": "9.2.8", + "resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-9.2.8.tgz", + "integrity": "sha512-rKm5FXkpsCyeqh8tdirtRUHvgNytWNMiaVKdctsvKOJvqnDVPAAQcz9Wmgo7bSwoLwtSHcDaRoxY7olV7J4QnA==", "dev": true, + "optional": true, + "peer": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" + "@puppeteer/browsers": "^2.2.0", + "@wdio/logger": "9.1.3", + "@wdio/types": "9.2.2", + "decamelize": "^6.0.0", + "deepmerge-ts": "^7.0.3", + "edgedriver": "^5.6.1", + "geckodriver": "^4.3.3", + "get-port": "^7.0.0", + "import-meta-resolve": "^4.0.0", + "locate-app": "^2.2.24", + "safaridriver": "^0.1.2", + "split2": "^4.2.0", + "wait-port": "^1.1.0" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=18.20.0" } }, - "node_modules/arraybuffer.prototype.slice": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz", - "integrity": "sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==", + "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, + "optional": true, + "peer": true, "dependencies": { - "array-buffer-byte-length": "^1.0.0", - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "get-intrinsic": "^1.2.1", - "is-array-buffer": "^3.0.2", - "is-shared-array-buffer": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "@webassemblyjs/helper-numbers": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2" } }, - "node_modules/asn1": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", - "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", - "dependencies": { - "safer-buffer": "~2.1.0" - } + "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, + "optional": true, + "peer": true }, - "node_modules/assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", - "engines": { - "node": ">=0.8" - } + "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, + "optional": true, + "peer": true }, - "node_modules/assertion-error": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", - "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "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, - "engines": { - "node": ">=12" - } + "optional": true, + "peer": true }, - "node_modules/ast-types": { - "version": "0.13.4", - "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", - "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", + "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, + "optional": true, + "peer": true, "dependencies": { - "tslib": "^2.0.1" - }, - "engines": { - "node": ">=4" + "@webassemblyjs/floating-point-hex-parser": "1.13.2", + "@webassemblyjs/helper-api-error": "1.13.2", + "@xtuc/long": "4.2.2" } }, - "node_modules/astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "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, - "engines": { - "node": ">=8" - } - }, - "node_modules/async": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", - "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==", - "dev": true - }, - "node_modules/async-limiter": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", - "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==" - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + "optional": true, + "peer": true }, - "node_modules/at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "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, - "engines": { - "node": ">= 4.0.0" + "optional": true, + "peer": 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/available-typed-arrays": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", + "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, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "optional": true, + "peer": true, + "dependencies": { + "@xtuc/ieee754": "^1.2.0" } }, - "node_modules/aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", - "engines": { - "node": "*" + "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, + "optional": true, + "peer": true, + "dependencies": { + "@xtuc/long": "4.2.2" } }, - "node_modules/aws4": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.12.0.tgz", - "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==" - }, - "node_modules/b4a": { - "version": "1.6.6", - "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.6.tgz", - "integrity": "sha512-5Tk1HLk6b6ctmjIkAcU/Ujv/1WqiDl0F0JdRCR80VsOcUlHcu7pWeWRlOqQLHfDEsVx9YH/aif5AG4ehoCtTmg==", - "dev": true - }, - "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==" + "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, + "optional": true, + "peer": true }, - "node_modules/bare-events": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.4.2.tgz", - "integrity": "sha512-qMKFd2qG/36aA4GwvKq8MxnPgCQAmBWmSyLWsJcbn8v03wvIPQ/hG1Ms8bPzndZxMDoHpxez5VOS+gC9Yi24/Q==", + "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, - "optional": true + "optional": true, + "peer": 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/bare-fs": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-2.3.1.tgz", - "integrity": "sha512-W/Hfxc/6VehXlsgFtbB5B4xFcsCl+pAh30cYhoFyXErf6oGrwjh8SwiPAdHgpmWonKuYpZgGywN0SXt7dgsADA==", + "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, "optional": true, + "peer": true, "dependencies": { - "bare-events": "^2.0.0", - "bare-path": "^2.0.0", - "bare-stream": "^2.0.0" + "@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/bare-os": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-2.4.0.tgz", - "integrity": "sha512-v8DTT08AS/G0F9xrhyLtepoo9EJBJ85FRSMbu1pQUlAf6A8T0tEEQGMVObWeqpjhSPXsE0VGlluFBJu2fdoTNg==", + "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, - "optional": true + "optional": true, + "peer": 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/bare-path": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-2.1.3.tgz", - "integrity": "sha512-lh/eITfU8hrj9Ru5quUp0Io1kJWIk1bTjzo7JH1P5dWmQ2EL4hFUlfI8FonAhSlgIfhn63p84CDY/x+PisgcXA==", + "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, "optional": true, + "peer": true, "dependencies": { - "bare-os": "^2.1.0" + "@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/bare-stream": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.1.3.tgz", - "integrity": "sha512-tiDAH9H/kP+tvNO5sczyn9ZAA7utrSMobyDchsnyyXBuUe2FSQWbxhtuHB8jwpHYYevVo2UJpcmvvjrbHboUUQ==", + "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, "optional": true, + "peer": true, "dependencies": { - "streamx": "^2.18.0" + "@webassemblyjs/ast": "1.14.1", + "@xtuc/long": "4.2.2" } }, - "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==", + "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, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] + "optional": true, + "peer": true }, - "node_modules/basic-ftp": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.5.tgz", - "integrity": "sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==", + "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, + "optional": true, + "peer": true + }, + "node_modules/@zip.js/zip.js": { + "version": "2.7.54", + "resolved": "https://registry.npmjs.org/@zip.js/zip.js/-/zip.js-2.7.54.tgz", + "integrity": "sha512-qMrJVg2hoEsZJjMJez9yI2+nZlBUxgYzGV3mqcb2B/6T1ihXp0fWBDYlVHlHquuorgNUQP5a8qSmX6HF5rFJNg==", + "dev": true, + "optional": true, + "peer": true, "engines": { - "node": ">=10.0.0" + "bun": ">=0.7.0", + "deno": ">=1.0.0", + "node": ">=16.5.0" } }, - "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==", + "node_modules/a-sync-waterfall": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/a-sync-waterfall/-/a-sync-waterfall-1.0.1.tgz", + "integrity": "sha512-RYTOHHdWipFUliRFMCS4X2Yn2X8M87V/OpSqWzKKOGhzqyUxzyVmhHDH9sAvG+ZuQf/TAOFsLCpMw09I1ufUnA==", "dev": true }, - "node_modules/bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", - "dependencies": { - "tweetnacl": "^0.14.3" - } + "node_modules/abab": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/abab/-/abab-1.0.4.tgz", + "integrity": "sha512-I+Wi+qiE2kUXyrRhNsWv6XsjUTBJjSoVSctKNBfLG5zG/Xe7Rjbxf13+vqYHNTwHaFU+FtSlVxOCTiMEVtPv0A==", + "deprecated": "Use your platform's native atob() and btoa() methods instead" }, - "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, + "node_modules/abbrev": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-2.0.0.tgz", + "integrity": "sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==", "engines": { - "node": "*" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "event-target-shim": "^5.0.0" + }, "engines": { - "node": ">=8" + "node": ">=6.5" } }, - "node_modules/bl": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-5.1.0.tgz", - "integrity": "sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==", + "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": { - "buffer": "^6.0.3", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" } }, - "node_modules/bl/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/acorn": { + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" + "bin": { + "acorn": "bin/acorn" }, "engines": { - "node": ">= 6" + "node": ">=0.4.0" } }, - "node_modules/body-parser": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", - "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", - "dev": true, + "node_modules/acorn-globals": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.4.tgz", + "integrity": "sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A==", "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.11.0", - "raw-body": "2.5.2", - "type-is": "~1.6.18", - "unpipe": "1.0.0" + "acorn": "^6.0.1", + "acorn-walk": "^6.0.1" + } + }, + "node_modules/acorn-globals/node_modules/acorn": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", + "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", + "bin": { + "acorn": "bin/acorn" }, "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" + "node": ">=0.4.0" } }, - "node_modules/body-parser/node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "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, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/acorn-walk": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.2.0.tgz", + "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==", "engines": { - "node": ">= 0.8" + "node": ">=0.4.0" } }, - "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==", + "node_modules/agent-base": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz", + "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==", "dev": true, - "dependencies": { - "ms": "2.0.0" + "engines": { + "node": ">= 14" } }, - "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/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } }, - "node_modules/body-parser/node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", "dev": true, "dependencies": { - "side-channel": "^1.0.4" + "ajv": "^8.0.0" }, - "engines": { - "node": ">=0.6" + "peerDependencies": { + "ajv": "^8.0.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "peerDependenciesMeta": { + "ajv": { + "optional": true + } } }, - "node_modules/bonjour-service": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.2.1.tgz", - "integrity": "sha512-oSzCS2zV14bh2kji6vNe7vrpJYCHGvcZnlffFQ1MEoX/WOeQ/teD8SYWKR942OI3INjq8OMNJlbPK5LLLUxFDw==", + "node_modules/ajv-formats/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", "dev": true, "dependencies": { - "fast-deep-equal": "^3.1.3", - "multicast-dns": "^7.2.5" + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/boolbase": { + "node_modules/ajv-formats/node_modules/json-schema-traverse": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true }, - "node_modules/boxen": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-7.1.1.tgz", - "integrity": "sha512-2hCgjEmP8YLWQ130n2FerGv7rYpfBmnmp9Uy2Le1vge6X3gZIfSmEzP5QTDElFxcvVcXlEn8Aq6MU/PZygIOog==", + "node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "optional": true, + "peer": true, + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "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": { - "ansi-align": "^3.0.1", - "camelcase": "^7.0.1", - "chalk": "^5.2.0", - "cli-boxes": "^3.0.0", - "string-width": "^5.1.2", - "type-fest": "^2.13.0", - "widest-line": "^4.0.1", - "wrap-ansi": "^8.1.0" + "type-fest": "^0.21.3" }, "engines": { - "node": ">=14.16" + "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/boxen/node_modules/chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", "dev": true, "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" + "node": ">=10" }, "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dependencies": { - "balanced-match": "^1.0.0" + "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/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" - }, + "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==", "engines": { "node": ">=8" } }, - "node_modules/brfs": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/brfs/-/brfs-1.6.1.tgz", - "integrity": "sha512-OfZpABRQQf+Xsmju8XE9bDjs+uU4vLREGolP7bDgcpsI17QREyZ4Bl+2KLxxx1kCgA0fAIhKQBaBYh+PEcCqYQ==", + "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==", "dependencies": { - "quote-stream": "^1.0.1", - "resolve": "^1.1.5", - "static-module": "^2.2.0", - "through2": "^2.0.0" + "color-convert": "^2.0.1" }, - "bin": { - "brfs": "bin/cmd.js" + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/brfs/node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "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": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" } }, - "node_modules/browser-process-hrtime": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", - "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==" - }, - "node_modules/browserslist": { - "version": "4.23.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", - "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", + "node_modules/archiver": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-7.0.1.tgz", + "integrity": "sha512-ZcbTaIqJOfCc03QwD468Unz/5Ir8ATtvAHsK+FdXbDIbGfihqh9mrvdcYunQzqn4HrvWWaFyaxJhGZagaJJpPQ==", "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" - } - ], + "optional": true, + "peer": true, "dependencies": { - "caniuse-lite": "^1.0.30001587", - "electron-to-chromium": "^1.4.668", - "node-releases": "^2.0.14", - "update-browserslist-db": "^1.0.13" - }, - "bin": { - "browserslist": "cli.js" + "archiver-utils": "^5.0.2", + "async": "^3.2.4", + "buffer-crc32": "^1.0.0", + "readable-stream": "^4.0.0", + "readdir-glob": "^1.1.2", + "tar-stream": "^3.0.0", + "zip-stream": "^6.0.1" }, "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + "node": ">= 14" } }, - "node_modules/buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "node_modules/archiver-utils": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-5.0.2.tgz", + "integrity": "sha512-wuLJMmIBQYCsGZgYLTy5FIB2pF6Lfb6cXMSF8Qywwk3t20zWnAi7zLcQFdKQmIB8wyZpY5ER38x08GbwtR2cLA==", "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" - } - ], + "optional": true, + "peer": true, "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, - "node_modules/buffer-crc32": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-1.0.0.tgz", - "integrity": "sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==", - "dev": true, + "glob": "^10.0.0", + "graceful-fs": "^4.2.0", + "is-stream": "^2.0.1", + "lazystream": "^1.0.0", + "lodash": "^4.17.15", + "normalize-path": "^3.0.0", + "readable-stream": "^4.0.0" + }, "engines": { - "node": ">=8.0.0" + "node": ">= 14" } }, - "node_modules/buffer-equal": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-0.0.1.tgz", - "integrity": "sha512-RgSV6InVQ9ODPdLWJ5UAqBqJBOg370Nz6ZQtRzpt6nUjc8v0St97uJ4PYC6NztqIScrAXafKM3mZPMygSe1ggA==", + "node_modules/archiver-utils/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, + "optional": true, + "peer": true, "engines": { - "node": ">=0.4.0" + "node": ">=0.8.x" } }, - "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==" - }, - "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==", + "node_modules/archiver-utils/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, + "optional": true, + "peer": true, "dependencies": { - "run-applescript": "^7.0.0" + "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" }, - "engines": { - "node": ">=18" + "bin": { + "glob": "dist/esm/bin.mjs" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", + "node_modules/archiver-utils/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==", "dev": true, - "engines": { - "node": ">= 0.8" + "optional": true, + "peer": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" } }, - "node_modules/cac": { - "version": "6.7.14", - "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", - "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "node_modules/archiver-utils/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, - "engines": { - "node": ">=8" - } + "optional": true, + "peer": true }, - "node_modules/cacheable-lookup": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz", - "integrity": "sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==", + "node_modules/archiver-utils/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==", "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, "engines": { - "node": ">=14.16" + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/cacheable-request": { - "version": "10.2.14", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-10.2.14.tgz", - "integrity": "sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==", + "node_modules/archiver-utils/node_modules/readable-stream": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", + "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", "dev": true, + "optional": true, + "peer": true, "dependencies": { - "@types/http-cache-semantics": "^4.0.2", - "get-stream": "^6.0.1", - "http-cache-semantics": "^4.1.1", - "keyv": "^4.5.3", - "mimic-response": "^4.0.0", - "normalize-url": "^8.0.0", - "responselike": "^3.0.0" + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" }, "engines": { - "node": ">=14.16" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, - "node_modules/cacheable-request/node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "node_modules/archiver-utils/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/archiver/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, + "optional": true, + "peer": true, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=0.8.x" } }, - "node_modules/call-bind": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", - "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", + "node_modules/archiver/node_modules/readable-stream": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", + "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", "dev": true, + "optional": true, + "peer": true, "dependencies": { - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.1", - "set-function-length": "^1.1.1" + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "node_modules/archiver/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "dev": true, - "engines": { - "node": ">=6" + "optional": true, + "peer": true, + "dependencies": { + "safe-buffer": "~5.2.0" } }, - "node_modules/camel-case": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", - "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", + "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.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", "dev": true, "dependencies": { - "pascal-case": "^3.1.2", - "tslib": "^2.0.3" + "dequal": "^2.0.3" } }, - "node_modules/camelcase": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-7.0.1.tgz", - "integrity": "sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==", + "node_modules/array-buffer-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", + "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "is-array-buffer": "^3.0.4" + }, "engines": { - "node": ">=14.16" + "node": ">= 0.4" }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-equal": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.2.tgz", + "integrity": "sha512-gUHx76KtnhEgB3HOuFYiCm3FIdEs6ocM2asHvNTkfu/Y09qQVrrVVaOKENmS2KkSaGoxgXNqC+ZVtR/n0MOkSA==", "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/caniuse-lite": { - "version": "1.0.30001596", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001596.tgz", - "integrity": "sha512-zpkZ+kEr6We7w63ORkoJ2pOfBwBkY/bJrG/UZ90qNb45Isblu8wzDgevEOrRL1r9dWayHjYiiyCMEXPn4DweGQ==", - "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/caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==" + "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==", + "dev": true }, - "node_modules/chai": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/chai/-/chai-5.1.1.tgz", - "integrity": "sha512-pT1ZgP8rPNqUgieVaEY+ryQr6Q4HXNg8Ei9UnLUrjN4IA7dvQC5JB+/kxVcPNDHyBcc/26CXPkbNzq3qwrOEKA==", + "node_modules/array-includes": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", + "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", "dev": true, "dependencies": { - "assertion-error": "^2.0.1", - "check-error": "^2.1.1", - "deep-eql": "^5.0.1", - "loupe": "^3.1.0", - "pathval": "^2.0.0" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", + "is-string": "^1.0.7" }, "engines": { - "node": ">=12" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "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/array.prototype.findlastindex": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", + "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" }, "engines": { - "node": ">=10" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/check-error": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", - "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==", - "dev": true, - "engines": { - "node": ">= 16" + "url": "https://github.com/sponsors/ljharb" } }, - "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/array.prototype.flat": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", + "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", "dev": true, "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" + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" }, "engines": { - "node": ">= 8.10.0" + "node": ">= 0.4" }, "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/chokidar/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/array.prototype.flatmap": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", + "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", "dev": true, "dependencies": { - "is-glob": "^4.0.1" + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" }, "engines": { - "node": ">= 6" - } - }, - "node_modules/chrome-trace-event": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", - "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", - "dev": true, - "engines": { - "node": ">=6.0" - } - }, - "node_modules/chromium-bidi": { - "version": "0.4.16", - "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.4.16.tgz", - "integrity": "sha512-7ZbXdWERxRxSwo3txsBjjmc/NLxqb1Bk30mRb0BMS4YIaiV6zvKZqL/UAH+DdqcDYayDWk2n/y8klkBDODrPvA==", - "dev": true, - "dependencies": { - "mitt": "3.0.0" + "node": ">= 0.4" }, - "peerDependencies": { - "devtools-protocol": "*" - } - }, - "node_modules/ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "engines": { - "node": ">=8" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/clean-css": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz", - "integrity": "sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==", + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", + "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", "dev": true, "dependencies": { - "source-map": "~0.6.0" + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.2.1", + "get-intrinsic": "^1.2.3", + "is-array-buffer": "^3.0.4", + "is-shared-array-buffer": "^1.0.2" }, "engines": { - "node": ">= 10.0" - } - }, - "node_modules/cli-boxes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz", - "integrity": "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==", - "dev": true, - "engines": { - "node": ">=10" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/cli-cursor": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", - "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", - "dev": true, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", + "dev": true + }, + "node_modules/asn1": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", "dependencies": { - "restore-cursor": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "safer-buffer": "~2.1.0" } }, - "node_modules/cli-spinners": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", - "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", - "dev": true, + "node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=0.8" } }, - "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==", + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", "dev": true, + "license": "MIT", "engines": { - "node": ">= 12" + "node": ">=12" } }, - "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==", + "node_modules/ast-types": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", + "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", "dev": true, + "optional": true, + "peer": true, "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" + "tslib": "^2.0.1" }, "engines": { - "node": ">=12" + "node": ">=4" } }, - "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/async": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", + "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==", "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==", - "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/async-limiter": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", + "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==" }, - "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/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", "dev": true, "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" + "possible-typed-array-names": "^1.0.0" }, "engines": { - "node": ">=10" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/clone-deep": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", - "dev": true, - "dependencies": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" - }, + "node_modules/aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", "engines": { - "node": ">=6" + "node": "*" } }, - "node_modules/clone-deep/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/aws4": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.13.2.tgz", + "integrity": "sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw==" + }, + "node_modules/b4a": { + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.6.tgz", + "integrity": "sha512-5Tk1HLk6b6ctmjIkAcU/Ujv/1WqiDl0F0JdRCR80VsOcUlHcu7pWeWRlOqQLHfDEsVx9YH/aif5AG4ehoCtTmg==", "dev": true, - "engines": { - "node": ">=0.10.0" - } + "optional": true, + "peer": true }, - "node_modules/codemirror": { - "version": "5.65.16", - "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.65.16.tgz", - "integrity": "sha512-br21LjYmSlVL0vFCPWPfhzUCT34FM/pAdK7rRIZwa0rrtrIdotvP4Oh4GUHsu2E3IrQMCfRkL/fN3ytMNxVQvg==" + "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==" }, - "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/bare-events": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.4.2.tgz", + "integrity": "sha512-qMKFd2qG/36aA4GwvKq8MxnPgCQAmBWmSyLWsJcbn8v03wvIPQ/hG1Ms8bPzndZxMDoHpxez5VOS+gC9Yi24/Q==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/bare-fs": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-2.3.5.tgz", + "integrity": "sha512-SlE9eTxifPDJrT6YgemQ1WGFleevzwY+XAP1Xqgl56HtcrisC2CHCZ2tq6dBpcH2TnNxwUEUGhweo+lrQtYuiw==", + "dev": true, + "optional": true, + "peer": true, "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" + "bare-events": "^2.0.0", + "bare-path": "^2.0.0", + "bare-stream": "^2.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==" - }, - "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/bare-os": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-2.4.4.tgz", + "integrity": "sha512-z3UiI2yi1mK0sXeRdc4O1Kk8aOa/e+FNWZcTiPB/dfTWyLypuE99LibgRaQki914Jq//yAWylcAt+mknKdixRQ==", + "dev": true, + "optional": true, + "peer": true }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "node_modules/bare-path": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-2.1.3.tgz", + "integrity": "sha512-lh/eITfU8hrj9Ru5quUp0Io1kJWIk1bTjzo7JH1P5dWmQ2EL4hFUlfI8FonAhSlgIfhn63p84CDY/x+PisgcXA==", + "dev": true, + "optional": true, + "peer": true, "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" + "bare-os": "^2.1.0" } }, - "node_modules/comlink": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/comlink/-/comlink-4.4.1.tgz", - "integrity": "sha512-+1dlx0aY5Jo1vHy/tSsIGpSkN4tS9rZSW8FIhG0JH/crs9wwweswIo/POr451r7bZww3hFbPAKnTpimzL/mm4Q==", - "dev": true - }, - "node_modules/commander": { - "version": "9.5.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", - "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", + "node_modules/bare-stream": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.5.2.tgz", + "integrity": "sha512-QK6bePvszntxgPKdVXciYzjlWv2Ry1mQuUqyUUzd27G7eLupl6d0K5AGJfnfyFAdgy5tRolHP/zbaUMslLceOg==", "dev": true, - "engines": { - "node": "^12.20.0 || >=14" + "optional": true, + "peer": true, + "dependencies": { + "streamx": "^2.21.0" } }, - "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==", - "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" + } + ], + "optional": true, + "peer": true }, - "node_modules/compress-commons": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-6.0.2.tgz", - "integrity": "sha512-6FqVXeETqWPoGcfzrXb37E50NP0LXT8kAMu5ooZayhWWdgEY4lBEEcbQNXtkuKQsGduxiIcI4gOTsxTmuq/bSg==", + "node_modules/basic-auth": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", + "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", "dev": true, "dependencies": { - "crc-32": "^1.2.0", - "crc32-stream": "^6.0.0", - "is-stream": "^2.0.1", - "normalize-path": "^3.0.0", - "readable-stream": "^4.0.0" + "safe-buffer": "5.1.2" }, "engines": { - "node": ">= 14" + "node": ">= 0.8" } }, - "node_modules/compress-commons/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, - "engines": { - "node": ">=0.8.x" - } + "node_modules/basic-auth/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/compress-commons/node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "node_modules/basic-ftp": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.5.tgz", + "integrity": "sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==", "dev": true, + "optional": true, + "peer": true, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=10.0.0" } }, - "node_modules/compress-commons/node_modules/readable-stream": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", - "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", - "dev": true, + "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/bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", "dependencies": { - "abort-controller": "^3.0.0", - "buffer": "^6.0.3", - "events": "^3.3.0", - "process": "^0.11.10", - "string_decoder": "^1.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "tweetnacl": "^0.14.3" } }, - "node_modules/compress-commons/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/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true, - "dependencies": { - "safe-buffer": "~5.2.0" + "engines": { + "node": ">=8" } }, - "node_modules/compressible": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", - "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "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==", "dev": true, "dependencies": { - "mime-db": ">= 1.43.0 < 2" + "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.6" + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" } }, - "node_modules/compression": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", - "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", + "node_modules/body-parser/node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", "dev": true, - "dependencies": { - "accepts": "~1.3.5", - "bytes": "3.0.0", - "compressible": "~2.0.16", - "debug": "2.6.9", - "on-headers": "~1.0.2", - "safe-buffer": "5.1.2", - "vary": "~1.1.2" - }, "engines": { - "node": ">= 0.8.0" + "node": ">= 0.8" } }, - "node_modules/compression/node_modules/debug": { + "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==", @@ -4155,1191 +4678,1213 @@ "ms": "2.0.0" } }, - "node_modules/compression/node_modules/ms": { + "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/compression/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/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/concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "engines": [ - "node >= 0.8" - ], - "dependencies": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "node_modules/condense-newlines": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/condense-newlines/-/condense-newlines-0.2.1.tgz", - "integrity": "sha512-P7X+QL9Hb9B/c8HI5BFFKmjgBu2XpQuF98WZ9XkO+dBGgk5XgwiQz7o1SmpglNWId3581UcS0SFAWfoIhMHPfg==", + "node_modules/body-parser/node_modules/qs": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "dev": true, "dependencies": { - "extend-shallow": "^2.0.1", - "is-whitespace": "^0.3.0", - "kind-of": "^3.0.2" + "side-channel": "^1.0.6" }, "engines": { - "node": ">=0.10.0" + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/config-chain": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", - "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", + "node_modules/bonjour-service": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.2.1.tgz", + "integrity": "sha512-oSzCS2zV14bh2kji6vNe7vrpJYCHGvcZnlffFQ1MEoX/WOeQ/teD8SYWKR942OI3INjq8OMNJlbPK5LLLUxFDw==", + "dev": true, "dependencies": { - "ini": "^1.3.4", - "proto-list": "~1.2.1" + "fast-deep-equal": "^3.1.3", + "multicast-dns": "^7.2.5" } }, - "node_modules/config-chain/node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" - }, - "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==", + "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, - "engines": { - "node": ">=0.8" + "optional": true, + "peer": true + }, + "node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dependencies": { + "balanced-match": "^1.0.0" } }, - "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==", + "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": { - "safe-buffer": "5.2.1" + "fill-range": "^7.1.1" }, "engines": { - "node": ">= 0.6" + "node": ">=8" } }, - "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/browser-process-hrtime": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", + "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==" + }, + "node_modules/browserslist": { + "version": "4.24.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz", + "integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==", "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", + "optional": true, + "peer": true, + "dependencies": { + "caniuse-lite": "^1.0.30001688", + "electron-to-chromium": "^1.5.73", + "node-releases": "^2.0.19", + "update-browserslist-db": "^1.1.1" + }, + "bin": { + "browserslist": "cli.js" + }, "engines": { - "node": ">= 0.6" + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "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==" + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "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" + } + ], + "optional": true, + "peer": true, + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } }, - "node_modules/cookie": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "node_modules/buffer-crc32": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-1.0.0.tgz", + "integrity": "sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==", "dev": true, + "optional": true, + "peer": true, "engines": { - "node": ">= 0.6" + "node": ">=8.0.0" } }, - "node_modules/cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", - "dev": true - }, - "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==" + "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, + "optional": true, + "peer": true }, - "node_modules/cosmiconfig": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", - "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", + "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": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.1.0", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.7.2" + "run-applescript": "^7.0.0" }, "engines": { - "node": ">=8" - } - }, - "node_modules/crc-32": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", - "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", - "dev": true, - "bin": { - "crc32": "bin/crc32.njs" + "node": ">=18" }, - "engines": { - "node": ">=0.8" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/crc32-stream": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-6.0.0.tgz", - "integrity": "sha512-piICUB6ei4IlTv1+653yq5+KoqfBYmj9bw6LqXoOneTMDXk5nM1qt12mFW1caG3LlJXEKW1Bp0WggEmIfQB34g==", + "node_modules/busboy": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-0.3.1.tgz", + "integrity": "sha512-y7tTxhGKXcyBxRKAni+awqx8uqaJKrSFSNFSeRG5CsWNdmy2BIK+6VGWEW7TZnIO/533mtMEA4rOevQV815YJw==", "dev": true, "dependencies": { - "crc-32": "^1.2.0", - "readable-stream": "^4.0.0" + "dicer": "0.3.0" }, "engines": { - "node": ">= 14" + "node": ">=4.5.0" } }, - "node_modules/crc32-stream/node_modules/events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "node_modules/bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", "dev": true, "engines": { - "node": ">=0.8.x" + "node": ">= 0.8" } }, - "node_modules/crc32-stream/node_modules/readable-stream": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", - "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", "dev": true, - "dependencies": { - "abort-controller": "^3.0.0", - "buffer": "^6.0.3", - "events": "^3.3.0", - "process": "^0.11.10", - "string_decoder": "^1.3.0" - }, + "license": "MIT", "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/crc32-stream/node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.2.0" + "node": ">=8" } }, - "node_modules/cross-fetch": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.0.0.tgz", - "integrity": "sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==", + "node_modules/cache-content-type": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-content-type/-/cache-content-type-1.0.1.tgz", + "integrity": "sha512-IKufZ1o4Ut42YUrZSo8+qnMTrFuKkvyoLXUywKz9GJ5BrhOFGhLdkx9sG4KAnVvbY6kEcSFjLQul+DVmBm2bgA==", "dev": true, "dependencies": { - "node-fetch": "^2.6.12" + "mime-types": "^2.1.18", + "ylru": "^1.2.0" + }, + "engines": { + "node": ">= 6.0.0" } }, - "node_modules/cross-fetch/node_modules/node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "node_modules/call-bind": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", "dev": true, "dependencies": { - "whatwg-url": "^5.0.0" + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" }, "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" + "node": ">= 0.4" }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/cross-fetch/node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "dev": true - }, - "node_modules/cross-fetch/node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "dev": true - }, - "node_modules/cross-fetch/node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "node_modules/call-bind-apply-helpers": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.1.tgz", + "integrity": "sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==", "dev": true, "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" }, "engines": { - "node": ">= 8" + "node": ">= 0.4" } }, - "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/call-bound": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.2.tgz", + "integrity": "sha512-0lk0PHFe/uz0vl527fG9CgdE9WdafjDbCXvBbs+LUv000TVt2Jjhqbs4Jwm8gz070w8xXyEAxrPOMullsxXeGg==", "dev": true, "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" + "call-bind": "^1.0.8", + "get-intrinsic": "^1.2.5" }, "engines": { - "node": ">= 18.12.0" + "node": ">= 0.4" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "@rspack/core": "0.x || 1.x", - "webpack": "^5.27.0" - }, - "peerDependenciesMeta": { - "@rspack/core": { - "optional": true - }, - "webpack": { - "optional": true - } + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/css-select": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", - "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", - "dev": true, - "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^6.0.1", - "domhandler": "^4.3.1", - "domutils": "^2.8.0", - "nth-check": "^2.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/css-shorthand-properties": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/css-shorthand-properties/-/css-shorthand-properties-1.1.1.tgz", - "integrity": "sha512-Md+Juc7M3uOdbAFwOYlTrccIZ7oCFuzrhKYQjdeUEW/sE1hv17Jp/Bws+ReOPpGVBTYCBoYo+G17V5Qo8QQ75A==", - "dev": true - }, - "node_modules/css-value": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/css-value/-/css-value-0.0.1.tgz", - "integrity": "sha512-FUV3xaJ63buRLgHrLQVlVgQnQdR4yqdLGaDu7g8CQcWjInDfM9plBTPI9FRfpahju1UBSaMckeb2/46ApS/V1Q==", - "dev": true - }, - "node_modules/css-what": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", - "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", + "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" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" + "node": ">=6" } }, - "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/caniuse-lite": { + "version": "1.0.30001695", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001695.tgz", + "integrity": "sha512-vHyLade6wTgI2u1ec3WQBxv+2BrTERV28UXQu9LO6lZ9pYeMk34vjXFLOxo1A4UBA8XTL4njRQZdno/yYaSmWw==", "dev": true, - "bin": { - "cssesc": "bin/cssesc" - }, - "engines": { - "node": ">=4" - } + "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/cssom": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", - "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==" + "node_modules/caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==" }, - "node_modules/cssstyle": { - "version": "0.2.37", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-0.2.37.tgz", - "integrity": "sha512-FUpKc+1FNBsHUr9IsfSGCovr8VuGOiiuzlgCyppKBjJi2jYTOFLN3oiiNRMIvYqbFzF38mqKj4BgcevzU5/kIA==", + "node_modules/chai": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.1.2.tgz", + "integrity": "sha512-aGtmf24DW6MLHHG5gCx4zaI3uBq3KRtxeVs0DjFH6Z0rDNbsvTxFASFvdj79pxjxZ8/5u3PIiN3IwEIQkiiuPw==", + "dev": true, + "license": "MIT", "dependencies": { - "cssom": "0.3.x" + "assertion-error": "^2.0.1", + "check-error": "^2.1.1", + "deep-eql": "^5.0.1", + "loupe": "^3.1.0", + "pathval": "^2.0.0" + }, + "engines": { + "node": ">=12" } }, - "node_modules/dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", + "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, "dependencies": { - "assert-plus": "^1.0.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">=0.10" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/data-uri-to-buffer": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", - "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", + "node_modules/check-error": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", + "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==", "dev": true, + "license": "MIT", "engines": { - "node": ">= 12" - } - }, - "node_modules/data-urls": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.1.0.tgz", - "integrity": "sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==", - "dependencies": { - "abab": "^2.0.0", - "whatwg-mimetype": "^2.2.0", - "whatwg-url": "^7.0.0" - } - }, - "node_modules/data-urls/node_modules/abab": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", - "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", - "deprecated": "Use your platform's native atob() and btoa() methods instead" - }, - "node_modules/data-urls/node_modules/whatwg-url": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", - "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", - "dependencies": { - "lodash.sortby": "^4.7.0", - "tr46": "^1.0.1", - "webidl-conversions": "^4.0.2" + "node": ">= 16" } }, - "node_modules/debounce": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz", - "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==", - "dev": true - }, - "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "node_modules/cheerio": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0.tgz", + "integrity": "sha512-quS9HgjQpdaXOvsZz82Oz7uxtXiy6UIsIQcpBj7HRw2M63Skasm9qlDocAM7jNuaxdhpPU7c4kJN+gA5MCu4ww==", "dev": true, + "optional": true, + "peer": true, "dependencies": { - "ms": "2.1.2" + "cheerio-select": "^2.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "domutils": "^3.1.0", + "encoding-sniffer": "^0.2.0", + "htmlparser2": "^9.1.0", + "parse5": "^7.1.2", + "parse5-htmlparser2-tree-adapter": "^7.0.0", + "parse5-parser-stream": "^7.1.2", + "undici": "^6.19.5", + "whatwg-mimetype": "^4.0.0" }, "engines": { - "node": ">=6.0" + "node": ">=18.17" }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "funding": { + "url": "https://github.com/cheeriojs/cheerio?sponsor=1" } }, - "node_modules/decamelize": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-6.0.0.tgz", - "integrity": "sha512-Fv96DCsdOgB6mdGl67MT5JaTNKRzrzill5OH5s8bjYJXVlcXyPYGyPsUkWyGV5p1TXI5esYIYMMeDJL0hEIwaA==", + "node_modules/cheerio-select": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", + "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", "dev": true, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "optional": true, + "peer": true, + "dependencies": { + "boolbase": "^1.0.0", + "css-select": "^5.1.0", + "css-what": "^6.1.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/fb55" } }, - "node_modules/decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "node_modules/cheerio-select/node_modules/css-select": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", + "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", "dev": true, + "optional": true, + "peer": true, "dependencies": { - "mimic-response": "^3.1.0" - }, - "engines": { - "node": ">=10" + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/fb55" } }, - "node_modules/decompress-response/node_modules/mimic-response": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "node_modules/cheerio-select/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, - "engines": { - "node": ">=10" + "optional": true, + "peer": true, + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" } }, - "node_modules/deep-eql": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", - "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", + "node_modules/cheerio-select/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, + "optional": true, + "peer": true, + "dependencies": { + "domelementtype": "^2.3.0" + }, "engines": { - "node": ">=6" + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" } }, - "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==" - }, - "node_modules/deepmerge": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", - "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "node_modules/cheerio-select/node_modules/domutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", + "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", "dev": true, - "engines": { - "node": ">=0.10.0" + "optional": true, + "peer": true, + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" } }, - "node_modules/deepmerge-ts": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/deepmerge-ts/-/deepmerge-ts-5.1.0.tgz", - "integrity": "sha512-eS8dRJOckyo9maw9Tu5O5RUi/4inFLrnoLkBe3cPfDMx3WZioXtmOew4TXQaxq7Rhl4xjDtR7c6x8nNTxOvbFw==", + "node_modules/cheerio/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, - "engines": { - "node": ">=16.0.0" + "optional": true, + "peer": true, + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" } }, - "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/cheerio/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, + "optional": true, + "peer": true, "dependencies": { - "bundle-name": "^4.1.0", - "default-browser-id": "^5.0.0" + "domelementtype": "^2.3.0" }, "engines": { - "node": ">=18" + "node": ">= 4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/fb55/domhandler?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/cheerio/node_modules/domutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", + "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", "dev": true, - "engines": { - "node": ">=18" + "optional": true, + "peer": true, + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/fb55/domutils?sponsor=1" } }, - "node_modules/default-gateway": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", - "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", + "node_modules/cheerio/node_modules/htmlparser2": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.1.0.tgz", + "integrity": "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==", "dev": true, + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "optional": true, + "peer": true, "dependencies": { - "execa": "^5.0.0" - }, - "engines": { - "node": ">= 10" + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.1.0", + "entities": "^4.5.0" } }, - "node_modules/default-gateway/node_modules/execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "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": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" + "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": ">=10" + "node": ">= 8.10.0" }, "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" } }, - "node_modules/default-gateway/node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "node_modules/chokidar/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, - "engines": { - "node": ">=10" + "dependencies": { + "is-glob": "^4.0.1" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">= 6" } }, - "node_modules/default-gateway/node_modules/human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "node_modules/chrome-trace-event": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", + "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", "dev": true, + "optional": true, + "peer": true, "engines": { - "node": ">=10.17.0" + "node": ">=6.0" } }, - "node_modules/default-gateway/node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/default-gateway/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/default-gateway/node_modules/strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "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": ">=6" + "node": ">= 12" } }, - "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/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": { - "clone": "^1.0.2" + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/defaults/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": ">=12" } }, - "node_modules/defer-to-connect": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", - "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", - "dev": true, - "engines": { - "node": ">=10" - } + "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==", + "dev": true }, - "node_modules/define-data-property": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", - "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", + "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==", "dev": true, "dependencies": { - "get-intrinsic": "^1.2.1", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" }, "engines": { - "node": ">= 0.4" + "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/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==", "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, "engines": { - "node": ">=12" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/define-properties": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", - "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "node_modules/clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", "dev": true, "dependencies": { - "define-data-property": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=6" } }, - "node_modules/degenerator": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", - "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", + "node_modules/clone-deep/node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", "dev": true, - "dependencies": { - "ast-types": "^0.13.4", - "escodegen": "^2.1.0", - "esprima": "^4.0.1" - }, "engines": { - "node": ">= 14" + "node": ">=0.10.0" } }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "dev": true, "engines": { - "node": ">=0.4.0" + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" } }, - "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==", + "node_modules/codemirror": { + "version": "5.65.16", + "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.65.16.tgz", + "integrity": "sha512-br21LjYmSlVL0vFCPWPfhzUCT34FM/pAdK7rRIZwa0rrtrIdotvP4Oh4GUHsu2E3IrQMCfRkL/fN3ytMNxVQvg==" + }, + "node_modules/color": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", + "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", "dev": true, + "dependencies": { + "color-convert": "^1.9.3", + "color-string": "^1.6.0" + } + }, + "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==", + "dependencies": { + "color-name": "~1.1.4" + }, "engines": { - "node": ">= 0.8" + "node": ">=7.0.0" } }, - "node_modules/dequal": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", - "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "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/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", "dev": true, - "engines": { - "node": ">=6" + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" } }, - "node_modules/destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "node_modules/color/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" + "dependencies": { + "color-name": "1.1.3" } }, - "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==", + "node_modules/color/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "dev": true }, - "node_modules/devtools-protocol": { - "version": "0.0.1302984", - "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1302984.tgz", - "integrity": "sha512-Rgh2Sk5fUSCtEx4QGH9iwTyECdFPySG2nlz5J8guGh2Wlha6uzSOCq/DCEC8faHlLaMPZJMuZ4ovgcX4LvOkKA==", + "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/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "node_modules/colorspace": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.4.tgz", + "integrity": "sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==", "dev": true, "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" + "color": "^3.1.3", + "text-hex": "1.0.x" } }, - "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==", - "dev": true, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "dependencies": { - "@leichtgewicht/ip-codec": "^2.0.1" + "delayed-stream": "~1.0.0" }, "engines": { - "node": ">=6" + "node": ">= 0.8" } }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, + "node_modules/commander": { + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", + "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", + "dev": true, + "optional": true, + "peer": true, "engines": { - "node": ">=6.0.0" + "node": "^12.20.0 || >=14" } }, - "node_modules/dom-accessibility-api": { - "version": "0.5.16", - "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", - "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", - "dev": true - }, - "node_modules/dom-converter": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", - "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", + "node_modules/compress-commons": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-6.0.2.tgz", + "integrity": "sha512-6FqVXeETqWPoGcfzrXb37E50NP0LXT8kAMu5ooZayhWWdgEY4lBEEcbQNXtkuKQsGduxiIcI4gOTsxTmuq/bSg==", "dev": true, + "optional": true, + "peer": true, "dependencies": { - "utila": "~0.4" + "crc-32": "^1.2.0", + "crc32-stream": "^6.0.0", + "is-stream": "^2.0.1", + "normalize-path": "^3.0.0", + "readable-stream": "^4.0.0" + }, + "engines": { + "node": ">= 14" } }, - "node_modules/dom-serializer": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", - "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "node_modules/compress-commons/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, + "optional": true, + "peer": true, + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/compress-commons/node_modules/readable-stream": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", + "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", "dev": true, + "optional": true, + "peer": true, "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.0", - "entities": "^2.0.0" + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" }, - "funding": { - "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.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/compress-commons/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ] - }, - "node_modules/domexception": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz", - "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==", - "deprecated": "Use your platform's native DOMException instead", + "optional": true, + "peer": true, "dependencies": { - "webidl-conversions": "^4.0.2" + "safe-buffer": "~5.2.0" } }, - "node_modules/domhandler": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", - "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "node_modules/compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", "dev": true, "dependencies": { - "domelementtype": "^2.2.0" + "mime-db": ">= 1.43.0 < 2" }, "engines": { - "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" + "node": ">= 0.6" } }, - "node_modules/domutils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", - "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "node_modules/compression": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", + "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", "dev": true, "dependencies": { - "dom-serializer": "^1.0.1", - "domelementtype": "^2.2.0", - "domhandler": "^4.2.0" + "accepts": "~1.3.5", + "bytes": "3.0.0", + "compressible": "~2.0.16", + "debug": "2.6.9", + "on-headers": "~1.0.2", + "safe-buffer": "5.1.2", + "vary": "~1.1.2" }, - "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" + "engines": { + "node": ">= 0.8.0" } }, - "node_modules/dot-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", - "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", + "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==", "dev": true, "dependencies": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" + "ms": "2.0.0" } }, - "node_modules/duplexer": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", - "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", + "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==", "dev": true }, - "node_modules/duplexer2": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", - "integrity": "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==", - "dependencies": { - "readable-stream": "^2.0.2" - } - }, - "node_modules/eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" + "node_modules/compression/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/ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", - "dependencies": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true }, - "node_modules/edge-paths": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/edge-paths/-/edge-paths-3.0.5.tgz", - "integrity": "sha512-sB7vSrDnFa4ezWQk9nZ/n0FdpdUuC6R1EOrlU3DL+bovcNFK28rqu2emmAUjujYEJTWIgQGqgVVWUZXMnc8iWg==", - "dev": true, + "node_modules/condense-newlines": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/condense-newlines/-/condense-newlines-0.2.1.tgz", + "integrity": "sha512-P7X+QL9Hb9B/c8HI5BFFKmjgBu2XpQuF98WZ9XkO+dBGgk5XgwiQz7o1SmpglNWId3581UcS0SFAWfoIhMHPfg==", "dependencies": { - "@types/which": "^2.0.1", - "which": "^2.0.2" + "extend-shallow": "^2.0.1", + "is-whitespace": "^0.3.0", + "kind-of": "^3.0.2" }, "engines": { - "node": ">=14.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/shirshak55" + "node": ">=0.10.0" } }, - "node_modules/edgedriver": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/edgedriver/-/edgedriver-5.6.0.tgz", - "integrity": "sha512-IeJXEczG+DNYBIa9gFgVYTqrawlxmc9SUqUsWU2E98jOsO/amA7wzabKOS8Bwgr/3xWoyXCJ6yGFrbFKrilyyQ==", - "dev": true, - "hasInstallScript": true, + "node_modules/config-chain": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", + "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", "dependencies": { - "@wdio/logger": "^8.28.0", - "@zip.js/zip.js": "^2.7.44", - "decamelize": "^6.0.0", - "edge-paths": "^3.0.5", - "node-fetch": "^3.3.2", - "which": "^4.0.0" - }, - "bin": { - "edgedriver": "bin/edgedriver.js" + "ini": "^1.3.4", + "proto-list": "~1.2.1" } }, - "node_modules/edgedriver/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/config-chain/node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + }, + "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": ">=16" + "node": ">=0.8" } }, - "node_modules/edgedriver/node_modules/which": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", - "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", + "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==", "dev": true, "dependencies": { - "isexe": "^3.1.1" - }, - "bin": { - "node-which": "bin/which.js" + "safe-buffer": "5.2.1" }, "engines": { - "node": "^16.13.0 || >=18.0.0" + "node": ">= 0.6" } }, - "node_modules/editorconfig": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-1.0.4.tgz", - "integrity": "sha512-L9Qe08KWTlqYMVvMcTIvMAdl1cDUubzRNYL+WfA4bLDMHe4nemKkpmYzkznE1FwLKu0EEmy6obgQKzMJrg4x9Q==", - "dependencies": { - "@one-ini/wasm": "0.1.1", - "commander": "^10.0.0", - "minimatch": "9.0.1", - "semver": "^7.5.3" - }, - "bin": { - "editorconfig": "bin/editorconfig" - }, + "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, "engines": { - "node": ">=14" + "node": ">= 0.6" } }, - "node_modules/editorconfig/node_modules/commander": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", - "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "node_modules/cookie": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz", + "integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==", + "dev": true, + "license": "MIT", "engines": { - "node": ">=14" + "node": ">=18" } }, - "node_modules/editorconfig/node_modules/minimatch": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.1.tgz", - "integrity": "sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==", + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "dev": true + }, + "node_modules/cookies": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/cookies/-/cookies-0.9.1.tgz", + "integrity": "sha512-TG2hpqe4ELx54QER/S3HQ9SRVnQnGBtKUz5bLQWtYAQ+o6GpgMs6sYUvaiJjVxb+UXwhRhAEP3m7LbsIZ77Hmw==", + "dev": true, "dependencies": { - "brace-expansion": "^2.0.1" + "depd": "~2.0.0", + "keygrip": "~1.1.0" }, "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": ">= 0.8" } }, - "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/core-js": { + "version": "3.40.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.40.0.tgz", + "integrity": "sha512-7vsMc/Lty6AGnn7uFpYT56QesI5D2Y/UkgKounk87OP9Z2H9Z8kj6jzcSGAxFmUtDOS0ntK6lbQz+Nsa0Jj6mQ==", + "hasInstallScript": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } }, - "node_modules/electron-to-chromium": { - "version": "1.4.699", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.699.tgz", - "integrity": "sha512-I7q3BbQi6e4tJJN5CRcyvxhK0iJb34TV8eJQcgh+fR2fQ8miMgZcEInckCo1U9exDHbfz7DLDnFn8oqH/VcRKw==", + "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/element-size": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/element-size/-/element-size-1.1.1.tgz", - "integrity": "sha512-eaN+GMOq/Q+BIWy0ybsgpcYImjGIdNLyjLFJU4XsLHXYQao5jCNb36GyN6C2qwmDDYSfIBmKpPpr4VnBdLCsPQ==" + "node_modules/corser": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/corser/-/corser-2.0.1.tgz", + "integrity": "sha512-utCYNzRSQIZNPIcGZdQc92UVJYAhtGAteCFg0yRaFm8f0P+CPtyGyHXJcGXnffjCybUCEx3FQ2G7U3/o9eIkVQ==", + "dev": true, + "engines": { + "node": ">= 0.4.0" + } }, - "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==" + "node_modules/crc-32": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", + "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", + "license": "Apache-2.0", + "bin": { + "crc32": "bin/crc32.njs" + }, + "engines": { + "node": ">=0.8" + } }, - "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/crc32-stream": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-6.0.0.tgz", + "integrity": "sha512-piICUB6ei4IlTv1+653yq5+KoqfBYmj9bw6LqXoOneTMDXk5nM1qt12mFW1caG3LlJXEKW1Bp0WggEmIfQB34g==", "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "crc-32": "^1.2.0", + "readable-stream": "^4.0.0" + }, "engines": { - "node": ">= 4" + "node": ">= 14" } }, - "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==", + "node_modules/crc32-stream/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, + "optional": true, + "peer": true, "engines": { - "node": ">= 0.8" + "node": ">=0.8.x" } }, - "node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "node_modules/crc32-stream/node_modules/readable-stream": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", + "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", "dev": true, + "optional": true, + "peer": true, "dependencies": { - "once": "^1.4.0" + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, - "node_modules/enhanced-resolve": { - "version": "5.17.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", - "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", + "node_modules/crc32-stream/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "dev": true, + "optional": true, + "peer": true, "dependencies": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" + "safe-buffer": "~5.2.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==", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" }, "engines": { - "node": ">=10.13.0" + "node": ">= 8" } }, - "node_modules/enquirer": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", - "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", + "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==", "dev": true, "dependencies": { - "ansi-colors": "^4.1.1", - "strip-ansi": "^6.0.1" + "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" }, "engines": { - "node": ">=8.6" + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "webpack": "^5.27.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } } }, - "node_modules/entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "node_modules/css-shorthand-properties": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/css-shorthand-properties/-/css-shorthand-properties-1.1.1.tgz", + "integrity": "sha512-Md+Juc7M3uOdbAFwOYlTrccIZ7oCFuzrhKYQjdeUEW/sE1hv17Jp/Bws+ReOPpGVBTYCBoYo+G17V5Qo8QQ75A==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/css-value": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/css-value/-/css-value-0.0.1.tgz", + "integrity": "sha512-FUV3xaJ63buRLgHrLQVlVgQnQdR4yqdLGaDu7g8CQcWjInDfM9plBTPI9FRfpahju1UBSaMckeb2/46ApS/V1Q==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/css-what": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">= 6" + }, "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" + "url": "https://github.com/sponsors/fb55" } }, - "node_modules/envinfo": { - "version": "7.11.1", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.11.1.tgz", - "integrity": "sha512-8PiZgZNIB4q/Lw4AhOvAfB/ityHAd2bli3lESSWmWSzSsl5dKpy5N1d1Rfkd2teq/g9xN90lc6o98DOjMeYHpg==", + "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==", "dev": true, "bin": { - "envinfo": "dist/cli.js" + "cssesc": "bin/cssesc" }, "engines": { "node": ">=4" } }, - "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==", + "node_modules/cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==" + }, + "node_modules/cssstyle": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.2.1.tgz", + "integrity": "sha512-9+vem03dMXG7gDmZ62uqmRiMRNtinIZ9ZyuF6BdxzfOD+FdN5hretzynkn0ReS2DO2GSw76RWHs0UmJPI2zUjw==", "dev": true, + "license": "MIT", "dependencies": { - "is-arrayish": "^0.2.1" + "@asamuzakjp/css-color": "^2.8.2", + "rrweb-cssom": "^0.8.0" + }, + "engines": { + "node": ">=18" } }, - "node_modules/es-abstract": { - "version": "1.22.3", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.3.tgz", - "integrity": "sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA==", - "dev": true, + "node_modules/dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", "dependencies": { - "array-buffer-byte-length": "^1.0.0", - "arraybuffer.prototype.slice": "^1.0.2", - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.5", - "es-set-tostringtag": "^2.0.1", - "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.6", - "get-intrinsic": "^1.2.2", - "get-symbol-description": "^1.0.0", - "globalthis": "^1.0.3", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0", - "internal-slot": "^1.0.5", - "is-array-buffer": "^3.0.2", - "is-callable": "^1.2.7", - "is-negative-zero": "^2.0.2", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", - "is-string": "^1.0.7", - "is-typed-array": "^1.1.12", - "is-weakref": "^1.0.2", - "object-inspect": "^1.13.1", - "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.5.1", - "safe-array-concat": "^1.0.1", - "safe-regex-test": "^1.0.0", - "string.prototype.trim": "^1.2.8", - "string.prototype.trimend": "^1.0.7", - "string.prototype.trimstart": "^1.0.7", - "typed-array-buffer": "^1.0.0", - "typed-array-byte-length": "^1.0.0", - "typed-array-byte-offset": "^1.0.0", - "typed-array-length": "^1.0.4", - "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.13" + "assert-plus": "^1.0.0" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=0.10" } }, - "node_modules/es-module-lexer": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.4.1.tgz", - "integrity": "sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==", - "dev": true - }, - "node_modules/es-set-tostringtag": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.2.tgz", - "integrity": "sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q==", + "node_modules/data-uri-to-buffer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", + "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", "dev": true, - "dependencies": { - "get-intrinsic": "^1.2.2", - "has-tostringtag": "^1.0.0", - "hasown": "^2.0.0" - }, + "optional": true, + "peer": true, "engines": { - "node": ">= 0.4" + "node": ">= 12" } }, - "node_modules/es-shim-unscopables": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", - "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", + "node_modules/data-urls": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz", + "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==", "dev": true, "dependencies": { - "hasown": "^2.0.0" + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.0.0" + }, + "engines": { + "node": ">=18" } }, - "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "node_modules/data-view-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", + "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", "dev": true, "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" }, "engines": { "node": ">= 0.4" @@ -5348,1464 +5893,1520 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/esbuild": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.23.0.tgz", - "integrity": "sha512-1lvV17H2bMYda/WaFb2jLPeHU3zml2k4/yagNMG8Q/YtfMjCwEUZa2eXXMgZTVSL5q1n4H7sQ0X6CdJDqqeCFA==", + "node_modules/data-view-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", + "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", "dev": true, - "hasInstallScript": true, - "bin": { - "esbuild": "bin/esbuild" + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" }, "engines": { - "node": ">=18" + "node": ">= 0.4" }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.23.0", - "@esbuild/android-arm": "0.23.0", - "@esbuild/android-arm64": "0.23.0", - "@esbuild/android-x64": "0.23.0", - "@esbuild/darwin-arm64": "0.23.0", - "@esbuild/darwin-x64": "0.23.0", - "@esbuild/freebsd-arm64": "0.23.0", - "@esbuild/freebsd-x64": "0.23.0", - "@esbuild/linux-arm": "0.23.0", - "@esbuild/linux-arm64": "0.23.0", - "@esbuild/linux-ia32": "0.23.0", - "@esbuild/linux-loong64": "0.23.0", - "@esbuild/linux-mips64el": "0.23.0", - "@esbuild/linux-ppc64": "0.23.0", - "@esbuild/linux-riscv64": "0.23.0", - "@esbuild/linux-s390x": "0.23.0", - "@esbuild/linux-x64": "0.23.0", - "@esbuild/netbsd-x64": "0.23.0", - "@esbuild/openbsd-arm64": "0.23.0", - "@esbuild/openbsd-x64": "0.23.0", - "@esbuild/sunos-x64": "0.23.0", - "@esbuild/win32-arm64": "0.23.0", - "@esbuild/win32-ia32": "0.23.0", - "@esbuild/win32-x64": "0.23.0" - } - }, - "node_modules/esbuild-loader": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/esbuild-loader/-/esbuild-loader-4.2.2.tgz", - "integrity": "sha512-Mdq/A1L8p37hkibp8jGFwuQTDSWhDmlueAefsrCPRwNWThEOlQmIglV7Gd6GE2mO5bt7ksfxKOMwkuY7jjVTXg==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", + "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", "dev": true, "dependencies": { - "esbuild": "^0.21.0", - "get-tsconfig": "^4.7.0", - "loader-utils": "^2.0.4", - "webpack-sources": "^1.4.3" + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" }, - "funding": { - "url": "https://github.com/privatenumber/esbuild-loader?sponsor=1" + "engines": { + "node": ">= 0.4" }, - "peerDependencies": { - "webpack": "^4.40.0 || ^5.0.0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/esbuild-loader/node_modules/@esbuild/aix-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", - "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=12" - } + "node_modules/debounce": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz", + "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==", + "dev": true }, - "node_modules/esbuild-loader/node_modules/@esbuild/android-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", - "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", - "cpu": [ - "arm" - ], + "node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", "dev": true, - "optional": true, - "os": [ - "android" - ], + "dependencies": { + "ms": "^2.1.3" + }, "engines": { - "node": ">=12" + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/esbuild-loader/node_modules/@esbuild/android-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", - "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", - "cpu": [ - "arm64" - ], + "node_modules/decamelize": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-6.0.0.tgz", + "integrity": "sha512-Fv96DCsdOgB6mdGl67MT5JaTNKRzrzill5OH5s8bjYJXVlcXyPYGyPsUkWyGV5p1TXI5esYIYMMeDJL0hEIwaA==", "dev": true, "optional": true, - "os": [ - "android" - ], + "peer": true, "engines": { - "node": ">=12" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/esbuild-loader/node_modules/@esbuild/android-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", - "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", - "cpu": [ - "x64" - ], + "node_modules/decimal.js": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", + "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==", + "dev": true + }, + "node_modules/deep-eql": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", + "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", "dev": true, - "optional": true, - "os": [ - "android" - ], + "license": "MIT", "engines": { - "node": ">=12" + "node": ">=6" } }, - "node_modules/esbuild-loader/node_modules/@esbuild/darwin-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", - "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", - "cpu": [ - "arm64" - ], + "node_modules/deep-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", + "integrity": "sha512-bHtC0iYvWhyaTzvV3CZgPeZQqCOBGyGsVV7v4eevpdkLHfiSrXUdBG+qAuSz4RI70sszvjQ1QSZ98An1yNwpSw==", + "dev": true + }, + "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==" + }, + "node_modules/deepmerge-ts": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/deepmerge-ts/-/deepmerge-ts-7.1.3.tgz", + "integrity": "sha512-qCSH6I0INPxd9Y1VtAiLpnYvz5O//6rCfJXKk0z66Up9/VOSr+1yS8XSKA5IWRxjocFGlzPyaZYe+jxq7OOLtQ==", "dev": true, "optional": true, - "os": [ - "darwin" - ], + "peer": true, "engines": { - "node": ">=12" + "node": ">=16.0.0" } }, - "node_modules/esbuild-loader/node_modules/@esbuild/darwin-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", - "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", - "cpu": [ - "x64" - ], + "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==", "dev": true, - "optional": true, - "os": [ - "darwin" - ], + "dependencies": { + "bundle-name": "^4.1.0", + "default-browser-id": "^5.0.0" + }, "engines": { - "node": ">=12" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/esbuild-loader/node_modules/@esbuild/freebsd-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", - "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", - "cpu": [ - "arm64" - ], + "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==", "dev": true, - "optional": true, - "os": [ - "freebsd" - ], "engines": { - "node": ">=12" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/esbuild-loader/node_modules/@esbuild/freebsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", - "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", - "cpu": [ - "x64" - ], + "node_modules/default-gateway": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", + "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", "dev": true, - "optional": true, - "os": [ - "freebsd" - ], + "dependencies": { + "execa": "^5.0.0" + }, "engines": { - "node": ">=12" + "node": ">= 10" } }, - "node_modules/esbuild-loader/node_modules/@esbuild/linux-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", - "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", - "cpu": [ - "arm" - ], + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", "dev": true, - "optional": true, - "os": [ - "linux" - ], + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, "engines": { - "node": ">=12" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/esbuild-loader/node_modules/@esbuild/linux-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", - "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", - "cpu": [ - "arm64" - ], + "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==", "dev": true, - "optional": true, - "os": [ - "linux" - ], "engines": { "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/esbuild-loader/node_modules/@esbuild/linux-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", - "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", - "cpu": [ - "ia32" - ], + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", "dev": true, - "optional": true, - "os": [ - "linux" - ], + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, "engines": { - "node": ">=12" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/esbuild-loader/node_modules/@esbuild/linux-loong64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", - "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", - "cpu": [ - "loong64" - ], + "node_modules/degenerator": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", + "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", "dev": true, "optional": true, - "os": [ - "linux" - ], + "peer": true, + "dependencies": { + "ast-types": "^0.13.4", + "escodegen": "^2.1.0", + "esprima": "^4.0.1" + }, "engines": { - "node": ">=12" + "node": ">= 14" } }, - "node_modules/esbuild-loader/node_modules/@esbuild/linux-mips64el": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", - "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", - "cpu": [ - "mips64el" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "engines": { - "node": ">=12" + "node": ">=0.4.0" } }, - "node_modules/esbuild-loader/node_modules/@esbuild/linux-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", - "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", - "cpu": [ - "ppc64" - ], + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", + "dev": true + }, + "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, - "optional": true, - "os": [ - "linux" - ], "engines": { - "node": ">=12" + "node": ">= 0.8" } }, - "node_modules/esbuild-loader/node_modules/@esbuild/linux-riscv64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", - "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", - "cpu": [ - "riscv64" - ], + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", "dev": true, - "optional": true, - "os": [ - "linux" - ], "engines": { - "node": ">=12" + "node": ">=6" } }, - "node_modules/esbuild-loader/node_modules/@esbuild/linux-s390x": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", - "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", - "cpu": [ - "s390x" - ], + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", "dev": true, - "optional": true, - "os": [ - "linux" - ], "engines": { - "node": ">=12" + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" } }, - "node_modules/esbuild-loader/node_modules/@esbuild/linux-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", - "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", - "cpu": [ - "x64" - ], + "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/dicer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/dicer/-/dicer-0.3.0.tgz", + "integrity": "sha512-MdceRRWqltEG2dZqO769g27N/3PXfcKl04VhYnBlo2YhH7zPi88VebsjTKclaOyiuMaGU72hTfw3VkUitGcVCA==", "dev": true, - "optional": true, - "os": [ - "linux" - ], + "dependencies": { + "streamsearch": "0.1.2" + }, "engines": { - "node": ">=12" + "node": ">=4.5.0" } }, - "node_modules/esbuild-loader/node_modules/@esbuild/netbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", - "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", - "cpu": [ - "x64" - ], + "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==", "dev": true, - "optional": true, - "os": [ - "netbsd" - ], + "dependencies": { + "@leichtgewicht/ip-codec": "^2.0.1" + }, "engines": { - "node": ">=12" + "node": ">=6" } }, - "node_modules/esbuild-loader/node_modules/@esbuild/openbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", - "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", - "cpu": [ - "x64" - ], + "node_modules/dom-accessibility-api": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", + "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", "dev": true, - "optional": true, - "os": [ - "openbsd" + "license": "MIT" + }, + "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, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } ], + "optional": true, + "peer": true + }, + "node_modules/domexception": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz", + "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==", + "deprecated": "Use your platform's native DOMException instead", + "dependencies": { + "webidl-conversions": "^4.0.2" + } + }, + "node_modules/domexception/node_modules/webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==" + }, + "node_modules/dunder-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.0.tgz", + "integrity": "sha512-9+Sj30DIu+4KvHqMfLUGLFYL2PkURSYMVXJyXe92nFRvlYq5hBjLEhblKB+vkd/WVlUYMWigiY07T91Fkk0+4A==", + "dev": true, + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, "engines": { - "node": ">=12" + "node": ">= 0.4" } }, - "node_modules/esbuild-loader/node_modules/@esbuild/sunos-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", - "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", - "cpu": [ - "x64" - ], + "node_modules/duplexer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", + "dev": true + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" + }, + "node_modules/ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/edge-paths": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/edge-paths/-/edge-paths-3.0.5.tgz", + "integrity": "sha512-sB7vSrDnFa4ezWQk9nZ/n0FdpdUuC6R1EOrlU3DL+bovcNFK28rqu2emmAUjujYEJTWIgQGqgVVWUZXMnc8iWg==", "dev": true, "optional": true, - "os": [ - "sunos" - ], + "peer": true, + "dependencies": { + "@types/which": "^2.0.1", + "which": "^2.0.2" + }, "engines": { - "node": ">=12" + "node": ">=14.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/shirshak55" } }, - "node_modules/esbuild-loader/node_modules/@esbuild/win32-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", - "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", - "cpu": [ - "arm64" - ], + "node_modules/edgedriver": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/edgedriver/-/edgedriver-5.6.1.tgz", + "integrity": "sha512-3Ve9cd5ziLByUdigw6zovVeWJjVs8QHVmqOB0sJ0WNeVPcwf4p18GnxMmVvlFmYRloUwf5suNuorea4QzwBIOA==", "dev": true, + "hasInstallScript": true, "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" + "peer": true, + "dependencies": { + "@wdio/logger": "^8.38.0", + "@zip.js/zip.js": "^2.7.48", + "decamelize": "^6.0.0", + "edge-paths": "^3.0.5", + "fast-xml-parser": "^4.4.1", + "node-fetch": "^3.3.2", + "which": "^4.0.0" + }, + "bin": { + "edgedriver": "bin/edgedriver.js" } }, - "node_modules/esbuild-loader/node_modules/@esbuild/win32-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", - "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", - "cpu": [ - "ia32" - ], + "node_modules/edgedriver/node_modules/@wdio/logger": { + "version": "8.38.0", + "resolved": "https://registry.npmjs.org/@wdio/logger/-/logger-8.38.0.tgz", + "integrity": "sha512-kcHL86RmNbcQP+Gq/vQUGlArfU6IIcbbnNp32rRIraitomZow+iEoc519rdQmSVusDozMS5DZthkgDdxK+vz6Q==", "dev": true, "optional": true, - "os": [ - "win32" - ], + "peer": true, + "dependencies": { + "chalk": "^5.1.2", + "loglevel": "^1.6.0", + "loglevel-plugin-prefix": "^0.8.4", + "strip-ansi": "^7.1.0" + }, "engines": { - "node": ">=12" + "node": "^16.13 || >=18" } }, - "node_modules/esbuild-loader/node_modules/@esbuild/win32-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", - "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", - "cpu": [ - "x64" - ], + "node_modules/edgedriver/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, "optional": true, - "os": [ - "win32" - ], + "peer": true, "engines": { "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, - "node_modules/esbuild-loader/node_modules/esbuild": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", - "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "node_modules/edgedriver/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", "dev": true, - "hasInstallScript": true, - "bin": { - "esbuild": "bin/esbuild" - }, + "optional": true, + "peer": true, "engines": { - "node": ">=12" + "node": "^12.17.0 || ^14.13 || >=16.0.0" }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.21.5", - "@esbuild/android-arm": "0.21.5", - "@esbuild/android-arm64": "0.21.5", - "@esbuild/android-x64": "0.21.5", - "@esbuild/darwin-arm64": "0.21.5", - "@esbuild/darwin-x64": "0.21.5", - "@esbuild/freebsd-arm64": "0.21.5", - "@esbuild/freebsd-x64": "0.21.5", - "@esbuild/linux-arm": "0.21.5", - "@esbuild/linux-arm64": "0.21.5", - "@esbuild/linux-ia32": "0.21.5", - "@esbuild/linux-loong64": "0.21.5", - "@esbuild/linux-mips64el": "0.21.5", - "@esbuild/linux-ppc64": "0.21.5", - "@esbuild/linux-riscv64": "0.21.5", - "@esbuild/linux-s390x": "0.21.5", - "@esbuild/linux-x64": "0.21.5", - "@esbuild/netbsd-x64": "0.21.5", - "@esbuild/openbsd-x64": "0.21.5", - "@esbuild/sunos-x64": "0.21.5", - "@esbuild/win32-arm64": "0.21.5", - "@esbuild/win32-ia32": "0.21.5", - "@esbuild/win32-x64": "0.21.5" + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/escalade": { + "node_modules/edgedriver/node_modules/isexe": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", "dev": true, + "optional": true, + "peer": true, "engines": { - "node": ">=6" + "node": ">=16" } }, - "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/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==", + "node_modules/edgedriver/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==", "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, "engines": { - "node": ">=10" + "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "node_modules/escodegen": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", - "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", + "node_modules/edgedriver/node_modules/which": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", + "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", + "dev": true, + "optional": true, + "peer": true, "dependencies": { - "esprima": "^4.0.1", - "estraverse": "^5.2.0", - "esutils": "^2.0.2" + "isexe": "^3.1.1" }, "bin": { - "escodegen": "bin/escodegen.js", - "esgenerate": "bin/esgenerate.js" + "node-which": "bin/which.js" }, "engines": { - "node": ">=6.0" - }, - "optionalDependencies": { - "source-map": "~0.6.1" + "node": "^16.13.0 || >=18.0.0" } }, - "node_modules/eslint": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.56.0.tgz", - "integrity": "sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==", - "dev": true, + "node_modules/editorconfig": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-1.0.4.tgz", + "integrity": "sha512-L9Qe08KWTlqYMVvMcTIvMAdl1cDUubzRNYL+WfA4bLDMHe4nemKkpmYzkznE1FwLKu0EEmy6obgQKzMJrg4x9Q==", "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.56.0", - "@humanwhocodes/config-array": "^0.11.13", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" + "@one-ini/wasm": "0.1.1", + "commander": "^10.0.0", + "minimatch": "9.0.1", + "semver": "^7.5.3" }, "bin": { - "eslint": "bin/eslint.js" + "editorconfig": "bin/editorconfig" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" + "node": ">=14" } }, - "node_modules/eslint-formatter-codeframe": { - "version": "7.32.1", - "resolved": "https://registry.npmjs.org/eslint-formatter-codeframe/-/eslint-formatter-codeframe-7.32.1.tgz", - "integrity": "sha512-DK/3Q3+zVKq/7PdSYiCxPrsDF8H/TRMK5n8Hziwr4IMkMy+XiKSwbpj25AdajS63I/B61Snetq4uVvX9fOLyAg==", - "dev": true, + "node_modules/editorconfig/node_modules/commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "engines": { + "node": ">=14" + } + }, + "node_modules/editorconfig/node_modules/minimatch": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.1.tgz", + "integrity": "sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==", "dependencies": { - "@babel/code-frame": "7.12.11", - "chalk": "^4.0.0" + "brace-expansion": "^2.0.1" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/eslint-import-resolver-node": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", - "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", + "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/electron-to-chromium": { + "version": "1.5.83", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.83.tgz", + "integrity": "sha512-LcUDPqSt+V0QmI47XLzZrz5OqILSMGsPFkDYus22rIbgorSvBYEFqq854ltTmUdHkY92FSdAAvsh4jWEULMdfQ==", "dev": true, - "dependencies": { - "debug": "^3.2.7", - "is-core-module": "^2.13.0", - "resolve": "^1.22.4" - } + "license": "ISC", + "optional": true, + "peer": true }, - "node_modules/eslint-import-resolver-node/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "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==" + }, + "node_modules/enabled": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz", + "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==", + "dev": true + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", "dev": true, - "dependencies": { - "ms": "^2.1.1" + "engines": { + "node": ">= 0.8" } }, - "node_modules/eslint-import-resolver-typescript": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.6.1.tgz", - "integrity": "sha512-xgdptdoi5W3niYeuQxKmzVDTATvLYqhpwmykwsh7f6HIOStGWEIL9iqZgQDF9u9OEzrRwR8no5q2VT+bjAujTg==", + "node_modules/encoding-sniffer": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.0.tgz", + "integrity": "sha512-ju7Wq1kg04I3HtiYIOrUrdfdDvkyO9s5XM8QAj/bN61Yo/Vb4vgJxy5vi4Yxk01gWHbrofpPtpxM8bKger9jhg==", "dev": true, + "optional": true, + "peer": true, "dependencies": { - "debug": "^4.3.4", - "enhanced-resolve": "^5.12.0", - "eslint-module-utils": "^2.7.4", - "fast-glob": "^3.3.1", - "get-tsconfig": "^4.5.0", - "is-core-module": "^2.11.0", - "is-glob": "^4.0.3" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" + "iconv-lite": "^0.6.3", + "whatwg-encoding": "^3.1.1" }, "funding": { - "url": "https://opencollective.com/unts/projects/eslint-import-resolver-ts" - }, - "peerDependencies": { - "eslint": "*", - "eslint-plugin-import": "*" + "url": "https://github.com/fb55/encoding-sniffer?sponsor=1" } }, - "node_modules/eslint-interactive": { - "version": "10.8.0", - "resolved": "https://registry.npmjs.org/eslint-interactive/-/eslint-interactive-10.8.0.tgz", - "integrity": "sha512-bsMSr0NVyxoSbKbA3Rn8so5+A9q+Zu8xExiIM18umPjrqfBAN8WcJfsWvfc9Myfiqn2WwLDM9mRglbx+Hp+z3Q==", + "node_modules/encoding-sniffer/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==", "dev": true, + "optional": true, + "peer": true, "dependencies": { - "boxen": "^7.0.2", - "chalk": "^5.0.1", - "comlink": "^4.3.1", - "enquirer": "^2.3.6", - "eslint-formatter-codeframe": "^7.32.1", - "estraverse": "^5.3.0", - "find-cache-dir": "^4.0.0", - "is-installed-globally": "^0.4.0", - "ora": "^6.1.2", - "strip-ansi": "^7.0.1", - "table": "^6.8.1", - "terminal-link": "^3.0.0", - "yargs": "^17.5.1" - }, - "bin": { - "eslint-interactive": "bin/eslint-interactive.js" + "safer-buffer": ">= 2.1.2 < 3.0.0" }, "engines": { - "node": "^14.13.1 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" + "node": ">=0.10.0" } }, - "node_modules/eslint-interactive/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" + "optional": true, + "peer": true, + "dependencies": { + "once": "^1.4.0" } }, - "node_modules/eslint-interactive/node_modules/chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "node_modules/enhanced-resolve": { + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", + "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", "dev": true, - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "engines": { + "node": ">=10.13.0" } }, - "node_modules/eslint-interactive/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/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", "dev": true, - "dependencies": { - "ansi-regex": "^6.0.1" - }, "engines": { - "node": ">=12" + "node": ">=0.12" }, "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" + "url": "https://github.com/fb55/entities?sponsor=1" } }, - "node_modules/eslint-module-utils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz", - "integrity": "sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==", - "dev": true, - "dependencies": { - "debug": "^3.2.7" + "node_modules/es-abstract": { + "version": "1.23.5", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.5.tgz", + "integrity": "sha512-vlmniQ0WNPwXqA0BnmwV3Ng7HxiGlh6r5U6JcTMNx8OilcAGqVJBHJcPjqOMaczU9fRuRK5Px2BdVyPRnKMMVQ==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "arraybuffer.prototype.slice": "^1.0.3", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "data-view-buffer": "^1.0.1", + "data-view-byte-length": "^1.0.1", + "data-view-byte-offset": "^1.0.0", + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-set-tostringtag": "^2.0.3", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.4", + "get-symbol-description": "^1.0.2", + "globalthis": "^1.0.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", + "has-symbols": "^1.0.3", + "hasown": "^2.0.2", + "internal-slot": "^1.0.7", + "is-array-buffer": "^3.0.4", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.1", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.3", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.13", + "is-weakref": "^1.0.2", + "object-inspect": "^1.13.3", + "object-keys": "^1.1.1", + "object.assign": "^4.1.5", + "regexp.prototype.flags": "^1.5.3", + "safe-array-concat": "^1.1.2", + "safe-regex-test": "^1.0.3", + "string.prototype.trim": "^1.2.9", + "string.prototype.trimend": "^1.0.8", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.2", + "typed-array-byte-length": "^1.0.1", + "typed-array-byte-offset": "^1.0.2", + "typed-array-length": "^1.0.6", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.15" }, "engines": { - "node": ">=4" + "node": ">= 0.4" }, - "peerDependenciesMeta": { - "eslint": { - "optional": true - } - } - }, - "node_modules/eslint-module-utils/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/eslint-plugin-import": { - "version": "2.29.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", - "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", + "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, - "dependencies": { - "array-includes": "^3.1.7", - "array.prototype.findlastindex": "^1.2.3", - "array.prototype.flat": "^1.3.2", - "array.prototype.flatmap": "^1.3.2", - "debug": "^3.2.7", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.9", - "eslint-module-utils": "^2.8.0", - "hasown": "^2.0.0", - "is-core-module": "^2.13.1", - "is-glob": "^4.0.3", - "minimatch": "^3.1.2", - "object.fromentries": "^2.0.7", - "object.groupby": "^1.0.1", - "object.values": "^1.1.7", - "semver": "^6.3.1", - "tsconfig-paths": "^3.15.0" - }, "engines": { - "node": ">=4" - }, - "peerDependencies": { - "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" + "node": ">= 0.4" } }, - "node_modules/eslint-plugin-import/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "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, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "engines": { + "node": ">= 0.4" } }, - "node_modules/eslint-plugin-import/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "node_modules/es-module-lexer": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.6.0.tgz", + "integrity": "sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==", "dev": true, - "dependencies": { - "ms": "^2.1.1" - } + "license": "MIT" }, - "node_modules/eslint-plugin-import/node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "node_modules/es-object-atoms": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", + "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", "dev": true, "dependencies": { - "esutils": "^2.0.2" + "es-errors": "^1.3.0" }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" } }, - "node_modules/eslint-plugin-import/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "node_modules/es-set-tostringtag": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", + "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", "dev": true, "dependencies": { - "brace-expansion": "^1.1.7" + "get-intrinsic": "^1.2.4", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.1" }, "engines": { - "node": "*" + "node": ">= 0.4" } }, - "node_modules/eslint-plugin-import/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/es-shim-unscopables": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", + "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", "dev": true, - "bin": { - "semver": "bin/semver.js" + "dependencies": { + "hasown": "^2.0.0" } }, - "node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", "dev": true, "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": ">= 0.4" }, "funding": { - "url": "https://opencollective.com/eslint" + "url": "https://github.com/sponsors/ljharb" } }, - "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==", + "node_modules/esbuild": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.24.2.tgz", + "integrity": "sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==", "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": ">=18" }, - "funding": { - "url": "https://opencollective.com/eslint" + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.24.2", + "@esbuild/android-arm": "0.24.2", + "@esbuild/android-arm64": "0.24.2", + "@esbuild/android-x64": "0.24.2", + "@esbuild/darwin-arm64": "0.24.2", + "@esbuild/darwin-x64": "0.24.2", + "@esbuild/freebsd-arm64": "0.24.2", + "@esbuild/freebsd-x64": "0.24.2", + "@esbuild/linux-arm": "0.24.2", + "@esbuild/linux-arm64": "0.24.2", + "@esbuild/linux-ia32": "0.24.2", + "@esbuild/linux-loong64": "0.24.2", + "@esbuild/linux-mips64el": "0.24.2", + "@esbuild/linux-ppc64": "0.24.2", + "@esbuild/linux-riscv64": "0.24.2", + "@esbuild/linux-s390x": "0.24.2", + "@esbuild/linux-x64": "0.24.2", + "@esbuild/netbsd-arm64": "0.24.2", + "@esbuild/netbsd-x64": "0.24.2", + "@esbuild/openbsd-arm64": "0.24.2", + "@esbuild/openbsd-x64": "0.24.2", + "@esbuild/sunos-x64": "0.24.2", + "@esbuild/win32-arm64": "0.24.2", + "@esbuild/win32-ia32": "0.24.2", + "@esbuild/win32-x64": "0.24.2" } }, - "node_modules/eslint-webpack-plugin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/eslint-webpack-plugin/-/eslint-webpack-plugin-4.0.1.tgz", - "integrity": "sha512-fUFcXpui/FftGx3NzvWgLZXlLbu+m74sUxGEgxgoxYcUtkIQbS6SdNNZkS99m5ycb23TfoNYrDpp1k/CK5j6Hw==", - "dev": true, - "dependencies": { - "@types/eslint": "^8.37.0", - "jest-worker": "^29.5.0", - "micromatch": "^4.0.5", - "normalize-path": "^3.0.0", - "schema-utils": "^4.0.0" - }, + "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": ">= 14.15.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "eslint": "^8.0.0", - "webpack": "^5.0.0" + "node": ">=6" } }, - "node_modules/eslint-webpack-plugin/node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "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/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": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" + "engines": { + "node": ">=10" }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint-webpack-plugin/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==", + "node_modules/escodegen": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", "dev": true, + "optional": true, + "peer": true, "dependencies": { - "fast-deep-equal": "^3.1.3" + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2" }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, - "node_modules/eslint-webpack-plugin/node_modules/jest-worker": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", - "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", - "dev": true, - "dependencies": { - "@types/node": "*", - "jest-util": "^29.7.0", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" } }, - "node_modules/eslint-webpack-plugin/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/eslint-webpack-plugin/node_modules/schema-utils": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", - "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "node_modules/eslint": { + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.18.0.tgz", + "integrity": "sha512-+waTfRWQlSbpt3KWE+CjrPPYnbq9kfZIYUqapc0uBXyjTp8aYXZDsUH16m39Ryq3NjAVP4tjuF7KaukeqoCoaA==", "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" + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.19.0", + "@eslint/core": "^0.10.0", + "@eslint/eslintrc": "^3.2.0", + "@eslint/js": "9.18.0", + "@eslint/plugin-kit": "^0.2.5", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.1", + "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.2.0", + "eslint-visitor-keys": "^4.2.0", + "espree": "^10.3.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": ">= 12.13.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } } }, - "node_modules/eslint-webpack-plugin/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "node_modules/eslint-formatter-codeframe": { + "version": "7.32.1", + "resolved": "https://registry.npmjs.org/eslint-formatter-codeframe/-/eslint-formatter-codeframe-7.32.1.tgz", + "integrity": "sha512-DK/3Q3+zVKq/7PdSYiCxPrsDF8H/TRMK5n8Hziwr4IMkMy+XiKSwbpj25AdajS63I/B61Snetq4uVvX9fOLyAg==", "dev": true, + "license": "MIT", "dependencies": { - "has-flag": "^4.0.0" + "@babel/code-frame": "7.12.11", + "chalk": "^4.0.0" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" + "node": "^10.12.0 || >=12.0.0" } }, - "node_modules/eslint/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "node_modules/eslint-formatter-codeframe/node_modules/@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", "dev": true, + "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "@babel/highlight": "^7.10.4" } }, - "node_modules/eslint/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "node_modules/eslint-import-resolver-node": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", "dev": true, "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" } }, - "node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "dependencies": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" + "ms": "^2.1.1" + } + }, + "node_modules/eslint-import-resolver-typescript": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.7.0.tgz", + "integrity": "sha512-Vrwyi8HHxY97K5ebydMtffsWAn1SCR9eol49eCd5fJS4O1WV7PaAjbcjmbfJJSMz/t4Mal212Uz/fQZrOB8mow==", + "dev": true, + "dependencies": { + "@nolyfill/is-core-module": "1.0.39", + "debug": "^4.3.7", + "enhanced-resolve": "^5.15.0", + "fast-glob": "^3.3.2", + "get-tsconfig": "^4.7.5", + "is-bun-module": "^1.0.2", + "is-glob": "^4.0.3", + "stable-hash": "^0.0.4" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^14.18.0 || >=16.0.0" }, "funding": { - "url": "https://opencollective.com/eslint" + "url": "https://opencollective.com/unts/projects/eslint-import-resolver-ts" + }, + "peerDependencies": { + "eslint": "*", + "eslint-plugin-import": "*", + "eslint-plugin-import-x": "*" + }, + "peerDependenciesMeta": { + "eslint-plugin-import": { + "optional": true + }, + "eslint-plugin-import-x": { + "optional": true + } } }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" + "node_modules/eslint-module-utils": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.0.tgz", + "integrity": "sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==", + "dev": true, + "dependencies": { + "debug": "^3.2.7" }, "engines": { "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } } }, - "node_modules/esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" + "ms": "^2.1.1" } }, - "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/eslint-plugin-import": { + "version": "2.31.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.31.0.tgz", + "integrity": "sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==", "dev": true, "dependencies": { - "estraverse": "^5.2.0" + "@rtsao/scc": "^1.1.0", + "array-includes": "^3.1.8", + "array.prototype.findlastindex": "^1.2.5", + "array.prototype.flat": "^1.3.2", + "array.prototype.flatmap": "^1.3.2", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.12.0", + "hasown": "^2.0.2", + "is-core-module": "^2.15.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.8", + "object.groupby": "^1.0.3", + "object.values": "^1.2.0", + "semver": "^6.3.1", + "string.prototype.trimend": "^1.0.8", + "tsconfig-paths": "^3.15.0" }, "engines": { - "node": ">=4.0" + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" } }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "engines": { - "node": ">=4.0" + "node_modules/eslint-plugin-import/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "node_modules/estree-walker": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", - "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "dependencies": { - "@types/estree": "^1.0.0" + "ms": "^2.1.1" } }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "engines": { + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { "node": ">=0.10.0" } }, - "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/eslint-plugin-import/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, "engines": { - "node": ">= 0.6" + "node": "*" } }, - "node_modules/event-target-shim": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "node_modules/eslint-plugin-import/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, - "engines": { - "node": ">=6" + "bin": { + "semver": "bin/semver.js" } }, - "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/events": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", - "integrity": "sha512-kEcvvCBByWXGnZy6JUlgAp2gBIUjfCAV6P6TgT1/aaQKcmuAEC4OZTV1I4EWQLz2gxZw76atuVyvHhTxvi0Flw==", - "engines": { - "node": ">=0.4.x" + "node_modules/eslint-plugin-oxlint": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/eslint-plugin-oxlint/-/eslint-plugin-oxlint-0.15.7.tgz", + "integrity": "sha512-u/Abrwh/6uu533ofqKlzmZra8ezgoMfUpRJ4I0UQmque/TqDPa+WSbdTLqRopmuTtBExUKJ4/jnyrFB3jk4GOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "jsonc-parser": "^3.3.1" } }, - "node_modules/execa": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", - "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "node_modules/eslint-rspack-plugin": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-rspack-plugin/-/eslint-rspack-plugin-4.2.1.tgz", + "integrity": "sha512-jv+VggchVC56U9ZxP2RUXTVOeOyjKVuTxGSQdp6YkPLLi9JTHFW5Fwkqi84NrOD3itBQz5m+Agvx6faAV1MJbg==", "dev": true, "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^8.0.1", - "human-signals": "^5.0.0", - "is-stream": "^3.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^5.1.0", - "onetime": "^6.0.0", - "signal-exit": "^4.1.0", - "strip-final-newline": "^3.0.0" + "@types/eslint": "^8.56.10", + "jest-worker": "^29.7.0", + "micromatch": "^4.0.8", + "normalize-path": "^3.0.0", + "schema-utils": "^4.2.0" }, "engines": { - "node": ">=16.17" + "node": ">= 16.0.0" }, "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "eslint": "^8.0.0 || ^9.0.0" } }, - "node_modules/execa/node_modules/mimic-fn": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", - "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "node_modules/eslint-rspack-plugin/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, - "engines": { - "node": ">=12" + "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": { - "url": "https://github.com/sponsors/sindresorhus" + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/execa/node_modules/npm-run-path": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", - "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", + "node_modules/eslint-rspack-plugin/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": { - "path-key": "^4.0.0" + "fast-deep-equal": "^3.1.3" }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/eslint-rspack-plugin/node_modules/jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "dev": true, + "dependencies": { + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/execa/node_modules/onetime": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", - "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "node_modules/eslint-rspack-plugin/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/eslint-rspack-plugin/node_modules/schema-utils": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.0.tgz", + "integrity": "sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==", "dev": true, "dependencies": { - "mimic-fn": "^4.0.0" + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" }, "engines": { - "node": ">=12" + "node": ">= 10.13.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "type": "opencollective", + "url": "https://opencollective.com/webpack" } }, - "node_modules/execa/node_modules/path-key": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", - "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "node_modules/eslint-rspack-plugin/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, "engines": { - "node": ">=12" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/express": { - "version": "4.19.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", - "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", + "node_modules/eslint-scope": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.2.0.tgz", + "integrity": "sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==", "dev": true, "dependencies": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.2", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.6.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.2.0", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.7", - "qs": "6.11.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" }, "engines": { - "node": ">= 0.10.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/express/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/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, - "dependencies": { - "ms": "2.0.0" + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "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==", - "dev": true - }, - "node_modules/express/node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "dependencies": { - "side-channel": "^1.0.4" - }, + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint/node_modules/eslint-visitor-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "dev": true, "engines": { - "node": ">=0.6" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://opencollective.com/eslint" } }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, "dependencies": { - "is-extendable": "^0.1.0" + "brace-expansion": "^1.1.7" }, "engines": { - "node": ">=0.10.0" + "node": "*" } }, - "node_modules/extract-zip": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", - "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "node_modules/espree": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", + "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", "dev": true, "dependencies": { - "debug": "^4.1.1", - "get-stream": "^5.1.0", - "yauzl": "^2.10.0" - }, - "bin": { - "extract-zip": "cli.js" + "acorn": "^8.14.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.0" }, "engines": { - "node": ">= 10.17.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, - "optionalDependencies": { - "@types/yauzl": "^2.9.1" + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/extract-zip/node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "node_modules/espree/node_modules/eslint-visitor-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", "dev": true, - "dependencies": { - "pump": "^3.0.0" - }, "engines": { - "node": ">=8" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://opencollective.com/eslint" } }, - "node_modules/extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", - "engines": [ - "node >=0.6.0" - ] - }, - "node_modules/falafel": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/falafel/-/falafel-2.2.5.tgz", - "integrity": "sha512-HuC1qF9iTnHDnML9YZAdCDQwT0yKl/U55K4XSUXqGAA2GLoafFgWRqdAbhWJxXaYD4pyoVxAJ8wH670jMpI9DQ==", - "dependencies": { - "acorn": "^7.1.1", - "isarray": "^2.0.1" + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" }, "engines": { - "node": ">=0.4.0" + "node": ">=4" } }, - "node_modules/falafel/node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "bin": { - "acorn": "bin/acorn" + "node_modules/esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" }, "engines": { - "node": ">=0.4.0" + "node": ">=0.10" } }, - "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/fast-fifo": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", - "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", - "dev": true - }, - "node_modules/fast-glob": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", - "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "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": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" + "estraverse": "^5.2.0" }, "engines": { - "node": ">=8.6.0" + "node": ">=4.0" } }, - "node_modules/fast-glob/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "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, - "dependencies": { - "is-glob": "^4.0.1" - }, "engines": { - "node": ">= 6" + "node": ">=4.0" } }, - "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==" - }, - "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==" - }, - "node_modules/fastest-levenshtein": { - "version": "1.0.16", - "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", - "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", "dev": true, - "engines": { - "node": ">= 4.9.1" + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" } }, - "node_modules/fastq": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.0.tgz", - "integrity": "sha512-zGygtijUMT7jnk3h26kUms3BkSDp4IfIKjmnqI2tvx6nuBfiF1UqOxbnLfzdv+apBy+53oaImsKtMw/xYbW+1w==", - "dev": true, - "dependencies": { - "reusify": "^1.0.4" + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "engines": { + "node": ">=0.10.0" } }, - "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/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", "dev": true, - "dependencies": { - "websocket-driver": ">=0.5.1" - }, "engines": { - "node": ">=0.8.0" + "node": ">= 0.6" } }, - "node_modules/fd-slicer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", "dev": true, - "dependencies": { - "pend": "~1.2.0" + "optional": true, + "peer": true, + "engines": { + "node": ">=6" } }, - "node_modules/fetch-blob": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", - "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", + "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/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/jimmywarting" - }, - { - "type": "paypal", - "url": "https://paypal.me/jimmywarting" - } - ], "dependencies": { - "node-domexception": "^1.0.0", - "web-streams-polyfill": "^3.0.3" + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" }, "engines": { - "node": "^12.20 || >= 14.13" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/fflate": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz", - "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==" - }, - "node_modules/file-entry-cache": { + "node_modules/execa/node_modules/get-stream": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "dev": true, - "dependencies": { - "flat-cache": "^3.0.4" - }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "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/execa/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/exit-hook": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-4.0.0.tgz", + "integrity": "sha512-Fqs7ChZm72y40wKjOFXBKg7nJZvQJmewP5/7LtePDdnah/+FH9Hp5sgMujSCMPXlxOAW2//1jrW9pnsY7o20vQ==", "dev": true, - "dependencies": { - "to-regex-range": "^5.0.1" + "engines": { + "node": ">=18" }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/expect-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.1.0.tgz", + "integrity": "sha512-bFi65yM+xZgk+u/KRIpekdSYkTB5W1pEf0Lt8Q8Msh7b+eQ7LXVtIB1Bkm4fvclDEL1b2CZkMhv2mOeF8tMdkA==", + "dev": true, "engines": { - "node": ">=8" + "node": ">=12.0.0" } }, - "node_modules/finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "node_modules/express": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", + "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", "dev": true, + "license": "MIT", "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", "debug": "2.6.9", - "encodeurl": "~1.0.2", + "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", "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", - "unpipe": "~1.0.0" + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" }, "engines": { - "node": ">= 0.8" + "node": ">= 0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/finalhandler/node_modules/debug": { + "node_modules/express/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==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express/node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", @@ -6814,360 +7415,426 @@ "ms": "2.0.0" } }, - "node_modules/finalhandler/node_modules/ms": { + "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==", "dev": true }, - "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/express/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==", + "dev": true + }, + "node_modules/express/node_modules/qs": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", "dev": true, "dependencies": { - "common-path-prefix": "^3.0.0", - "pkg-dir": "^7.0.0" + "side-channel": "^1.0.6" }, "engines": { - "node": ">=14.16" + "node": ">=0.6" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "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, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" + "is-extendable": "^0.1.0" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=0.10.0" } }, - "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" - } - }, - "node_modules/flat-cache": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", - "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "node_modules/extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", "dev": true, + "optional": true, + "peer": true, "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + }, + "bin": { + "extract-zip": "cli.js" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">= 10.17.0" + }, + "optionalDependencies": { + "@types/yauzl": "^2.9.1" } }, - "node_modules/flatted": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", - "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", - "dev": true - }, - "node_modules/follow-redirects": { - "version": "1.15.6", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", - "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", + "node_modules/extract-zip/node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], + "license": "MIT", + "optional": true, + "peer": true, "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } + "node": "*" } }, - "node_modules/for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "node_modules/extract-zip/node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", "dev": true, + "license": "MIT", + "optional": true, + "peer": true, "dependencies": { - "is-callable": "^1.1.3" + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" } }, - "node_modules/foreground-child": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", - "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", - "dependencies": { - "cross-spawn": "^7.0.0", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } + "node_modules/extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", + "engines": [ + "node >=0.6.0" + ] }, - "node_modules/forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", - "engines": { - "node": "*" - } + "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/fork-ts-checker-webpack-plugin": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.3.tgz", - "integrity": "sha512-SbH/l9ikmMWycd5puHJKTkZJKddF4iRLyW3DeZ08HTI7NGyLS38MXd/KGgeWumQO7YNQbW2u/NtPT2YowbPaGQ==", + "node_modules/fast-fifo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", + "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", "dev": true, - "dependencies": { - "@babel/code-frame": "^7.8.3", - "@types/json-schema": "^7.0.5", - "chalk": "^4.1.0", - "chokidar": "^3.4.2", - "cosmiconfig": "^6.0.0", - "deepmerge": "^4.2.2", - "fs-extra": "^9.0.0", - "glob": "^7.1.6", - "memfs": "^3.1.2", - "minimatch": "^3.0.4", - "schema-utils": "2.7.0", - "semver": "^7.3.2", - "tapable": "^1.0.0" - }, - "engines": { - "node": ">=10", - "yarn": ">=1.0.0" - }, - "peerDependencies": { - "eslint": ">= 6", - "typescript": ">= 2.7", - "vue-template-compiler": "*", - "webpack": ">= 4" - }, - "peerDependenciesMeta": { - "eslint": { - "optional": true - }, - "vue-template-compiler": { - "optional": true - } - } + "optional": true, + "peer": true }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/@babel/code-frame": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", - "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", "dev": true, "dependencies": { - "@babel/highlight": "^7.23.4", - "chalk": "^2.4.2" + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" }, "engines": { - "node": ">=6.9.0" + "node": ">=8.6.0" } }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/@babel/code-frame/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "is-glob": "^4.0.1" }, "engines": { - "node": ">=4" + "node": ">= 6" } }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "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==" + }, + "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==" + }, + "node_modules/fast-uri": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.3.tgz", + "integrity": "sha512-aLrHthzCjH5He4Z2H9YZ+v6Ujb9ocRuW6ZzkJQOrTxleEijANq4v1TsaPaVG1PZcuurEzrLcWRyYBYXD5cEiaw==", + "dev": true + }, + "node_modules/fast-xml-parser": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.5.0.tgz", + "integrity": "sha512-/PlTQCI96+fZMAOLMZK4CWG1ItCbfZ/0jx7UIJFChPNrx7tcEgerUgWbeieCM9MfHInUDyK8DWYZ+YrywDJuTg==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + }, + { + "type": "paypal", + "url": "https://paypal.me/naturalintelligence" + } + ], + "optional": true, + "peer": true, "dependencies": { - "color-convert": "^1.9.0" + "strnum": "^1.0.5" }, - "engines": { - "node": ">=4" + "bin": { + "fxparser": "src/cli/cli.js" } }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "node_modules/fastq": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.0.tgz", + "integrity": "sha512-zGygtijUMT7jnk3h26kUms3BkSDp4IfIKjmnqI2tvx6nuBfiF1UqOxbnLfzdv+apBy+53oaImsKtMw/xYbW+1w==", "dev": true, "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "reusify": "^1.0.4" } }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "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==", "dev": true, "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, + "websocket-driver": ">=0.5.1" + }, "engines": { "node": ">=0.8.0" } }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", "dev": true, + "license": "MIT", + "optional": true, + "peer": true, "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=10" + "pend": "~1.2.0" } }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "node_modules/fecha": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz", + "integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==", + "dev": true + }, + "node_modules/fetch-blob": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", + "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "paypal", + "url": "https://paypal.me/jimmywarting" + } + ], + "optional": true, + "peer": 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-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" }, "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": "^12.20 || >= 14.13" } }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } + "node_modules/fflate": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz", + "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==" }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/memfs": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", - "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", + "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, "dependencies": { - "fs-monkey": "^1.0.4" + "flat-cache": "^4.0.0" }, "engines": { - "node": ">= 4.0.0" + "node": ">=16.0.0" } }, - "node_modules/fork-ts-checker-webpack-plugin/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/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": { - "brace-expansion": "^1.1.7" + "to-regex-range": "^5.0.1" }, "engines": { - "node": "*" + "node": ">=8" } }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/schema-utils": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz", - "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==", + "node_modules/finalhandler": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", + "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", "dev": true, "dependencies": { - "@types/json-schema": "^7.0.4", - "ajv": "^6.12.2", - "ajv-keywords": "^3.4.1" - }, + "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" + }, + "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==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "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==", + "dev": true + }, + "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, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, "engines": { - "node": ">= 8.9.0" + "node": ">=10" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "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" + } + }, + "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, "dependencies": { - "has-flag": "^3.0.0" + "flatted": "^3.2.9", + "keyv": "^4.5.4" }, "engines": { - "node": ">=4" + "node": ">=16" } }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/tapable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", - "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", + "node_modules/flatted": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.2.tgz", + "integrity": "sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==", + "dev": true, + "license": "ISC" + }, + "node_modules/fn.name": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz", + "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==", + "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": ">=6" + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } } }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", "dev": true, + "dependencies": { + "is-callable": "^1.1.3" + } + }, + "node_modules/foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, "engines": { - "node": ">= 10.0.0" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", + "engines": { + "node": "*" } }, - "node_modules/form-data-encoder": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.1.4.tgz", - "integrity": "sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==", + "node_modules/form-data": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", + "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, "engines": { - "node": ">= 14.17" + "node": ">= 6" } }, "node_modules/formdata-polyfill": { @@ -7175,6 +7842,8 @@ "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "fetch-blob": "^3.1.2" }, @@ -7201,40 +7870,28 @@ } }, "node_modules/fs-extra": { - "version": "11.2.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", - "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", + "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": "^6.0.1", - "universalify": "^2.0.0" + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" }, "engines": { - "node": ">=14.14" + "node": ">=6 <7 || >=8" } }, "node_modules/fs-extra/node_modules/universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "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": ">= 10.0.0" + "node": ">= 4.0.0" } }, - "node_modules/fs-monkey": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.5.tgz", - "integrity": "sha512-8uMbBjrhzW76TYgEV27Y5E//W2f/lTFmx78P2w19FZSxarhI/798APGQyuGCwmkNxgwGRhrLfvWyLBvNtuOmew==", - "dev": true - }, - "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", @@ -7253,6 +7910,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -7285,17 +7943,19 @@ } }, "node_modules/geckodriver": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/geckodriver/-/geckodriver-4.4.2.tgz", - "integrity": "sha512-/JFJ7DJPJUvDhLjzQk+DwjlkAmiShddfRHhZ/xVL9FWbza5Bi3UMGmmerEKqD69JbRs7R81ZW31co686mdYZyA==", + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/geckodriver/-/geckodriver-4.5.1.tgz", + "integrity": "sha512-lGCRqPMuzbRNDWJOQcUqhNqPvNsIFu6yzXF8J/6K3WCYFd2r5ckbeF7h1cxsnjA7YLSEiWzERCt6/gjZ3tW0ug==", "dev": true, "hasInstallScript": true, + "optional": true, + "peer": true, "dependencies": { - "@wdio/logger": "^8.28.0", - "@zip.js/zip.js": "^2.7.44", + "@wdio/logger": "^9.0.0", + "@zip.js/zip.js": "^2.7.48", "decamelize": "^6.0.0", "http-proxy-agent": "^7.0.2", - "https-proxy-agent": "^7.0.4", + "https-proxy-agent": "^7.0.5", "node-fetch": "^3.3.2", "tar-fs": "^3.0.6", "which": "^4.0.0" @@ -7312,6 +7972,8 @@ "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", "dev": true, + "optional": true, + "peer": true, "engines": { "node": ">=16" } @@ -7321,6 +7983,8 @@ "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "isexe": "^3.1.1" }, @@ -7340,25 +8004,23 @@ "node": "6.* || 8.* || >= 10.*" } }, - "node_modules/get-func-name": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", - "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", - "dev": true, - "engines": { - "node": "*" - } - }, "node_modules/get-intrinsic": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", - "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.5.tgz", + "integrity": "sha512-Y4+pKa7XeRUPWFNvOOYHkRYrfzW07oraURSvjDmRVOJ748OrVmeXtpE4+GCEHncjCjkTxPNRt8kEbxDhsn6VTg==", "dev": true, "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "dunder-proto": "^1.0.0", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -7369,6 +8031,8 @@ "resolved": "https://registry.npmjs.org/get-port/-/get-port-7.1.0.tgz", "integrity": "sha512-QB9NKEeDg3xxVwCCwJQ9+xycaz6pBB6iQ76wiWMl1927n0Kir6alPiP+yuiICLLU4jpMe08dXfpebuQppFA2zw==", "dev": true, + "optional": true, + "peer": true, "engines": { "node": ">=16" }, @@ -7377,25 +8041,31 @@ } }, "node_modules/get-stream": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", - "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "pump": "^3.0.0" + }, "engines": { - "node": ">=16" + "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", + "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" + "call-bind": "^1.0.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4" }, "engines": { "node": ">= 0.4" @@ -7417,15 +8087,16 @@ } }, "node_modules/get-uri": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.3.tgz", - "integrity": "sha512-BzUrJBS9EcUb4cFol8r4W3v1cPsSyajLSthNkz5BxbpDcHN5tIrM10E2eNvfnvBn3DaT3DUgx0OpsBKkaOpanw==", + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.4.tgz", + "integrity": "sha512-E1b1lFFLvLgak2whF2xDBcOy6NLVGZBqqjJjsIhvopKfWWEi64pLVTWWehV8KlLerZkfNTA95sTe2OdJKm1OzQ==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "basic-ftp": "^5.0.2", "data-uri-to-buffer": "^6.0.2", - "debug": "^4.3.4", - "fs-extra": "^11.2.0" + "debug": "^4.3.4" }, "engines": { "node": ">= 14" @@ -7436,6 +8107,8 @@ "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==", "dev": true, + "optional": true, + "peer": true, "engines": { "node": ">= 14" } @@ -7454,10 +8127,11 @@ "integrity": "sha512-526NA+3EA+ztAQi0IZpSWiM0fyQXIp7IbRvfJ4wS/TjjQD0uv0fVybXwwqqSOlq33UckivI0yMDlVtboWm3k7A==" }, "node_modules/glob": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.0.tgz", - "integrity": "sha512-9UiX/Bl6J2yaBbxKoEBRm4Cipxgok8kQYcOPEhScPwebu2I0HoQOuYdIO6S3hLuWoZgpDpwQZMzTFxgpkyT76g==", + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.1.tgz", + "integrity": "sha512-zrQDm8XPnYEKawJScsnM0QzobJxlT/kHOOlRTio8IH/GrmxRE5fjllkzdaHclIuNjUQTJYH2xHNIGfdpJkDJUw==", "dev": true, + "license": "ISC", "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^4.0.1", @@ -7492,7 +8166,9 @@ "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 + "dev": true, + "optional": true, + "peer": true }, "node_modules/glob/node_modules/minimatch": { "version": "10.0.1", @@ -7509,55 +8185,26 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/global-dirs": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz", - "integrity": "sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==", - "dev": true, - "dependencies": { - "ini": "2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globals/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", "dev": true, "engines": { - "node": ">=10" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/globalthis": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", - "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", "dev": true, "dependencies": { - "define-properties": "^1.1.3" + "define-properties": "^1.2.1", + "gopd": "^1.0.1" }, "engines": { "node": ">= 0.4" @@ -7566,93 +8213,16 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/glsl-editor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/glsl-editor/-/glsl-editor-1.0.0.tgz", - "integrity": "sha512-eku+MXM8P3lXU8yhGdChkKdqorNrGmG+21YT/veoxODbqPEleBXOwXV76L6T9dnXXjt9elY7z9ctxBAyTLtOqg==", - "dependencies": { - "brfs": "^1.2.0", - "codemirror": "^4.5.0", - "element-size": "^1.1.1", - "events": "^1.0.2", - "inherits": "^2.0.1", - "insert-css": "^0.2.0", - "through2": "^0.6.1", - "xtend": "^4.0.0" - } - }, - "node_modules/glsl-editor/node_modules/codemirror": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-4.13.0.tgz", - "integrity": "sha512-+KOX1KjxkdzFJibjxg4u7r5uuLXG6M9cmVbio7x5qAyXcyT0Y437DPMP3AEmD1bGxoi+xFx21B84W0MfIuTfxQ==" - }, "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dev": true, - "dependencies": { - "get-intrinsic": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/got": { - "version": "12.6.1", - "resolved": "https://registry.npmjs.org/got/-/got-12.6.1.tgz", - "integrity": "sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ==", - "dev": true, - "dependencies": { - "@sindresorhus/is": "^5.2.0", - "@szmarczak/http-timer": "^5.0.1", - "cacheable-lookup": "^7.0.0", - "cacheable-request": "^10.2.8", - "decompress-response": "^6.0.0", - "form-data-encoder": "^2.1.2", - "get-stream": "^6.0.1", - "http2-wrapper": "^2.1.10", - "lowercase-keys": "^3.0.0", - "p-cancelable": "^3.0.0", - "responselike": "^3.0.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sindresorhus/got?sponsor=1" - } - }, - "node_modules/got/node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", "dev": true, "engines": { - "node": ">=10" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/graceful-fs": { @@ -7665,13 +8235,16 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", - "dev": true + "dev": true, + "optional": true, + "peer": 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 + "dev": true, + "license": "MIT" }, "node_modules/graphql": { "version": "16.9.0", @@ -7724,14 +8297,6 @@ "node": ">=6" } }, - "node_modules/has": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.4.tgz", - "integrity": "sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==", - "engines": { - "node": ">= 0.4.0" - } - }, "node_modules/has-bigints": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", @@ -7751,22 +8316,25 @@ } }, "node_modules/has-property-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", - "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "dev": true, "dependencies": { - "get-intrinsic": "^1.2.2" + "es-define-property": "^1.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/has-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", + "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", "dev": true, + "dependencies": { + "dunder-proto": "^1.0.0" + }, "engines": { "node": ">= 0.4" }, @@ -7775,9 +8343,9 @@ } }, "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "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" @@ -7787,12 +8355,12 @@ } }, "node_modules/has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "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.2" + "has-symbols": "^1.0.3" }, "engines": { "node": ">= 0.4" @@ -7802,9 +8370,10 @@ } }, "node_modules/hasown": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", - "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, "dependencies": { "function-bind": "^1.1.2" }, @@ -7840,11 +8409,15 @@ } }, "node_modules/html-encoding-sniffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", - "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", + "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==", + "dev": true, "dependencies": { - "whatwg-encoding": "^1.0.1" + "whatwg-encoding": "^3.1.1" + }, + "engines": { + "node": ">=18" } }, "node_modules/html-entities": { @@ -7869,93 +8442,61 @@ "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", "dev": true }, - "node_modules/html-minifier-terser": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", - "integrity": "sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==", + "node_modules/htmlfy": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/htmlfy/-/htmlfy-0.3.2.tgz", + "integrity": "sha512-FsxzfpeDYRqn1emox9VpxMPfGjADoUmmup8D604q497R0VNxiXs4ZZTN2QzkaMA5C9aHGUoe1iQRVSm+HK9xuA==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/http-assert": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/http-assert/-/http-assert-1.5.0.tgz", + "integrity": "sha512-uPpH7OKX4H25hBmU6G1jWNaqJGpTXxey+YOUizJUAgu0AjLUeC8D73hTrhvDS5D+GJN1DN1+hhc/eF/wpxtp0w==", "dev": true, "dependencies": { - "camel-case": "^4.1.2", - "clean-css": "^5.2.2", - "commander": "^8.3.0", - "he": "^1.2.0", - "param-case": "^3.0.4", - "relateurl": "^0.2.7", - "terser": "^5.10.0" - }, - "bin": { - "html-minifier-terser": "cli.js" + "deep-equal": "~1.0.1", + "http-errors": "~1.8.0" }, "engines": { - "node": ">=12" + "node": ">= 0.8" } }, - "node_modules/html-minifier-terser/node_modules/commander": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", - "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "node_modules/http-assert/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", "dev": true, "engines": { - "node": ">= 12" + "node": ">= 0.6" } }, - "node_modules/html-webpack-plugin": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.6.0.tgz", - "integrity": "sha512-iwaY4wzbe48AfKLZ/Cc8k0L+FKG6oSNRaZ8x5A/T/IVDGyXcbHncM9TdDa93wn0FsSm82FhTKW7f3vS61thXAw==", + "node_modules/http-assert/node_modules/http-errors": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", "dev": true, "dependencies": { - "@types/html-minifier-terser": "^6.0.0", - "html-minifier-terser": "^6.0.2", - "lodash": "^4.17.21", - "pretty-error": "^4.0.0", - "tapable": "^2.0.0" + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.1" }, "engines": { - "node": ">=10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/html-webpack-plugin" - }, - "peerDependencies": { - "@rspack/core": "0.x || 1.x", - "webpack": "^5.20.0" - }, - "peerDependenciesMeta": { - "@rspack/core": { - "optional": true - }, - "webpack": { - "optional": true - } + "node": ">= 0.6" } }, - "node_modules/htmlparser2": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", - "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", + "node_modules/http-assert/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, - "funding": [ - "https://github.com/fb55/htmlparser2?sponsor=1", - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.0.0", - "domutils": "^2.5.2", - "entities": "^2.0.0" + "engines": { + "node": ">= 0.6" } }, - "node_modules/http-cache-semantics": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", - "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", - "dev": true - }, "node_modules/http-deceiver": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", @@ -8012,9 +8553,9 @@ } }, "node_modules/http-proxy-middleware": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz", - "integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==", + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.7.tgz", + "integrity": "sha512-fgVY8AV7qU7z/MmXJ/rxwbrtQH4jBQ9m7kp3llF0liB7glmFeVZFBepQb32T3y8n8k2+AEYuMPCpinYW+/CuRA==", "dev": true, "dependencies": { "@types/http-proxy": "^1.17.8", @@ -8047,6 +8588,69 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/http-server": { + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/http-server/-/http-server-14.1.1.tgz", + "integrity": "sha512-+cbxadF40UXd9T01zUHgA+rlo2Bg1Srer4+B4NwIHdaGxAGGv59nYRnGGDJ9LBk7alpS0US+J+bLLdQOOkJq4A==", + "dev": true, + "dependencies": { + "basic-auth": "^2.0.1", + "chalk": "^4.1.2", + "corser": "^2.0.1", + "he": "^1.2.0", + "html-encoding-sniffer": "^3.0.0", + "http-proxy": "^1.18.1", + "mime": "^1.6.0", + "minimist": "^1.2.6", + "opener": "^1.5.1", + "portfinder": "^1.0.28", + "secure-compare": "3.0.1", + "union": "~0.5.0", + "url-join": "^4.0.1" + }, + "bin": { + "http-server": "bin/http-server" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/http-server/node_modules/html-encoding-sniffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", + "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==", + "dev": true, + "dependencies": { + "whatwg-encoding": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/http-server/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==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/http-server/node_modules/whatwg-encoding": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", + "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", + "dev": true, + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", @@ -8061,26 +8665,13 @@ "npm": ">=1.3.7" } }, - "node_modules/http2-wrapper": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.1.tgz", - "integrity": "sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==", - "dev": true, - "dependencies": { - "quick-lru": "^5.1.1", - "resolve-alpn": "^1.2.0" - }, - "engines": { - "node": ">=10.19.0" - } - }, "node_modules/https-proxy-agent": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", - "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", + "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, "dependencies": { - "agent-base": "^7.0.2", + "agent-base": "^7.1.2", "debug": "4" }, "engines": { @@ -8088,12 +8679,27 @@ } }, "node_modules/human-signals": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", - "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/humanize-number": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/humanize-number/-/humanize-number-0.0.2.tgz", + "integrity": "sha512-un3ZAcNQGI7RzaWGZzQDH47HETM4Wrj6z6E4TId8Yeq9w5ZKUVB1nrT2jwFheTUjEmqcgTjXDc959jum+ai1kQ==", + "dev": true + }, + "node_modules/hyperdyperid": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/hyperdyperid/-/hyperdyperid-1.2.0.tgz", + "integrity": "sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A==", "dev": true, "engines": { - "node": ">=16.17.0" + "node": ">=10.18" } }, "node_modules/iconv-lite": { @@ -8137,7 +8743,9 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "optional": true, + "peer": true }, "node_modules/ignore": { "version": "5.3.1", @@ -8159,166 +8767,298 @@ "xmldom": "^0.1.27" } }, - "node_modules/immediate": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", - "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==", - "dev": true - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" + "node_modules/ikonate/node_modules/acorn": { + "version": "5.7.4", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", + "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==", + "bin": { + "acorn": "bin/acorn" }, "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=0.4.0" } }, - "node_modules/import-local": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", - "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", - "dev": true, + "node_modules/ikonate/node_modules/cssstyle": { + "version": "0.2.37", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-0.2.37.tgz", + "integrity": "sha512-FUpKc+1FNBsHUr9IsfSGCovr8VuGOiiuzlgCyppKBjJi2jYTOFLN3oiiNRMIvYqbFzF38mqKj4BgcevzU5/kIA==", "dependencies": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - }, - "bin": { - "import-local-fixture": "fixtures/cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "cssom": "0.3.x" } }, - "node_modules/import-local/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, + "node_modules/ikonate/node_modules/data-urls": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.1.0.tgz", + "integrity": "sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==", "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" + "abab": "^2.0.0", + "whatwg-mimetype": "^2.2.0", + "whatwg-url": "^7.0.0" } }, - "node_modules/import-local/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, + "node_modules/ikonate/node_modules/data-urls/node_modules/abab": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", + "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", + "deprecated": "Use your platform's native atob() and btoa() methods instead" + }, + "node_modules/ikonate/node_modules/data-urls/node_modules/whatwg-url": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", + "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" } }, - "node_modules/import-local/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, + "node_modules/ikonate/node_modules/escodegen": { + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", + "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", "dependencies": { - "p-try": "^2.0.0" + "esprima": "^4.0.1", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" }, "engines": { - "node": ">=6" + "node": ">=4.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "optionalDependencies": { + "source-map": "~0.6.1" } }, - "node_modules/import-local/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, + "node_modules/ikonate/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "engines": { - "node": ">=8" + "node": ">=4.0" } }, - "node_modules/import-local/node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, + "node_modules/ikonate/node_modules/html-encoding-sniffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", + "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==", "dependencies": { - "find-up": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/import-meta-resolve": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.1.0.tgz", - "integrity": "sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==", - "dev": true, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "whatwg-encoding": "^1.0.1" } }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, + "node_modules/ikonate/node_modules/jsdom": { + "version": "11.10.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-11.10.0.tgz", + "integrity": "sha512-x5No5FpJgBg3j5aBwA8ka6eGuS5IxbC8FOkmyccKvObtFT0bDMict/LOxINZsZGZSfGdNomLZ/qRV9Bpq/GIBA==", + "dependencies": { + "abab": "^1.0.4", + "acorn": "^5.3.0", + "acorn-globals": "^4.1.0", + "array-equal": "^1.0.0", + "cssom": ">= 0.3.2 < 0.4.0", + "cssstyle": ">= 0.2.37 < 0.3.0", + "data-urls": "^1.0.0", + "domexception": "^1.0.0", + "escodegen": "^1.9.0", + "html-encoding-sniffer": "^1.0.2", + "left-pad": "^1.2.0", + "nwmatcher": "^1.4.3", + "parse5": "4.0.0", + "pn": "^1.1.0", + "request": "^2.83.0", + "request-promise-native": "^1.0.5", + "sax": "^1.2.4", + "symbol-tree": "^3.2.2", + "tough-cookie": "^2.3.3", + "w3c-hr-time": "^1.0.1", + "webidl-conversions": "^4.0.2", + "whatwg-encoding": "^1.0.3", + "whatwg-mimetype": "^2.1.0", + "whatwg-url": "^6.4.0", + "ws": "^4.0.0", + "xml-name-validator": "^3.0.0" + } + }, + "node_modules/ikonate/node_modules/levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", + "dependencies": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + }, "engines": { - "node": ">=0.8.19" + "node": ">= 0.8.0" } }, - "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==", + "node_modules/ikonate/node_modules/optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dependencies": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/ikonate/node_modules/parse5": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz", + "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==" + }, + "node_modules/ikonate/node_modules/prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/ikonate/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==" + }, + "node_modules/ikonate/node_modules/tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/ikonate/node_modules/tr46": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", + "integrity": "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/ikonate/node_modules/type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", + "dependencies": { + "prelude-ls": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/ikonate/node_modules/webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==" + }, + "node_modules/ikonate/node_modules/whatwg-encoding": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", + "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", + "dependencies": { + "iconv-lite": "0.4.24" + } + }, + "node_modules/ikonate/node_modules/whatwg-mimetype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", + "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==" + }, + "node_modules/ikonate/node_modules/whatwg-url": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-6.5.0.tgz", + "integrity": "sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ==", + "dependencies": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + }, + "node_modules/ikonate/node_modules/ws": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-4.1.0.tgz", + "integrity": "sha512-ZGh/8kF9rrRNffkLFV4AzhvooEclrOH0xaugmqGsIfFgOE/pIz4fMc4Ef+5HSQqTEug2S9JZIWDR47duDSLfaA==", + "dependencies": { + "async-limiter": "~1.0.0", + "safe-buffer": "~5.1.0" + } + }, + "node_modules/ikonate/node_modules/xml-name-validator": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", + "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==" + }, + "node_modules/immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, "dependencies": { - "once": "^1.3.0", - "wrappy": "1" + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "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/import-meta-resolve": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.1.0.tgz", + "integrity": "sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==", + "dev": true, + "optional": true, + "peer": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } }, - "node_modules/ini": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", - "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", + "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": ">=10" + "node": ">=0.8.19" } }, - "node_modules/insert-css": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/insert-css/-/insert-css-0.2.0.tgz", - "integrity": "sha512-tXSEsS2BJfEdtBuKzqfbbOijbWQC+y0i5pGd4OXNBauhWZ5lLNs7nb03tyONVuvwu6RXyQqWwqoRJV3jKR7+ag==" + "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/internal-slot": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.6.tgz", - "integrity": "sha512-Xj6dv+PsbtwyPpEflsejS+oIZxmMlV44zAhG479uYu89MsjcYOhCFnNyKrkJrihbsiasQyY0afoCl/9BLR65bg==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", + "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", "dev": true, "dependencies": { - "get-intrinsic": "^1.2.2", + "es-errors": "^1.3.0", "hasown": "^2.0.0", "side-channel": "^1.0.4" }, @@ -8340,6 +9080,8 @@ "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "jsbn": "1.1.0", "sprintf-js": "^1.1.3" @@ -8352,7 +9094,9 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/ipaddr.js": { "version": "2.1.0", @@ -8364,25 +9108,42 @@ } }, "node_modules/is-array-buffer": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", - "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", + "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", "dev": true, "dependencies": { "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.0", - "is-typed-array": "^1.1.10" + "get-intrinsic": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", "dev": true }, + "node_modules/is-async-function": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz", + "integrity": "sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-bigint": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", @@ -8428,6 +9189,15 @@ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" }, + "node_modules/is-bun-module": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/is-bun-module/-/is-bun-module-1.3.0.tgz", + "integrity": "sha512-DgXeu5UWI0IsMQundYb5UAOzm6G2eVnarJ0byP6Tm55iZNKceD59LNPA2L4VvsScTtHcw0yEkVwSf7PC+QoLSA==", + "dev": true, + "dependencies": { + "semver": "^7.6.3" + } + }, "node_modules/is-callable": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", @@ -8441,11 +9211,30 @@ } }, "node_modules/is-core-module": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", - "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", + "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", + "dev": true, "dependencies": { - "hasown": "^2.0.0" + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-view": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", + "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", + "dev": true, + "dependencies": { + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -8498,6 +9287,21 @@ "node": ">=0.10.0" } }, + "node_modules/is-finalizationregistry": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.0.tgz", + "integrity": "sha512-qfMdqbAQEwBw78ZyReKnlA8ezmPdb9BemzIIip/JkjaZUhitfXDkkr+3QTboW0JrSXT1QWyYShpvnNHGZ4c4yA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -8506,6 +9310,21 @@ "node": ">=8" } }, + "node_modules/is-generator-function": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -8536,38 +9355,22 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-installed-globally": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", - "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", "dev": true, - "dependencies": { - "global-dirs": "^3.0.0", - "is-path-inside": "^3.0.2" - }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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, - "engines": { - "node": ">=12" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-negative-zero": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", - "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", "dev": true, "engines": { "node": ">= 0.4" @@ -8618,20 +9421,13 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/is-plain-obj": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", "dev": true, + "optional": true, + "peer": true, "engines": { "node": ">=12" }, @@ -8651,14 +9447,22 @@ "node": ">=0.10.0" } }, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "dev": true + }, "node_modules/is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.0.tgz", + "integrity": "sha512-B6ohK4ZmoftlUe+uvenXSbPJFo6U37BH7oO1B3nQH8f/7h27N56s85MhUtbFJAziz5dcmuR3i8ovUl35zp8pFA==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "call-bind": "^1.0.7", + "gopd": "^1.1.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" }, "engines": { "node": ">= 0.4" @@ -8667,25 +9471,40 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-shared-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", - "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", + "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", "dev": true, "dependencies": { - "call-bind": "^1.0.2" + "call-bind": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", - "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -8722,12 +9541,12 @@ } }, "node_modules/is-typed-array": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", - "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", + "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", "dev": true, "dependencies": { - "which-typed-array": "^1.1.11" + "which-typed-array": "^1.1.14" }, "engines": { "node": ">= 0.4" @@ -8741,16 +9560,16 @@ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" }, - "node_modules/is-unicode-supported": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", - "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==", + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", "dev": true, "engines": { - "node": ">=12" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-weakref": { @@ -8765,6 +9584,22 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-weakset": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.3.tgz", + "integrity": "sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-whitespace": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/is-whitespace/-/is-whitespace-0.3.0.tgz", @@ -8791,7 +9626,8 @@ "node_modules/isarray": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==" + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true }, "node_modules/isexe": { "version": "2.0.0", @@ -8852,6 +9688,8 @@ "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "@types/node": "*", "merge-stream": "^2.0.0", @@ -8866,6 +9704,8 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -8972,149 +9812,56 @@ "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==" }, "node_modules/jsdom": { - "version": "11.10.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-11.10.0.tgz", - "integrity": "sha512-x5No5FpJgBg3j5aBwA8ka6eGuS5IxbC8FOkmyccKvObtFT0bDMict/LOxINZsZGZSfGdNomLZ/qRV9Bpq/GIBA==", - "dependencies": { - "abab": "^1.0.4", - "acorn": "^5.3.0", - "acorn-globals": "^4.1.0", - "array-equal": "^1.0.0", - "cssom": ">= 0.3.2 < 0.4.0", - "cssstyle": ">= 0.2.37 < 0.3.0", - "data-urls": "^1.0.0", - "domexception": "^1.0.0", - "escodegen": "^1.9.0", - "html-encoding-sniffer": "^1.0.2", - "left-pad": "^1.2.0", - "nwmatcher": "^1.4.3", - "parse5": "4.0.0", - "pn": "^1.1.0", - "request": "^2.83.0", - "request-promise-native": "^1.0.5", - "sax": "^1.2.4", - "symbol-tree": "^3.2.2", - "tough-cookie": "^2.3.3", - "w3c-hr-time": "^1.0.1", - "webidl-conversions": "^4.0.2", - "whatwg-encoding": "^1.0.3", - "whatwg-mimetype": "^2.1.0", - "whatwg-url": "^6.4.0", - "ws": "^4.0.0", - "xml-name-validator": "^3.0.0" - } - }, - "node_modules/jsdom/node_modules/acorn": { - "version": "5.7.4", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", - "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/jsdom/node_modules/escodegen": { - "version": "1.14.3", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", - "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-26.0.0.tgz", + "integrity": "sha512-BZYDGVAIriBWTpIxYzrXjv3E/4u8+/pSG5bQdIYCbNCGOvsPkDQfTVLAIXAf9ETdCpduCVTkDe2NNZ8NIwUVzw==", + "dev": true, + "license": "MIT", "dependencies": { - "esprima": "^4.0.1", - "estraverse": "^4.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1" - }, - "bin": { - "escodegen": "bin/escodegen.js", - "esgenerate": "bin/esgenerate.js" - }, - "engines": { - "node": ">=4.0" + "cssstyle": "^4.2.1", + "data-urls": "^5.0.0", + "decimal.js": "^10.4.3", + "form-data": "^4.0.1", + "html-encoding-sniffer": "^4.0.0", + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.6", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.16", + "parse5": "^7.2.1", + "rrweb-cssom": "^0.8.0", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^5.0.0", + "w3c-xmlserializer": "^5.0.0", + "webidl-conversions": "^7.0.0", + "whatwg-encoding": "^3.1.1", + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.1.0", + "ws": "^8.18.0", + "xml-name-validator": "^5.0.0" }, - "optionalDependencies": { - "source-map": "~0.6.1" - } - }, - "node_modules/jsdom/node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "engines": { - "node": ">=4.0" - } - }, - "node_modules/jsdom/node_modules/levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", - "dependencies": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" + "node": ">=18" }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/jsdom/node_modules/optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dependencies": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" + "peerDependencies": { + "canvas": "^3.0.0" }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/jsdom/node_modules/prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", - "engines": { - "node": ">= 0.8.0" + "peerDependenciesMeta": { + "canvas": { + "optional": true + } } }, - "node_modules/jsdom/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==" - }, "node_modules/jsdom/node_modules/tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "dependencies": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/jsdom/node_modules/type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.0.0.tgz", + "integrity": "sha512-FRKsF7cz96xIIeMZ82ehjC3xW2E+O2+v11udrDYewUbszngYhsGa8z6YUMMzO9QJZzzyd0nGGXnML/TReX6W8Q==", + "dev": true, "dependencies": { - "prelude-ls": "~1.1.2" + "tldts": "^6.1.32" }, "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/jsdom/node_modules/ws": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-4.1.0.tgz", - "integrity": "sha512-ZGh/8kF9rrRNffkLFV4AzhvooEclrOH0xaugmqGsIfFgOE/pIz4fMc4Ef+5HSQqTEug2S9JZIWDR47duDSLfaA==", - "dependencies": { - "async-limiter": "~1.0.0", - "safe-buffer": "~5.1.0" + "node": ">=16" } }, "node_modules/json-buffer": { @@ -9127,7 +9874,9 @@ "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 + "dev": true, + "optional": true, + "peer": true }, "node_modules/json-schema": { "version": "0.4.0", @@ -9150,39 +9899,22 @@ "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" }, - "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/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, - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } + "license": "MIT" }, "node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", "dev": true, - "dependencies": { - "universalify": "^2.0.0" - }, "optionalDependencies": { "graceful-fs": "^4.1.6" } }, - "node_modules/jsonfile/node_modules/universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "dev": true, - "engines": { - "node": ">= 10.0.0" - } - }, "node_modules/jsprim": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", @@ -9202,6 +9934,8 @@ "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "lie": "~3.3.0", "pako": "~1.0.2", @@ -9213,7 +9947,21 @@ "version": "1.0.11", "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/keygrip": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/keygrip/-/keygrip-1.1.0.tgz", + "integrity": "sha512-iYSchDJ+liQ8iwbSI2QqsQOvqv58eJCEanyJPJi+Khyu8smkcKSFUCbPwzFcL7YVtZ6eONjqRX/38caJ7QjRAQ==", + "dev": true, + "dependencies": { + "tsscmp": "1.0.6" + }, + "engines": { + "node": ">= 0.6" + } }, "node_modules/keyv": { "version": "4.5.4", @@ -9235,25 +9983,210 @@ "node": ">=0.10.0" } }, - "node_modules/ky": { - "version": "0.33.3", - "resolved": "https://registry.npmjs.org/ky/-/ky-0.33.3.tgz", - "integrity": "sha512-CasD9OCEQSFIam2U8efFK81Yeg8vNMTBUqtMOHlrcWQHqUX3HeCl9Dr31u4toV7emlH8Mymk5+9p0lL6mKb/Xw==", + "node_modules/koa": { + "version": "2.15.3", + "resolved": "https://registry.npmjs.org/koa/-/koa-2.15.3.tgz", + "integrity": "sha512-j/8tY9j5t+GVMLeioLaxweJiKUayFhlGqNTzf2ZGwL0ZCQijd2RLHK0SLW5Tsko8YyyqCZC2cojIb0/s62qTAg==", "dev": true, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sindresorhus/ky?sponsor=1" - } + "dependencies": { + "accepts": "^1.3.5", + "cache-content-type": "^1.0.0", + "content-disposition": "~0.5.2", + "content-type": "^1.0.4", + "cookies": "~0.9.0", + "debug": "^4.3.2", + "delegates": "^1.0.0", + "depd": "^2.0.0", + "destroy": "^1.0.4", + "encodeurl": "^1.0.2", + "escape-html": "^1.0.3", + "fresh": "~0.5.2", + "http-assert": "^1.3.0", + "http-errors": "^1.6.3", + "is-generator-function": "^1.0.7", + "koa-compose": "^4.1.0", + "koa-convert": "^2.0.0", + "on-finished": "^2.3.0", + "only": "~0.0.2", + "parseurl": "^1.3.2", + "statuses": "^1.5.0", + "type-is": "^1.6.16", + "vary": "^1.1.2" + }, + "engines": { + "node": "^4.8.4 || ^6.10.1 || ^7.10.1 || >= 8.1.4" + } + }, + "node_modules/koa-compose": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/koa-compose/-/koa-compose-4.1.0.tgz", + "integrity": "sha512-8ODW8TrDuMYvXRwra/Kh7/rJo9BtOfPc6qO8eAfC80CnCvSjSl0bkRM24X6/XBBEyj0v1nRUQ1LyOy3dbqOWXw==", + "dev": true }, - "node_modules/launch-editor": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.6.1.tgz", - "integrity": "sha512-eB/uXmFVpY4zezmGp5XtU21kwo7GBbKB+EQ+UZeWtGb9yAM5xt/Evk+lYH3eRNAtId+ej4u7TYPFZ07w4s7rRw==", + "node_modules/koa-convert": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/koa-convert/-/koa-convert-2.0.0.tgz", + "integrity": "sha512-asOvN6bFlSnxewce2e/DK3p4tltyfC4VM7ZwuTuepI7dEQVcvpyFuBcEARu1+Hxg8DIwytce2n7jrZtRlPrARA==", "dev": true, "dependencies": { - "picocolors": "^1.0.0", + "co": "^4.6.0", + "koa-compose": "^4.1.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/koa-logger": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/koa-logger/-/koa-logger-3.2.1.tgz", + "integrity": "sha512-MjlznhLLKy9+kG8nAXKJLM0/ClsQp/Or2vI3a5rbSQmgl8IJBQO0KI5FA70BvW+hqjtxjp49SpH2E7okS6NmHg==", + "dev": true, + "dependencies": { + "bytes": "^3.1.0", + "chalk": "^2.4.2", + "humanize-number": "0.0.2", + "passthrough-counter": "^1.0.0" + }, + "engines": { + "node": ">= 7.6.0" + } + }, + "node_modules/koa-logger/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/koa-logger/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": ">= 0.8" + } + }, + "node_modules/koa-logger/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/koa-logger/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/koa-logger/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/koa-logger/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/koa-logger/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/koa-logger/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/koa/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/koa/node_modules/http-errors": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", + "dev": true, + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/koa/node_modules/http-errors/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/koa/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/kuler": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", + "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==", + "dev": true + }, + "node_modules/launch-editor": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.6.1.tgz", + "integrity": "sha512-eB/uXmFVpY4zezmGp5XtU21kwo7GBbKB+EQ+UZeWtGb9yAM5xt/Evk+lYH3eRNAtId+ej4u7TYPFZ07w4s7rRw==", + "dev": true, + "dependencies": { + "picocolors": "^1.0.0", "shell-quote": "^1.8.1" } }, @@ -9262,6 +10195,8 @@ "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz", "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "readable-stream": "^2.0.5" }, @@ -9293,43 +10228,27 @@ "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "immediate": "~3.0.5" } }, - "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/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==", "dev": true, + "optional": true, + "peer": true, "engines": { "node": ">=6.11.5" } }, - "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/locate-app": { - "version": "2.4.21", - "resolved": "https://registry.npmjs.org/locate-app/-/locate-app-2.4.21.tgz", - "integrity": "sha512-ySSBwlUnVKoLgw39q8YaNtvklhaTMoVqBf2+CuY3hkOFuWubHAJ6NJuTjv+jfTV1FuOgKsigRdsYUIeVgKHvNA==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/locate-app/-/locate-app-2.5.0.tgz", + "integrity": "sha512-xIqbzPMBYArJRmPGUZD9CzV9wOqmVtQnaAn3wrj3s6WYW0bQvPI7x+sPYUGmDTYMHefVK//zc6HEYZ1qnxIK+Q==", "dev": true, "funding": [ { @@ -9341,19 +10260,23 @@ "url": "https://github.com/hejny/locate-app/blob/main/README.md#%EF%B8%8F-contributing" } ], + "optional": true, + "peer": true, "dependencies": { - "@promptbook/utils": "0.58.0", - "type-fest": "2.13.0", - "userhome": "1.0.0" + "@promptbook/utils": "0.69.5", + "type-fest": "4.26.0", + "userhome": "1.0.1" } }, "node_modules/locate-app/node_modules/type-fest": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.13.0.tgz", - "integrity": "sha512-lPfAm42MxE4/456+QyIaaVBAwgpJb6xZ8PRu09utnhPdWwcyj9vgy6Sq0Z5yNbJ21EdxB5dRU/Qg8bsyAMtlcw==", + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.26.0.tgz", + "integrity": "sha512-OduNjVJsFbifKb57UqZ2EMP1i4u64Xwow3NYXUtBbD4vIwJdQd4+xl8YDou1dlm4DVrtwT/7Ky8z8WyCULVfxw==", "dev": true, + "optional": true, + "peer": true, "engines": { - "node": ">=12.20" + "node": ">=16" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -9388,7 +10311,9 @@ "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/lodash.merge": { "version": "4.6.2", @@ -9401,51 +10326,38 @@ "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==" }, - "node_modules/lodash.truncate": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", - "dev": true - }, "node_modules/lodash.zip": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.zip/-/lodash.zip-4.2.0.tgz", "integrity": "sha512-C7IOaBBK/0gMORRBd8OETNx3kmOkgIWIPvyDpZSCTwUrpYmgZwJkjZeOD8ww4xbOUOs4/attY+pciKvadNfFbg==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, - "node_modules/log-symbols": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-5.1.0.tgz", - "integrity": "sha512-l0x2DvrW294C9uDCoQe1VSU4gf529FkSZ6leBl4TiqZH/e+0R7hSfHQBNut2mNygDgHwvYHfFLn6Oxb3VWj2rA==", + "node_modules/logform": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/logform/-/logform-2.7.0.tgz", + "integrity": "sha512-TFYA4jnP7PVbmlBIfhlSe+WKxs9dklXMTEGcBCIvLhE/Tn3H6Gk1norupVW7m5Cnd4bLcr08AytbyV/xj7f/kQ==", "dev": true, "dependencies": { - "chalk": "^5.0.0", - "is-unicode-supported": "^1.1.0" - }, - "engines": { - "node": ">=12" + "@colors/colors": "1.6.0", + "@types/triple-beam": "^1.3.2", + "fecha": "^4.2.0", + "ms": "^2.1.1", + "safe-stable-stringify": "^2.3.1", + "triple-beam": "^1.3.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/log-symbols/node_modules/chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", - "dev": true, "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "node": ">= 12.0.0" } }, "node_modules/loglevel": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.9.1.tgz", - "integrity": "sha512-hP3I3kCrDIMuRwAwHltphhDM1r8i55H33GgqjXbrisuJhF4kRhW1dNuxsRklp4bXl8DSdLaNLuiL4A/LWRfxvg==", + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.9.2.tgz", + "integrity": "sha512-HgMmCqIJSAKqo68l0rS2AanEWfkxaZ5wNiEFb5ggm08lDs9Xl2KxBlX3PTcaD2chBM1gXAYf491/M2Rv8Jwayg==", "dev": true, + "optional": true, + "peer": true, "engines": { "node": ">= 0.6.0" }, @@ -9458,37 +10370,16 @@ "version": "0.8.4", "resolved": "https://registry.npmjs.org/loglevel-plugin-prefix/-/loglevel-plugin-prefix-0.8.4.tgz", "integrity": "sha512-WpG9CcFAOjz/FtNht+QJeGpvVl/cdR6P0z6OcXSkr8wFJOsV2GRj2j10JLfjuA4aYkcKCNIEqRGCyTife9R8/g==", - "dev": true - }, - "node_modules/loupe": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.1.tgz", - "integrity": "sha512-edNu/8D5MKVfGVFRhFf8aAxiTM6Wumfz5XsaatSxlD3w4R1d/WEKUTydCdPGbl9K7QG/Ca3GnDV2sIKIpXRQcw==", - "dev": true, - "dependencies": { - "get-func-name": "^2.0.1" - } - }, - "node_modules/lower-case": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", - "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", "dev": true, - "dependencies": { - "tslib": "^2.0.3" - } + "optional": true, + "peer": true }, - "node_modules/lowercase-keys": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", - "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==", + "node_modules/loupe": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.2.tgz", + "integrity": "sha512-23I4pFZHmAemUnz8WZXbYRSKYj801VDaNv9ETuMh7IrMc7VuVVSo+Z9iLE3ni30+U48iDWfi30d3twAXBYmnCg==", "dev": true, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } + "license": "MIT" }, "node_modules/lru-cache": { "version": "11.0.0", @@ -9504,17 +10395,19 @@ "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", "dev": true, + "license": "MIT", "bin": { "lz-string": "bin/bin.js" } }, "node_modules/magic-string": { - "version": "0.30.10", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz", - "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==", + "version": "0.30.17", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", + "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", "dev": true, + "license": "MIT", "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15" + "@jridgewell/sourcemap-codec": "^1.5.0" } }, "node_modules/media-typer": { @@ -9527,11 +10420,14 @@ } }, "node_modules/memfs": { - "version": "4.7.7", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.7.7.tgz", - "integrity": "sha512-x9qc6k88J/VVwnfTkJV8pRRswJ2156Rc4w5rciRqKceFDZ0y1MqsNL9pkg5sE0GOcDzZYbonreALhaHzg1siFw==", + "version": "4.15.0", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.15.0.tgz", + "integrity": "sha512-q9MmZXd2rRWHS6GU3WEm3HyiXZyyoA1DqdOhEq0lxPBmKb5S7IAOwX0RgUCwJfqjelDCySa5h8ujOy24LqsWcw==", "dev": true, "dependencies": { + "@jsonjoy.com/json-pack": "^1.0.3", + "@jsonjoy.com/util": "^1.3.0", + "tree-dump": "^1.0.1", "tslib": "^2.0.0" }, "engines": { @@ -9543,25 +10439,12 @@ } }, "node_modules/merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", - "dev": true - }, - "node_modules/merge-source-map": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.0.4.tgz", - "integrity": "sha512-PGSmS0kfnTnMJCzJ16BLLCEe6oeYCamKFFdQKshi4BmM6FUwipjVOcBFGxqtQtirtAG4iZvHlqST9CpZKqlRjA==", - "dependencies": { - "source-map": "^0.5.6" - } - }, - "node_modules/merge-source-map/node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", - "engines": { - "node": ">=0.10.0" + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/merge-stream": { @@ -9589,12 +10472,12 @@ } }, "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, "dependencies": { - "braces": "^3.0.2", + "braces": "^3.0.3", "picomatch": "^2.3.1" }, "engines": { @@ -9641,115 +10524,31 @@ "node": ">=6" } }, - "node_modules/mimic-response": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz", - "integrity": "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==", - "dev": true, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } + "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/mini-css-extract-plugin": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.0.tgz", - "integrity": "sha512-Zs1YsZVfemekSZG+44vBsYTLQORkPMwnlv+aehcxK/NLKC+EGhDB39/YePYYqx/sTk6NnYpuqikhSn7+JIevTA==", - "dev": true, + "node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dependencies": { - "schema-utils": "^4.0.0", - "tapable": "^2.2.1" + "brace-expansion": "^2.0.1" }, "engines": { - "node": ">= 12.13.0" + "node": ">=16 || 14 >=14.17" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.0.0" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/mini-css-extract-plugin/node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "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": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/mini-css-extract-plugin/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/mini-css-extract-plugin/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/mini-css-extract-plugin/node_modules/schema-utils": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", - "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", - "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.9.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.1.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "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": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -9762,11 +10561,17 @@ "node": ">=16 || 14 >=14.17" } }, - "node_modules/mitt": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.0.tgz", - "integrity": "sha512-7dX2/10ITVyqh4aOSVI9gdape+t9l2/8QxHrFmUXu4EEUpdlxl6RudZUPZoc+zuY2hk1j7XxVroIVIan/pD/SQ==", - "dev": true + "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": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } }, "node_modules/mrmime": { "version": "2.0.0", @@ -9778,34 +10583,35 @@ } }, "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "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/msw": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/msw/-/msw-2.3.4.tgz", - "integrity": "sha512-sHMlwrajgmZSA2l1o7qRSe+azm/I+x9lvVVcOxAzi4vCtH8uVPJk1K5BQYDkzGl+tt0RvM9huEXXdeGrgcc79g==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/msw/-/msw-2.7.0.tgz", + "integrity": "sha512-BIodwZ19RWfCbYTxWTUfTXc+sg4OwjCAgxU1ZsgmggX/7S3LdUifsbUPJs61j0rWb19CZRGY5if77duhc0uXzw==", "dev": true, "hasInstallScript": true, "dependencies": { - "@bundled-es-modules/cookie": "^2.0.0", + "@bundled-es-modules/cookie": "^2.0.1", "@bundled-es-modules/statuses": "^1.0.1", "@bundled-es-modules/tough-cookie": "^0.1.6", - "@inquirer/confirm": "^3.0.0", - "@mswjs/interceptors": "^0.29.0", + "@inquirer/confirm": "^5.0.0", + "@mswjs/interceptors": "^0.37.0", + "@open-draft/deferred-promise": "^2.2.0", "@open-draft/until": "^2.1.0", "@types/cookie": "^0.6.0", "@types/statuses": "^2.0.4", - "chalk": "^4.1.2", "graphql": "^16.8.1", "headers-polyfill": "^4.0.2", "is-node-process": "^1.2.0", - "outvariant": "^1.4.2", - "path-to-regexp": "^6.2.0", + "outvariant": "^1.4.3", + "path-to-regexp": "^6.3.0", + "picocolors": "^1.1.1", "strict-event-emitter": "^0.5.1", - "type-fest": "^4.9.0", + "type-fest": "^4.26.1", "yargs": "^17.7.2" }, "bin": { @@ -9818,7 +10624,7 @@ "url": "https://github.com/sponsors/mswjs" }, "peerDependencies": { - "typescript": ">= 4.7.x" + "typescript": ">= 4.8.x" }, "peerDependenciesMeta": { "typescript": { @@ -9826,16 +10632,10 @@ } } }, - "node_modules/msw/node_modules/path-to-regexp": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.2.tgz", - "integrity": "sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==", - "dev": true - }, "node_modules/msw/node_modules/type-fest": { - "version": "4.23.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.23.0.tgz", - "integrity": "sha512-ZiBujro2ohr5+Z/hZWHESLz3g08BBdrdLMieYFULJO+tWc437sn8kQsWLJoZErY8alNhxre9K4p3GURAG11n+w==", + "version": "4.30.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.30.0.tgz", + "integrity": "sha512-G6zXWS1dLj6eagy6sVhOMQiLtJdxQBHIA9Z6HFUNLOlr6MFOgzV8wvmidtPONfPtEUv0uZsy77XJNzTAfwPDaA==", "dev": true, "engines": { "node": ">=16" @@ -9858,18 +10658,18 @@ } }, "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==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-2.0.0.tgz", + "integrity": "sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==", "dev": true, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "version": "3.3.8", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", + "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==", "dev": true, "funding": [ { @@ -9903,13 +10703,17 @@ "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/netmask": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==", "dev": true, + "optional": true, + "peer": true, "engines": { "node": ">= 0.4.0" } @@ -9922,16 +10726,6 @@ "fflate": "*" } }, - "node_modules/no-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", - "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", - "dev": true, - "dependencies": { - "lower-case": "^2.0.2", - "tslib": "^2.0.3" - } - }, "node_modules/node-domexception": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", @@ -9947,6 +10741,8 @@ "url": "https://paypal.me/jimmywarting" } ], + "optional": true, + "peer": true, "engines": { "node": ">=10.5.0" } @@ -9956,6 +10752,8 @@ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "data-uri-to-buffer": "^4.0.0", "fetch-blob": "^3.1.4", @@ -9979,10 +10777,12 @@ } }, "node_modules/node-releases": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", - "dev": true + "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, + "optional": true, + "peer": true }, "node_modules/nopt": { "version": "7.2.0", @@ -10007,18 +10807,6 @@ "node": ">=0.10.0" } }, - "node_modules/normalize-url": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.1.tgz", - "integrity": "sha512-IO9QvjUMWxPQQhs60oOu10CRkWCiZzSUkzbXGGV9pviYl1fXYcvkzQ5jV9z8Y6un8ARoVRl4EtC6v6jNqbaJ/w==", - "dev": true, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/npm-run-path": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", @@ -10036,6 +10824,8 @@ "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "boolbase": "^1.0.0" }, @@ -10052,11 +10842,51 @@ "fflate": "^0.8.0" } }, + "node_modules/nunjucks": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/nunjucks/-/nunjucks-3.2.4.tgz", + "integrity": "sha512-26XRV6BhkgK0VOxfbU5cQI+ICFUtMLixv1noZn1tGU38kQH5A5nmmbk/O45xdyBhD1esk47nKrY0mvQpZIhRjQ==", + "dev": true, + "dependencies": { + "a-sync-waterfall": "^1.0.0", + "asap": "^2.0.3", + "commander": "^5.1.0" + }, + "bin": { + "nunjucks-precompile": "bin/precompile" + }, + "engines": { + "node": ">= 6.9.0" + }, + "peerDependencies": { + "chokidar": "^3.3.0" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/nunjucks/node_modules/commander": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, "node_modules/nwmatcher": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/nwmatcher/-/nwmatcher-1.4.4.tgz", "integrity": "sha512-3iuY4N5dhgMpCUrOVnuAdGrgxVqV2cJpM+XNccjR2DKOB1RUP0aA+wGXEiNziG/UKboFyGBIoKOaNlJxx8bciQ==" }, + "node_modules/nwsapi": { + "version": "2.2.16", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.16.tgz", + "integrity": "sha512-F1I/bimDpj3ncaNDhfyMWuFqmQDBwDB0Fogc2qpL3BWvkQteFD/8BzWuIRl83rq0DXfm8SGt/HFhLXZyljTXcQ==", + "dev": true + }, "node_modules/oauth-sign": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", @@ -10065,20 +10895,14 @@ "node": "*" } }, - "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.1", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", - "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "version": "1.13.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz", + "integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==", "dev": true, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -10111,14 +10935,15 @@ } }, "node_modules/object.fromentries": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.7.tgz", - "integrity": "sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==", + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -10128,26 +10953,28 @@ } }, "node_modules/object.groupby": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.1.tgz", - "integrity": "sha512-HqaQtqLnp/8Bn4GL16cj+CUYbnpe1bh0TtEaWvybszDG4tgxCJuRpV8VGuvNaI1fAnI4lUJzDG55MXcOH4JZcQ==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", + "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "get-intrinsic": "^1.2.1" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2" + }, + "engines": { + "node": ">= 0.4" } }, "node_modules/object.values": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.7.tgz", - "integrity": "sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", + "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -10188,10 +11015,21 @@ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "wrappy": "1" } }, + "node_modules/one-time": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz", + "integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==", + "dev": true, + "dependencies": { + "fn.name": "1.x.x" + } + }, "node_modules/onetime": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", @@ -10207,6 +11045,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/only": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/only/-/only-0.0.2.tgz", + "integrity": "sha512-Fvw+Jemq5fjjyWz6CpKx6w9s7xxqo3+JCyM0WXWeCSOboZ8ABkyvP8ID4CZuChA/wxSx+XSJmdOm8rGVyJ1hdQ==", + "dev": true + }, "node_modules/open": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/open/-/open-10.1.0.tgz", @@ -10251,81 +11095,37 @@ "node": ">= 0.8.0" } }, - "node_modules/ora": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/ora/-/ora-6.3.1.tgz", - "integrity": "sha512-ERAyNnZOfqM+Ao3RAvIXkYh5joP220yf59gVe2X/cI6SiCxIdi4c9HZKZD8R6q/RDXEje1THBju6iExiSsgJaQ==", - "dev": true, - "dependencies": { - "chalk": "^5.0.0", - "cli-cursor": "^4.0.0", - "cli-spinners": "^2.6.1", - "is-interactive": "^2.0.0", - "is-unicode-supported": "^1.1.0", - "log-symbols": "^5.1.0", - "stdin-discarder": "^0.1.0", - "strip-ansi": "^7.0.1", - "wcwidth": "^1.0.1" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ora/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/ora/node_modules/chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", - "dev": true, - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/ora/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==", - "dev": true, - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, "node_modules/outvariant": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/outvariant/-/outvariant-1.4.3.tgz", "integrity": "sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA==", "dev": true }, - "node_modules/p-cancelable": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", - "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==", + "node_modules/oxlint": { + "version": "0.15.7", + "resolved": "https://registry.npmjs.org/oxlint/-/oxlint-0.15.7.tgz", + "integrity": "sha512-ECx9retPd7Rvq62TasGODyQ4mrMtqBCCB18xOYGiAf8PP61snHaokLeTWQFf+pTURWpJZ9pIi2pMIDKh2P2SpQ==", "dev": true, + "license": "MIT", + "bin": { + "oxc_language_server": "bin/oxc_language_server", + "oxlint": "bin/oxlint" + }, "engines": { - "node": ">=12.20" + "node": ">=14.*" + }, + "funding": { + "url": "https://github.com/sponsors/Boshen" + }, + "optionalDependencies": { + "@oxlint/darwin-arm64": "0.15.7", + "@oxlint/darwin-x64": "0.15.7", + "@oxlint/linux-arm64-gnu": "0.15.7", + "@oxlint/linux-arm64-musl": "0.15.7", + "@oxlint/linux-x64-gnu": "0.15.7", + "@oxlint/linux-x64-musl": "0.15.7", + "@oxlint/win32-arm64": "0.15.7", + "@oxlint/win32-x64": "0.15.7" } }, "node_modules/p-limit": { @@ -10358,46 +11158,22 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/p-retry": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-6.2.0.tgz", - "integrity": "sha512-JA6nkq6hKyWLLasXQXUrO4z8BUZGUt/LjlJxx8Gb2+2ntodU/SS63YZ8b0LUTbQ8ZB9iwOfhEPhg4ykKnn2KsA==", - "dev": true, - "dependencies": { - "@types/retry": "0.12.2", - "is-network-error": "^1.0.0", - "retry": "^0.13.1" - }, - "engines": { - "node": ">=16.17" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/pac-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.0.2.tgz", - "integrity": "sha512-BFi3vZnO9X5Qt6NRz7ZOaPja3ic0PhlsmCRYLOpN11+mWBCR6XJDqW5RF3j8jm4WGGQZtBA+bTfxYzeKW73eHg==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.1.0.tgz", + "integrity": "sha512-Z5FnLVVZSnX7WjBg0mhDtydeRZ1xMcATZThjySQUHqr+0ksP8kqaw23fNKkaaN/Z8gwLUs/W7xdl0I75eP2Xyw==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "@tootallnate/quickjs-emscripten": "^0.23.0", - "agent-base": "^7.0.2", + "agent-base": "^7.1.2", "debug": "^4.3.4", "get-uri": "^6.0.1", "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.5", + "https-proxy-agent": "^7.0.6", "pac-resolver": "^7.0.1", - "socks-proxy-agent": "^8.0.4" + "socks-proxy-agent": "^8.0.5" }, "engines": { "node": ">= 14" @@ -10408,6 +11184,8 @@ "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz", "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "degenerator": "^5.0.0", "netmask": "^2.0.2" @@ -10421,21 +11199,6 @@ "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==" }, - "node_modules/pako": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz", - "integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==" - }, - "node_modules/param-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", - "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", - "dev": true, - "dependencies": { - "dot-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -10448,28 +11211,63 @@ "node": ">=6" } }, - "node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "node_modules/parse5": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.2.1.tgz", + "integrity": "sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==", "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" - }, - "engines": { - "node": ">=8" + "entities": "^4.5.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/inikulin/parse5?sponsor=1" } }, - "node_modules/parse5": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz", - "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==" + "node_modules/parse5-htmlparser2-tree-adapter": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz", + "integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "domhandler": "^5.0.3", + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-htmlparser2-tree-adapter/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, + "optional": true, + "peer": true, + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/parse5-parser-stream": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz", + "integrity": "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } }, "node_modules/parseurl": { "version": "1.3.3", @@ -10480,15 +11278,11 @@ "node": ">= 0.8" } }, - "node_modules/pascal-case": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", - "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", - "dev": true, - "dependencies": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } + "node_modules/passthrough-counter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/passthrough-counter/-/passthrough-counter-1.0.0.tgz", + "integrity": "sha512-Wy8PXTLqPAN0oEgBrlnsXPMww3SYJ44tQ8aVrGAI4h4JZYCS0oYqsPqtPR8OhJpv6qFbpbB7XAn0liKV7EXubA==", + "dev": true }, "node_modules/path-exists": { "version": "4.0.0", @@ -10499,15 +11293,6 @@ "node": ">=8" } }, - "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, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", @@ -10519,7 +11304,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==" + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true }, "node_modules/path-scurry": { "version": "2.0.0", @@ -10538,31 +11324,24 @@ } }, "node_modules/path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz", + "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==", "dev": true }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/pathe": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", - "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", - "dev": true + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.2.tgz", + "integrity": "sha512-15Ztpk+nov8DR524R4BF7uEuzESgzUEAV4Ah7CUMNGXdE5ELuvxElxGXndBl32vMSsWa1jpNf22Z+Er3sKwq+w==", + "dev": true, + "license": "MIT" }, "node_modules/pathval": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.0.tgz", "integrity": "sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 14.16" } @@ -10571,7 +11350,8 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/performance-now": { "version": "2.1.0", @@ -10579,9 +11359,9 @@ "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==" }, "node_modules/picocolors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "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": { @@ -10596,112 +11376,103 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "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/playwright": { + "version": "1.49.1", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.49.1.tgz", + "integrity": "sha512-VYL8zLoNTBxVOrJBbDuRgDWa3i+mfQgDTrL8Ah9QXZ7ax4Dsj0MSq5bYgytRnDVVe+njoKnfsYkH3HzqVj5UZA==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "find-up": "^6.3.0" + "playwright-core": "1.49.1" + }, + "bin": { + "playwright": "cli.js" }, "engines": { - "node": ">=14.16" + "node": ">=18" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "optionalDependencies": { + "fsevents": "2.3.2" } }, - "node_modules/pkg-dir/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/playwright-core": { + "version": "1.49.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.49.1.tgz", + "integrity": "sha512-BzmpVcs4kE2CH15rWfzpjzVGhWERJfmnXmniSyKeRZUs9Ws65m+RGIi7mjJK/euCegfn3i7jvqWeWyHe9y3Vgg==", "dev": true, - "dependencies": { - "locate-path": "^7.1.0", - "path-exists": "^5.0.0" + "license": "Apache-2.0", + "bin": { + "playwright-core": "cli.js" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=18" } }, - "node_modules/pkg-dir/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/playwright/node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", "dev": true, - "dependencies": { - "p-locate": "^6.0.0" - }, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "node_modules/pkg-dir/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/pn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz", + "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==" + }, + "node_modules/portfinder": { + "version": "1.0.32", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.32.tgz", + "integrity": "sha512-on2ZJVVDXRADWE6jnQaX0ioEylzgBpQk8r55NE4wjXW1ZxO+BgDlY6DXwj20i0V8eB4SenDQ00WEaxfiIQPcxg==", "dev": true, "dependencies": { - "yocto-queue": "^1.0.0" + "async": "^2.6.4", + "debug": "^3.2.7", + "mkdirp": "^0.5.6" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 0.12.0" } }, - "node_modules/pkg-dir/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/portfinder/node_modules/async": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", + "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", "dev": true, "dependencies": { - "p-limit": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "lodash": "^4.17.14" } }, - "node_modules/pkg-dir/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/portfinder/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "dependencies": { + "ms": "^2.1.1" } }, - "node_modules/pkg-dir/node_modules/yocto-queue": { + "node_modules/possible-typed-array-names": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", - "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", "dev": true, "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 0.4" } }, - "node_modules/pn": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz", - "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==" - }, "node_modules/postcss": { - "version": "8.4.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz", - "integrity": "sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==", + "version": "8.4.49", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz", + "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==", "dev": true, "funding": [ { @@ -10719,8 +11490,8 @@ ], "dependencies": { "nanoid": "^3.3.7", - "picocolors": "^1.0.1", - "source-map-js": "^1.2.0" + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" }, "engines": { "node": "^10 || ^12 || >=14" @@ -10814,9 +11585,9 @@ } }, "node_modules/prettier": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", - "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.4.2.tgz", + "integrity": "sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==", "dev": true, "bin": { "prettier": "bin/prettier.cjs" @@ -10841,21 +11612,12 @@ "node": ">=0.10.0" } }, - "node_modules/pretty-error": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz", - "integrity": "sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==", - "dev": true, - "dependencies": { - "lodash": "^4.17.20", - "renderkid": "^3.0.0" - } - }, "node_modules/pretty-format": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1", "ansi-styles": "^5.0.0", @@ -10870,6 +11632,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -10882,6 +11645,8 @@ "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", "dev": true, + "optional": true, + "peer": true, "engines": { "node": ">= 0.6.0" } @@ -10889,13 +11654,16 @@ "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==" + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true }, "node_modules/progress": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", "dev": true, + "optional": true, + "peer": true, "engines": { "node": ">=0.4.0" } @@ -10928,19 +11696,21 @@ } }, "node_modules/proxy-agent": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.4.0.tgz", - "integrity": "sha512-u0piLU+nCOHMgGjRbimiXmA9kM/L9EHh3zL81xCdp7m+Y2pHIsnmbdDoEDoAz5geaonNR6q6+yOPQs6n4T6sBQ==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.5.0.tgz", + "integrity": "sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A==", "dev": true, + "optional": true, + "peer": true, "dependencies": { - "agent-base": "^7.0.2", + "agent-base": "^7.1.2", "debug": "^4.3.4", "http-proxy-agent": "^7.0.1", - "https-proxy-agent": "^7.0.3", + "https-proxy-agent": "^7.0.6", "lru-cache": "^7.14.1", - "pac-proxy-agent": "^7.0.1", + "pac-proxy-agent": "^7.1.0", "proxy-from-env": "^1.1.0", - "socks-proxy-agent": "^8.0.2" + "socks-proxy-agent": "^8.0.5" }, "engines": { "node": ">= 14" @@ -10951,6 +11721,8 @@ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", "dev": true, + "optional": true, + "peer": true, "engines": { "node": ">=12" } @@ -10959,7 +11731,9 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/psl": { "version": "1.9.0", @@ -10967,10 +11741,12 @@ "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==" }, "node_modules/pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", + "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -10984,58 +11760,6 @@ "node": ">=6" } }, - "node_modules/puppeteer-core": { - "version": "20.9.0", - "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-20.9.0.tgz", - "integrity": "sha512-H9fYZQzMTRrkboEfPmf7m3CLDN6JvbxXA3qTtS+dFt27tR+CsFHzPsT6pzp6lYL6bJbAPaR0HaPO6uSi+F94Pg==", - "dev": true, - "dependencies": { - "@puppeteer/browsers": "1.4.6", - "chromium-bidi": "0.4.16", - "cross-fetch": "4.0.0", - "debug": "4.3.4", - "devtools-protocol": "0.0.1147663", - "ws": "8.13.0" - }, - "engines": { - "node": ">=16.3.0" - }, - "peerDependencies": { - "typescript": ">= 4.7.4" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/puppeteer-core/node_modules/devtools-protocol": { - "version": "0.0.1147663", - "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1147663.tgz", - "integrity": "sha512-hyWmRrexdhbZ1tcJUGpO95ivbRhWXz++F4Ko+n21AY5PNln2ovoJw+8ZMNDTtip+CNFQfrtLVh/w4009dXO/eQ==", - "dev": true - }, - "node_modules/puppeteer-core/node_modules/ws": { - "version": "8.13.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", - "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", - "dev": true, - "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_modules/qs": { "version": "6.5.3", "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", @@ -11048,7 +11772,9 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/query-selector-shadow-dom/-/query-selector-shadow-dom-1.0.1.tgz", "integrity": "sha512-lT5yCqEBgfoMYpf3F2xQRK7zEr1rhIIZuceDK6+xRkJQ4NMbHTwXqk4NkwDwQMNqXgG9r9fyHnzwNVs6zV5KRw==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/querystringify": { "version": "2.2.0", @@ -11080,47 +11806,17 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==", - "dev": true - }, - "node_modules/quick-lru": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", - "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/quote-stream": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/quote-stream/-/quote-stream-1.0.2.tgz", - "integrity": "sha512-kKr2uQ2AokadPjvTyKJQad9xELbZwYzWlNfI3Uz2j/ib5u6H9lDP7fUUR//rMycd0gv4Z5P1qXMfXR8YpIxrjQ==", - "dependencies": { - "buffer-equal": "0.0.1", - "minimist": "^1.1.3", - "through2": "^2.0.0" - }, - "bin": { - "quote-stream": "bin/cmd.js" - } - }, - "node_modules/quote-stream/node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } + "optional": true, + "peer": true }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "safe-buffer": "^5.1.0" } @@ -11162,12 +11858,14 @@ "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true + "dev": true, + "license": "MIT" }, "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, "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -11181,18 +11879,22 @@ "node_modules/readable-stream/node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true }, "node_modules/readable-stream/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==" + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true }, "node_modules/readdir-glob": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.3.tgz", "integrity": "sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "minimatch": "^5.1.0" } @@ -11202,6 +11904,8 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "brace-expansion": "^2.0.1" }, @@ -11233,21 +11937,20 @@ "node": ">= 10.13.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/regexp.prototype.flags": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz", - "integrity": "sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==", + "node_modules/reflect.getprototypeof": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.8.tgz", + "integrity": "sha512-B5dj6usc5dkk8uFliwjwDHM8To5/QwdKz9JcBZ8Ic4G1f0YmeeJTtE/ZTdgRFPAfxZFiUaPhZ1Jcs4qeagItGQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "set-function-name": "^2.0.0" + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "dunder-proto": "^1.0.0", + "es-abstract": "^1.23.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "gopd": "^1.2.0", + "which-builtin-type": "^1.2.0" }, "engines": { "node": ">= 0.4" @@ -11256,26 +11959,29 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/relateurl": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", - "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==", + "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, - "engines": { - "node": ">= 0.10" - } + "license": "MIT" }, - "node_modules/renderkid": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz", - "integrity": "sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==", + "node_modules/regexp.prototype.flags": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.3.tgz", + "integrity": "sha512-vqlC04+RQoFalODCbCumG2xIOvapzVMHwsyIGM/SIE8fRhFFsXeH8/QQ+s0T0kDAhKc4k30s73/0ydkHQz6HlQ==", "dev": true, "dependencies": { - "css-select": "^4.1.3", - "dom-converter": "^0.2.0", - "htmlparser2": "^6.1.0", - "lodash": "^4.17.21", - "strip-ansi": "^6.0.1" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/request": { @@ -11405,6 +12111,7 @@ "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", @@ -11417,40 +12124,13 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/resolve-alpn": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", - "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", - "dev": true - }, - "node_modules/resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "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": { - "resolve-from": "^5.0.0" - }, "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-cwd/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "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, - "engines": { - "node": ">=4" + "node": ">=4" } }, "node_modules/resolve-pkg-maps": { @@ -11462,26 +12142,13 @@ "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" } }, - "node_modules/responselike": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-3.0.0.tgz", - "integrity": "sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==", - "dev": true, - "dependencies": { - "lowercase-keys": "^3.0.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/resq": { "version": "1.11.0", "resolved": "https://registry.npmjs.org/resq/-/resq-1.11.0.tgz", "integrity": "sha512-G10EBz+zAAy3zUd/CDoBbXRL6ia9kOo3xRHrMDsHljI0GDkhYlyjwoCx5+3eCC4swi1uCoZQhskuJkj7Gp57Bw==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "fast-deep-equal": "^2.0.1" } @@ -11490,29 +12157,9 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", "integrity": "sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w==", - "dev": true - }, - "node_modules/restore-cursor": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", - "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", "dev": true, - "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/restore-cursor/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 + "optional": true, + "peer": true }, "node_modules/retry": { "version": "0.13.1", @@ -11537,72 +12184,90 @@ "version": "0.2.5", "resolved": "https://registry.npmjs.org/rgb2hex/-/rgb2hex-0.2.5.tgz", "integrity": "sha512-22MOP1Rh7sAo1BZpDG6R5RFYzR2lYEgwq7HEmyW2qcsOqR2lQKmn+O//xV3YG/0rrhMC6KVX2hU+ZXuaw9a5bw==", - "dev": true + "dev": true, + "optional": true, + "peer": 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==", + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz", + "integrity": "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==", "dev": true, "dependencies": { - "glob": "^7.1.3" + "glob": "^10.3.7" }, "bin": { - "rimraf": "bin.js" + "rimraf": "dist/esm/bin.mjs" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/rimraf/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "node_modules/rimraf/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": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "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" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/rimraf/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "node_modules/rimraf/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==", "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" - }, - "engines": { - "node": "*" + "@isaacs/cliui": "^8.0.2" }, "funding": { "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" } }, - "node_modules/rimraf/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/rimraf/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/rimraf/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==", "dev": true, "dependencies": { - "brace-expansion": "^1.1.7" + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" }, "engines": { - "node": "*" + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/rollup": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.19.0.tgz", - "integrity": "sha512-5r7EYSQIowHsK4eTZ0Y81qpZuJz+MUuYeqmmYmRMl1nwhdmbiYqt5jwzf6u7wyOzJgYqtCRMtVRKOtHANBz7rA==", + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.30.1.tgz", + "integrity": "sha512-mlJ4glW020fPuLi7DkM/lN97mYEZGWeqBnrljzN0gs7GLctqX3lNWxKQ7Gl712UAX+6fog/L3jh4gb7R6aVi3w==", "dev": true, + "license": "MIT", "dependencies": { - "@types/estree": "1.0.5" + "@types/estree": "1.0.6" }, "bin": { "rollup": "dist/bin/rollup" @@ -11612,25 +12277,35 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.19.0", - "@rollup/rollup-android-arm64": "4.19.0", - "@rollup/rollup-darwin-arm64": "4.19.0", - "@rollup/rollup-darwin-x64": "4.19.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.19.0", - "@rollup/rollup-linux-arm-musleabihf": "4.19.0", - "@rollup/rollup-linux-arm64-gnu": "4.19.0", - "@rollup/rollup-linux-arm64-musl": "4.19.0", - "@rollup/rollup-linux-powerpc64le-gnu": "4.19.0", - "@rollup/rollup-linux-riscv64-gnu": "4.19.0", - "@rollup/rollup-linux-s390x-gnu": "4.19.0", - "@rollup/rollup-linux-x64-gnu": "4.19.0", - "@rollup/rollup-linux-x64-musl": "4.19.0", - "@rollup/rollup-win32-arm64-msvc": "4.19.0", - "@rollup/rollup-win32-ia32-msvc": "4.19.0", - "@rollup/rollup-win32-x64-msvc": "4.19.0", + "@rollup/rollup-android-arm-eabi": "4.30.1", + "@rollup/rollup-android-arm64": "4.30.1", + "@rollup/rollup-darwin-arm64": "4.30.1", + "@rollup/rollup-darwin-x64": "4.30.1", + "@rollup/rollup-freebsd-arm64": "4.30.1", + "@rollup/rollup-freebsd-x64": "4.30.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.30.1", + "@rollup/rollup-linux-arm-musleabihf": "4.30.1", + "@rollup/rollup-linux-arm64-gnu": "4.30.1", + "@rollup/rollup-linux-arm64-musl": "4.30.1", + "@rollup/rollup-linux-loongarch64-gnu": "4.30.1", + "@rollup/rollup-linux-powerpc64le-gnu": "4.30.1", + "@rollup/rollup-linux-riscv64-gnu": "4.30.1", + "@rollup/rollup-linux-s390x-gnu": "4.30.1", + "@rollup/rollup-linux-x64-gnu": "4.30.1", + "@rollup/rollup-linux-x64-musl": "4.30.1", + "@rollup/rollup-win32-arm64-msvc": "4.30.1", + "@rollup/rollup-win32-ia32-msvc": "4.30.1", + "@rollup/rollup-win32-x64-msvc": "4.30.1", "fsevents": "~2.3.2" } }, + "node_modules/rrweb-cssom": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.8.0.tgz", + "integrity": "sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==", + "dev": true, + "license": "MIT" + }, "node_modules/run-applescript": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.0.0.tgz", @@ -11666,20 +12341,72 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/s3rver": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/s3rver/-/s3rver-3.7.1.tgz", + "integrity": "sha512-H9KIX6n8NqcfoE4ziFNbQASBQfjcNJgb+3wbT9L5iotEqfOncFO1c38cfJSFSo7xXTu1zM9HA6t2u9xKNlYRaA==", + "dev": true, + "dependencies": { + "@koa/router": "^9.0.0", + "busboy": "^0.3.1", + "commander": "^5.0.0", + "fast-xml-parser": "^3.12.19", + "fs-extra": "^8.0.0", + "he": "^1.2.0", + "koa": "^2.7.0", + "koa-logger": "^3.2.0", + "lodash": "^4.17.5", + "statuses": "^2.0.0", + "winston": "^3.0.0" + }, + "bin": { + "s3rver": "bin/s3rver.js" + }, + "engines": { + "node": ">=8.3.0" + } + }, + "node_modules/s3rver/node_modules/commander": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/s3rver/node_modules/fast-xml-parser": { + "version": "3.21.1", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-3.21.1.tgz", + "integrity": "sha512-FTFVjYoBOZTJekiUsawGsSYV9QL0A+zDYCRj7y34IO6Jg+2IMYEtQa+bbictpdpV8dHxXywqU7C0gRDEOFtBFg==", + "dev": true, + "dependencies": { + "strnum": "^1.0.4" + }, + "bin": { + "xml2js": "cli.js" + }, + "funding": { + "type": "paypal", + "url": "https://paypal.me/naturalintelligence" + } + }, "node_modules/safaridriver": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/safaridriver/-/safaridriver-0.1.2.tgz", "integrity": "sha512-4R309+gWflJktzPXBQCobbWEHlzC4aK3a+Ov3tz2Ib2aBxiwd11phkdIBH1l0EO22x24CJMUQkpKFumRriCSRg==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/safe-array-concat": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.0.tgz", - "integrity": "sha512-ZdQ0Jeb9Ofti4hbt5lX3T2JcAamT9hfzYU1MNB+z/jaEbB6wfFfPIR/zEORmZqobkCCJhSjodobH6WHNmJ97dg==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", + "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", "dev": true, "dependencies": { - "call-bind": "^1.0.5", - "get-intrinsic": "^1.2.2", + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4", "has-symbols": "^1.0.3", "isarray": "^2.0.5" }, @@ -11710,13 +12437,13 @@ ] }, "node_modules/safe-regex-test": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.2.tgz", - "integrity": "sha512-83S9w6eFq12BBIJYvjMux6/dkirb8+4zJRA9cxNBVb7Wq5fJBW+Xze48WqR8pxua7bDuAaaAxtVVd4Idjp1dBQ==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", + "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", "dev": true, "dependencies": { - "call-bind": "^1.0.5", - "get-intrinsic": "^1.2.2", + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", "is-regex": "^1.1.4" }, "engines": { @@ -11726,21 +12453,44 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/safe-stable-stringify": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz", + "integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, "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/sax": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.3.0.tgz", - "integrity": "sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==" + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", + "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==" + }, + "node_modules/saxes": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "dev": true, + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=v12.22.7" + } }, "node_modules/schema-utils": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "@types/json-schema": "^7.0.8", "ajv": "^6.12.5", @@ -11754,6 +12504,12 @@ "url": "https://opencollective.com/webpack" } }, + "node_modules/secure-compare": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/secure-compare/-/secure-compare-3.0.1.tgz", + "integrity": "sha512-AckIIV90rPDcBcglUwXPF3kg0P0qmPsPXAj6BBEENQE1p5yA1xfmDJzfi1Tappj37Pv2mVbKpL3Z1T+Nn7k1Qw==", + "dev": true + }, "node_modules/select-hose": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", @@ -11785,9 +12541,9 @@ } }, "node_modules/send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", "dev": true, "dependencies": { "debug": "2.6.9", @@ -11823,17 +12579,22 @@ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true }, - "node_modules/send/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/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==", + "dev": true, + "engines": { + "node": ">= 0.8" + } }, "node_modules/serialize-error": { "version": "11.0.3", "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-11.0.3.tgz", "integrity": "sha512-2G2y++21dhj2R7iHAdd0FIzjGwuKZld+7Pl/bTU6YIkrC2ZMbVUjm+luj6A6V34Rv9XfKJDKpTWu9W4Gse1D9g==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "type-fest": "^2.12.2" }, @@ -11849,6 +12610,8 @@ "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "randombytes": "^2.1.0" } @@ -11932,45 +12695,47 @@ } }, "node_modules/serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", + "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", "dev": true, "dependencies": { - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "parseurl": "~1.3.3", - "send": "0.18.0" + "send": "0.19.0" }, "engines": { "node": ">= 0.8.0" } }, "node_modules/set-function-length": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.0.tgz", - "integrity": "sha512-4DBHDoyHlM1IRPGYcoxexgh67y4ueR53FKV1yyxwFMY7aCqcN/38M1+SwZ/qJQ8iLv7+ck385ot4CcisOAPT9w==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", "dev": true, "dependencies": { - "define-data-property": "^1.1.1", + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.2", + "get-intrinsic": "^1.2.4", "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.1" + "has-property-descriptors": "^1.0.2" }, "engines": { "node": ">= 0.4" } }, "node_modules/set-function-name": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.1.tgz", - "integrity": "sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", "dev": true, "dependencies": { - "define-data-property": "^1.0.1", + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", "functions-have-names": "^1.2.3", - "has-property-descriptors": "^1.0.0" + "has-property-descriptors": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -11980,7 +12745,9 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/setprototypeof": { "version": "1.2.0", @@ -12009,11 +12776,6 @@ "node": ">=0.10.0" } }, - "node_modules/shallow-copy": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/shallow-copy/-/shallow-copy-0.0.1.tgz", - "integrity": "sha512-b6i4ZpVuUxB9h5gfCxPiusKYkqTMOjEbBs4wMaFbkfia4yFv92UKZ6Df8WXcKbn08JNL/abvg3FnMAOfakDvUw==" - }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -12043,14 +12805,72 @@ } }, "node_modules/side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "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": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", "dev": true, "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" + "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" @@ -12073,11 +12893,14 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/simple-html-tokenizer": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/simple-html-tokenizer/-/simple-html-tokenizer-0.1.1.tgz", - "integrity": "sha512-Mc/gH3RvlKvB/gkp9XwgDKEWrSYyefIJPGG8Jk1suZms/rISdUuVEMx5O1WBnTWaScvxXDvGJrZQWblUmQHjkQ==", - "dev": true + "node_modules/simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.3.1" + } }, "node_modules/sirv": { "version": "2.0.4", @@ -12093,37 +12916,13 @@ "node": ">= 10" } }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" - } - }, "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, + "optional": true, + "peer": true, "engines": { "node": ">= 6.0.0", "npm": ">= 3.0.0" @@ -12154,6 +12953,8 @@ "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.3.tgz", "integrity": "sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "ip-address": "^9.0.5", "smart-buffer": "^4.2.0" @@ -12164,12 +12965,14 @@ } }, "node_modules/socks-proxy-agent": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.4.tgz", - "integrity": "sha512-GNAq/eg8Udq2x0eNiFkr9gRg5bA7PXEWagQdeRX4cPSG+X/8V38v637gim9bjFptMk1QWsCTr0ttrJEiXbNnRw==", + "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, + "optional": true, + "peer": true, "dependencies": { - "agent-base": "^7.1.1", + "agent-base": "^7.1.2", "debug": "^4.3.4", "socks": "^2.8.3" }, @@ -12177,25 +12980,19 @@ "node": ">= 14" } }, - "node_modules/source-list-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", - "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", - "dev": true - }, "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==", - "devOptional": true, + "optional": true, "engines": { "node": ">=0.10.0" } }, "node_modules/source-map-js": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", - "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "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": ">=0.10.0" @@ -12206,15 +13003,17 @@ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" } }, "node_modules/spacetrim": { - "version": "0.11.36", - "resolved": "https://registry.npmjs.org/spacetrim/-/spacetrim-0.11.36.tgz", - "integrity": "sha512-jqv5aAfMLkBnFK+38QUtEGgU7x1KrfpDnCdjX4+W1IEVgA8Kf3tk8K9je8j2nkCSXdIngjda53fuXERr4/61kw==", + "version": "0.11.59", + "resolved": "https://registry.npmjs.org/spacetrim/-/spacetrim-0.11.59.tgz", + "integrity": "sha512-lLYsktklSRKprreOm7NXReW8YiX2VBjbgmXYEziOoGf/qsJqAEACaDvoTtUOycwjpaSh+bT8eu0KrJn7UNxiCg==", "dev": true, "funding": [ { @@ -12225,7 +13024,9 @@ "type": "github", "url": "https://github.com/hejny/spacetrim/blob/main/README.md#%EF%B8%8F-contributing" } - ] + ], + "optional": true, + "peer": true }, "node_modules/spdy": { "version": "4.0.2", @@ -12276,6 +13077,8 @@ "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", "dev": true, + "optional": true, + "peer": true, "engines": { "node": ">= 10.x" } @@ -12284,8 +13087,10 @@ "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 - }, + "dev": true, + "optional": true, + "peer": true + }, "node_modules/sshpk": { "version": "1.18.0", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", @@ -12310,150 +13115,26 @@ "node": ">=0.10.0" } }, - "node_modules/stackback": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", - "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "node_modules/stable-hash": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/stable-hash/-/stable-hash-0.0.4.tgz", + "integrity": "sha512-LjdcbuBeLcdETCrPn9i8AYAZ1eCtu4ECAWtP7UleOiZ9LzVxRzzUZEoZ8zB24nhkQnDWyET0I+3sWokSDS3E7g==", "dev": true }, - "node_modules/static-eval": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/static-eval/-/static-eval-2.1.1.tgz", - "integrity": "sha512-MgWpQ/ZjGieSVB3eOJVs4OA2LT/q1vx98KPCTTQPzq/aLr0YUXTsgryTXr4SLfR0ZfUUCiedM9n/ABeDIyy4mA==", - "dependencies": { - "escodegen": "^2.1.0" - } - }, - "node_modules/static-module": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/static-module/-/static-module-2.2.5.tgz", - "integrity": "sha512-D8vv82E/Kpmz3TXHKG8PPsCPg+RAX6cbCOyvjM6x04qZtQ47EtJFVwRsdov3n5d6/6ynrOY9XB4JkaZwB2xoRQ==", - "dependencies": { - "concat-stream": "~1.6.0", - "convert-source-map": "^1.5.1", - "duplexer2": "~0.1.4", - "escodegen": "~1.9.0", - "falafel": "^2.1.0", - "has": "^1.0.1", - "magic-string": "^0.22.4", - "merge-source-map": "1.0.4", - "object-inspect": "~1.4.0", - "quote-stream": "~1.0.2", - "readable-stream": "~2.3.3", - "shallow-copy": "~0.0.1", - "static-eval": "^2.0.0", - "through2": "~2.0.3" - } - }, - "node_modules/static-module/node_modules/escodegen": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.9.1.tgz", - "integrity": "sha512-6hTjO1NAWkHnDk3OqQ4YrCuwwmGHL9S3nPlzBOUG/R44rda3wLNrfvQ5fkSGjyhHFKM7ALPKcKGrwvCLe0lC7Q==", - "dependencies": { - "esprima": "^3.1.3", - "estraverse": "^4.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1" - }, - "bin": { - "escodegen": "bin/escodegen.js", - "esgenerate": "bin/esgenerate.js" - }, - "engines": { - "node": ">=4.0" - }, - "optionalDependencies": { - "source-map": "~0.6.1" - } - }, - "node_modules/static-module/node_modules/esprima": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", - "integrity": "sha512-AWwVMNxwhN8+NIPQzAQZCm7RkLC4RbM3B1OobMuyp3i+w73X57KCKaVIxaRZb+DYCojq7rspo+fmuQfAboyhFg==", - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/static-module/node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/static-module/node_modules/levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", - "dependencies": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/static-module/node_modules/magic-string": { - "version": "0.22.5", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.22.5.tgz", - "integrity": "sha512-oreip9rJZkzvA8Qzk9HFs8fZGF/u7H/gtrE8EN6RjKJ9kh2HlC+yQ2QezifqTZfGyiuAV0dRv5a+y/8gBb1m9w==", - "dependencies": { - "vlq": "^0.2.2" - } - }, - "node_modules/static-module/node_modules/object-inspect": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.4.1.tgz", - "integrity": "sha512-wqdhLpfCUbEsoEwl3FXwGyv8ief1k/1aUdIPCqVnupM6e8l63BEJdiF/0swtn04/8p05tG/T0FrpTlfwvljOdw==" - }, - "node_modules/static-module/node_modules/optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dependencies": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/static-module/node_modules/prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", + "node_modules/stack-trace": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", + "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==", + "dev": true, "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/static-module/node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" + "node": "*" } }, - "node_modules/static-module/node_modules/type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", - "dependencies": { - "prelude-ls": "~1.1.2" - }, - "engines": { - "node": ">= 0.8.0" - } + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true }, "node_modules/statuses": { "version": "2.0.1", @@ -12465,26 +13146,11 @@ } }, "node_modules/std-env": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.7.0.tgz", - "integrity": "sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==", + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.8.0.tgz", + "integrity": "sha512-Bc3YwwCB+OzldMxOXJIIvC6cPRWr/LxOp48CdQTOkPyk/t4JWWJbrilwBd7RJzKV8QW7tJkcgAmeuLLJugl5/w==", "dev": true }, - "node_modules/stdin-discarder": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/stdin-discarder/-/stdin-discarder-0.1.0.tgz", - "integrity": "sha512-xhV7w8S+bUwlPTb4bAOUQhv8/cSS5offJuX8GQGq32ONF0ZtDWKfkdomM3HMRA+LhX6um/FZ0COqlwsjD53LeQ==", - "dev": true, - "dependencies": { - "bl": "^5.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/stealthy-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", @@ -12493,11 +13159,22 @@ "node": ">=0.10.0" } }, + "node_modules/streamsearch": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", + "integrity": "sha512-jos8u++JKm0ARcSUTAZXOVC0mSox7Bhn6sBgty73P1f3JGf7yG2clTbBNHUdde/kdvP2FESam+vM6l8jBrNxHA==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/streamx": { - "version": "2.18.0", - "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.18.0.tgz", - "integrity": "sha512-LLUC1TWdjVdn1weXGcSxyTR3T4+acB6tVGXT95y0nGbca4t4o/ng1wKAGTljm9VicuCVLvRlqFYXYy5GwgM7sQ==", + "version": "2.21.0", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.21.0.tgz", + "integrity": "sha512-Qz6MsDZXJ6ur9u+b+4xCG18TluU7PGlRfXVAAjNiGsFrBUt/ioyLkxbFaKJygoPs+/kW4VyBj0bSj89Qu0IGyg==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "fast-fifo": "^1.3.2", "queue-tick": "^1.0.1", @@ -12517,6 +13194,7 @@ "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, "dependencies": { "safe-buffer": "~5.1.0" } @@ -12524,7 +13202,8 @@ "node_modules/string_decoder/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==" + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true }, "node_modules/string-width": { "version": "5.1.2", @@ -12587,14 +13266,18 @@ } }, "node_modules/string.prototype.trim": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz", - "integrity": "sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==", + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", + "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-data-property": "^1.1.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-object-atoms": "^1.0.0", + "has-property-descriptors": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -12604,28 +13287,35 @@ } }, "node_modules/string.prototype.trimend": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz", - "integrity": "sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==", + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", + "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/string.prototype.trimstart": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz", - "integrity": "sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -12664,15 +13354,12 @@ } }, "node_modules/strip-final-newline": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", - "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", "dev": true, "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=6" } }, "node_modules/strip-json-comments": { @@ -12687,21 +13374,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/style-loader": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-4.0.0.tgz", - "integrity": "sha512-1V4WqhhZZgjVAVJyt7TdDPZoPBPNHbekX4fWnCJL1yQukhCeZhJySUL+gL9y6sNdN95uEOS83Y55SqHcP7MzLA==", - "dev": true, - "engines": { - "node": ">= 18.12.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.27.0" - } + "node_modules/strnum": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", + "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==", + "dev": true }, "node_modules/supports-color": { "version": "7.2.0", @@ -12715,23 +13392,11 @@ "node": ">=8" } }, - "node_modules/supports-hyperlinks": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz", - "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0", - "supports-color": "^7.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, "engines": { "node": ">= 0.4" }, @@ -12739,106 +13404,11 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/svg-inline-loader": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/svg-inline-loader/-/svg-inline-loader-0.8.2.tgz", - "integrity": "sha512-kbrcEh5n5JkypaSC152eGfGcnT4lkR0eSfvefaUJkLqgGjRQJyKDvvEE/CCv5aTSdfXuc+N98w16iAojhShI3g==", - "dev": true, - "dependencies": { - "loader-utils": "^1.1.0", - "object-assign": "^4.0.1", - "simple-html-tokenizer": "^0.1.1" - } - }, - "node_modules/svg-inline-loader/node_modules/json5": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", - "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", - "dev": true, - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" - } - }, - "node_modules/svg-inline-loader/node_modules/loader-utils": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.2.tgz", - "integrity": "sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==", - "dev": true, - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - }, - "engines": { - "node": ">=4.0.0" - } - }, "node_modules/symbol-tree": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==" }, - "node_modules/table": { - "version": "6.8.1", - "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz", - "integrity": "sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==", - "dev": true, - "dependencies": { - "ajv": "^8.0.1", - "lodash.truncate": "^4.4.2", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/table/node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/table/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/table/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/table/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/tapable": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", @@ -12853,6 +13423,8 @@ "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.6.tgz", "integrity": "sha512-iokBDQQkUyeXhgPYaZxmczGPhnhXZ0CmrqI+MOb/WFGS9DW5wnfrLgtjUJBvz50vQ3qfRwJ62QVoCFu8mPVu5w==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "pump": "^3.0.0", "tar-stream": "^3.1.5" @@ -12867,33 +13439,21 @@ "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "b4a": "^1.6.4", "fast-fifo": "^1.2.0", "streamx": "^2.15.0" } }, - "node_modules/terminal-link": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-3.0.0.tgz", - "integrity": "sha512-flFL3m4wuixmf6IfhFJd1YPiLiMuxEc8uHRM1buzIeZPm22Au2pDqBJQgdo7n1WfPU1ONFGv7YDwpFBmHGF6lg==", - "dev": true, - "dependencies": { - "ansi-escapes": "^5.0.0", - "supports-hyperlinks": "^2.2.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/terser": { "version": "5.29.1", "resolved": "https://registry.npmjs.org/terser/-/terser-5.29.1.tgz", "integrity": "sha512-lZQ/fyaIGxsbGxApKmoPTODIzELy3++mXhS5hOqaAWZjQtpq/hFHAc+rm29NND1rYRxRWKcjuARNwULNXa5RtQ==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.8.2", @@ -12912,6 +13472,8 @@ "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "@jridgewell/trace-mapping": "^0.3.20", "jest-worker": "^27.4.5", @@ -12945,58 +13507,46 @@ "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 + "dev": true, + "optional": true, + "peer": true }, "node_modules/text-decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.1.1.tgz", "integrity": "sha512-8zll7REEv4GDD3x4/0pW+ppIxSNs7H1J10IKFZsuOMscumCdM2a+toDGLPA3T+1+fLBql4zbt5z83GEQGGV5VA==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "b4a": "^1.6.4" } }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "node_modules/text-hex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", + "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==", "dev": true }, + "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==", + "dev": true, + "engines": { + "node": ">=10.18" + }, + "peerDependencies": { + "tslib": "^2" + } + }, "node_modules/through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "dev": true - }, - "node_modules/through2": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", - "integrity": "sha512-RkK/CCESdTKQZHdmKICijdKKsCRVHs5KsLZ6pACAmF/1GPUQhonHSXWNERctxEp7RmvjdNbZTL5z9V7nSCXKcg==", - "dependencies": { - "readable-stream": ">=1.0.33-1 <1.1.0-0", - "xtend": ">=4.0.0 <4.1.0-0" - } - }, - "node_modules/through2/node_modules/isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==" - }, - "node_modules/through2/node_modules/readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "node_modules/through2/node_modules/string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==" + "dev": true, + "optional": true, + "peer": true }, "node_modules/thunky": { "version": "1.1.0", @@ -13005,38 +13555,107 @@ "dev": true }, "node_modules/tinybench": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.8.0.tgz", - "integrity": "sha512-1/eK7zUnIklz4JUUlL+658n58XO2hHLQfSk1Zf2LKieUjxidN16eKFEoDEfjHc3ohofSSqK3X5yO6VGb6iW8Lw==", + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", "dev": true }, + "node_modules/tinyexec": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", + "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyglobby": { + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.10.tgz", + "integrity": "sha512-Zc+8eJlFMvgatPZTl6A9L/yht8QqdmUNtURHaKZLmKBE12hNPSrqNkUp2cs3M/UKmNVVAMFQYSjYIVHDjW5zew==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.4.2", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.4.3", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.3.tgz", + "integrity": "sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/tinypool": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.0.0.tgz", - "integrity": "sha512-KIKExllK7jp3uvrNtvRBYBWBOAXSX8ZvoaD8T+7KB/QHIuoJW3Pmr60zucywjAlMb5TeXUkcs/MWeWLu0qvuAQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.0.2.tgz", + "integrity": "sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA==", "dev": true, "engines": { "node": "^18.0.0 || >=20.0.0" } }, "node_modules/tinyrainbow": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-1.2.0.tgz", - "integrity": "sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-2.0.0.tgz", + "integrity": "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==", "dev": true, + "license": "MIT", "engines": { "node": ">=14.0.0" } }, "node_modules/tinyspy": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-3.0.0.tgz", - "integrity": "sha512-q5nmENpTHgiPVd1cJDDc9cVoYN5x4vCvwT3FMilvKPKneCBZAxn2YWQjDF0UMcE9k0Cay1gBiDfTMU0g+mPMQA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-3.0.2.tgz", + "integrity": "sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=14.0.0" } }, + "node_modules/tldts": { + "version": "6.1.70", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.70.tgz", + "integrity": "sha512-/W1YVgYVJd9ZDjey5NXadNh0mJXkiUMUue9Zebd0vpdo1sU+H4zFFTaJ1RKD4N6KFoHfcXy6l+Vu7bh+bdWCzA==", + "dev": true, + "dependencies": { + "tldts-core": "^6.1.70" + }, + "bin": { + "tldts": "bin/cli.js" + } + }, + "node_modules/tldts-core": { + "version": "6.1.70", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.70.tgz", + "integrity": "sha512-RNnIXDB1FD4T9cpQRErEqw6ZpjLlGdMOitdV+0xtbsnwr4YFka1zpc7D4KD+aAn8oSG5JyFrdasZTE04qDE9Yg==", + "dev": true + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -13083,23 +13702,80 @@ } }, "node_modules/tr46": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", - "integrity": "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.0.0.tgz", + "integrity": "sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==", + "dev": true, "dependencies": { - "punycode": "^2.1.0" + "punycode": "^2.3.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/tree-dump": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/tree-dump/-/tree-dump-1.0.2.tgz", + "integrity": "sha512-dpev9ABuLWdEubk+cIaI9cHwRNNDjkBBLXTwI4UCUFdQ5xXKqNXoK4FEciw/vxf+NQ7Cb7sGUyeUtORvHIdRXQ==", + "dev": true, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/triple-beam": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.4.1.tgz", + "integrity": "sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==", + "dev": true, + "engines": { + "node": ">= 14.0.0" } }, "node_modules/ts-api-utils": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", - "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.0.0.tgz", + "integrity": "sha512-xCt/TOAc+EOHS1XPnijD3/yzpH6qg2xppZO1YDqGoVsNXfQfzHpOdNuXwrwOU8u4ITXJyDCTyt8w5g1sZv9ynQ==", "dev": true, + "license": "MIT", "engines": { - "node": ">=16" + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, + "node_modules/ts-checker-rspack-plugin": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ts-checker-rspack-plugin/-/ts-checker-rspack-plugin-1.1.1.tgz", + "integrity": "sha512-BlpPqnfAmV0TcDg58H+1qV8Zb57ilv0x+ajjnxrVQ6BWgC8HzAdc+TycqDOJ4sZZYIV+hywQGozZFGklzbCR6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.16.7", + "@rspack/lite-tapable": "^1.0.0", + "chokidar": "^3.5.3", + "memfs": "^4.14.0", + "minimatch": "^9.0.5", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=16.0.0" }, "peerDependencies": { - "typescript": ">=4.2.0" + "@rspack/core": "^1.0.0", + "typescript": ">=3.8.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + } } }, "node_modules/tsconfig-paths": { @@ -13132,13 +13808,22 @@ "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", "dev": true }, + "node_modules/tsscmp": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/tsscmp/-/tsscmp-1.0.6.tgz", + "integrity": "sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==", + "dev": true, + "engines": { + "node": ">=0.6.x" + } + }, "node_modules/tsx": { - "version": "4.16.2", - "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.16.2.tgz", - "integrity": "sha512-C1uWweJDgdtX2x600HjaFaucXTilT7tgUZHbOE4+ypskZ1OP8CRCSDkCxG6Vya9EwaFIVagWwpaVAn5wzypaqQ==", + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.19.2.tgz", + "integrity": "sha512-pOUl6Vo2LUq/bSa8S5q7b91cgNSjctn9ugq/+Mvow99qW6x/UZYwzxy/3NmqoT66eHYfCVvFvACC58UBPFf28g==", "dev": true, "dependencies": { - "esbuild": "~0.21.5", + "esbuild": "~0.23.0", "get-tsconfig": "^4.7.5" }, "bin": { @@ -13152,9 +13837,9 @@ } }, "node_modules/tsx/node_modules/@esbuild/aix-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", - "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.23.1.tgz", + "integrity": "sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ==", "cpu": [ "ppc64" ], @@ -13164,13 +13849,13 @@ "aix" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/tsx/node_modules/@esbuild/android-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", - "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.23.1.tgz", + "integrity": "sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ==", "cpu": [ "arm" ], @@ -13180,13 +13865,13 @@ "android" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/tsx/node_modules/@esbuild/android-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", - "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.23.1.tgz", + "integrity": "sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw==", "cpu": [ "arm64" ], @@ -13196,13 +13881,13 @@ "android" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/tsx/node_modules/@esbuild/android-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", - "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.23.1.tgz", + "integrity": "sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg==", "cpu": [ "x64" ], @@ -13212,13 +13897,13 @@ "android" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/tsx/node_modules/@esbuild/darwin-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", - "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.23.1.tgz", + "integrity": "sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q==", "cpu": [ "arm64" ], @@ -13228,13 +13913,13 @@ "darwin" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/tsx/node_modules/@esbuild/darwin-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", - "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.23.1.tgz", + "integrity": "sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw==", "cpu": [ "x64" ], @@ -13244,13 +13929,13 @@ "darwin" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/tsx/node_modules/@esbuild/freebsd-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", - "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.23.1.tgz", + "integrity": "sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA==", "cpu": [ "arm64" ], @@ -13260,13 +13945,13 @@ "freebsd" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/tsx/node_modules/@esbuild/freebsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", - "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.23.1.tgz", + "integrity": "sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g==", "cpu": [ "x64" ], @@ -13276,13 +13961,13 @@ "freebsd" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/tsx/node_modules/@esbuild/linux-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", - "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.23.1.tgz", + "integrity": "sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ==", "cpu": [ "arm" ], @@ -13292,13 +13977,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/tsx/node_modules/@esbuild/linux-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", - "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.23.1.tgz", + "integrity": "sha512-/93bf2yxencYDnItMYV/v116zff6UyTjo4EtEQjUBeGiVpMmffDNUyD9UN2zV+V3LRV3/on4xdZ26NKzn6754g==", "cpu": [ "arm64" ], @@ -13308,13 +13993,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/tsx/node_modules/@esbuild/linux-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", - "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.23.1.tgz", + "integrity": "sha512-VTN4EuOHwXEkXzX5nTvVY4s7E/Krz7COC8xkftbbKRYAl96vPiUssGkeMELQMOnLOJ8k3BY1+ZY52tttZnHcXQ==", "cpu": [ "ia32" ], @@ -13324,13 +14009,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/tsx/node_modules/@esbuild/linux-loong64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", - "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.23.1.tgz", + "integrity": "sha512-Vx09LzEoBa5zDnieH8LSMRToj7ir/Jeq0Gu6qJ/1GcBq9GkfoEAoXvLiW1U9J1qE/Y/Oyaq33w5p2ZWrNNHNEw==", "cpu": [ "loong64" ], @@ -13340,13 +14025,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/tsx/node_modules/@esbuild/linux-mips64el": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", - "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.23.1.tgz", + "integrity": "sha512-nrFzzMQ7W4WRLNUOU5dlWAqa6yVeI0P78WKGUo7lg2HShq/yx+UYkeNSE0SSfSure0SqgnsxPvmAUu/vu0E+3Q==", "cpu": [ "mips64el" ], @@ -13356,13 +14041,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/tsx/node_modules/@esbuild/linux-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", - "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.23.1.tgz", + "integrity": "sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw==", "cpu": [ "ppc64" ], @@ -13372,13 +14057,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/tsx/node_modules/@esbuild/linux-riscv64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", - "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.23.1.tgz", + "integrity": "sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA==", "cpu": [ "riscv64" ], @@ -13388,1037 +14073,721 @@ "linux" ], "engines": { - "node": ">=12" - } - }, - "node_modules/tsx/node_modules/@esbuild/linux-s390x": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", - "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/tsx/node_modules/@esbuild/linux-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", - "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/tsx/node_modules/@esbuild/netbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", - "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/tsx/node_modules/@esbuild/openbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", - "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/tsx/node_modules/@esbuild/sunos-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", - "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/tsx/node_modules/@esbuild/win32-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", - "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/tsx/node_modules/@esbuild/win32-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", - "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/tsx/node_modules/@esbuild/win32-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", - "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/tsx/node_modules/esbuild": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", - "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", - "dev": true, - "hasInstallScript": true, - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.21.5", - "@esbuild/android-arm": "0.21.5", - "@esbuild/android-arm64": "0.21.5", - "@esbuild/android-x64": "0.21.5", - "@esbuild/darwin-arm64": "0.21.5", - "@esbuild/darwin-x64": "0.21.5", - "@esbuild/freebsd-arm64": "0.21.5", - "@esbuild/freebsd-x64": "0.21.5", - "@esbuild/linux-arm": "0.21.5", - "@esbuild/linux-arm64": "0.21.5", - "@esbuild/linux-ia32": "0.21.5", - "@esbuild/linux-loong64": "0.21.5", - "@esbuild/linux-mips64el": "0.21.5", - "@esbuild/linux-ppc64": "0.21.5", - "@esbuild/linux-riscv64": "0.21.5", - "@esbuild/linux-s390x": "0.21.5", - "@esbuild/linux-x64": "0.21.5", - "@esbuild/netbsd-x64": "0.21.5", - "@esbuild/openbsd-x64": "0.21.5", - "@esbuild/sunos-x64": "0.21.5", - "@esbuild/win32-arm64": "0.21.5", - "@esbuild/win32-ia32": "0.21.5", - "@esbuild/win32-x64": "0.21.5" - } - }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", - "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" - } - }, - "node_modules/tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==" - }, - "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, - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-fest": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", - "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", - "dev": true, - "engines": { - "node": ">=12.20" - }, - "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==", - "dev": true, - "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/typed-array-buffer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz", - "integrity": "sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1", - "is-typed-array": "^1.1.10" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/typed-array-byte-length": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz", - "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "has-proto": "^1.0.1", - "is-typed-array": "^1.1.10" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-byte-offset": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz", - "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==", - "dev": true, - "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "has-proto": "^1.0.1", - "is-typed-array": "^1.1.10" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-length": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", - "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "is-typed-array": "^1.1.9" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" - }, - "node_modules/typescript": { - "version": "5.5.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", - "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/unbzip2-stream": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", - "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", - "dev": true, - "dependencies": { - "buffer": "^5.2.1", - "through": "^2.3.8" - } - }, - "node_modules/unbzip2-stream/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/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/universalify": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", - "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", - "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, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/update-browserslist-db": { - "version": "1.0.13", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", - "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", - "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.1.1", - "picocolors": "^1.0.0" - }, - "bin": { - "update-browserslist-db": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/url-parse": { - "version": "1.5.10", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", - "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", - "dev": true, - "dependencies": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, - "node_modules/userhome": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/userhome/-/userhome-1.0.0.tgz", - "integrity": "sha512-ayFKY3H+Pwfy4W98yPdtH1VqH4psDeyW8lYYFzfecR9d6hqLpqhecktvYR3SEEXt7vG0S1JEpciI3g94pMErig==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" - }, - "node_modules/utila": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", - "integrity": "sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==", - "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==", - "dev": true, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", - "bin": { - "uuid": "bin/uuid" - } - }, - "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, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", - "engines": [ - "node >=0.6.0" - ], - "dependencies": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "node_modules/verror/node_modules/core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==" - }, - "node_modules/vite": { - "version": "5.3.4", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.4.tgz", - "integrity": "sha512-Cw+7zL3ZG9/NZBB8C+8QbQZmR54GwqIz+WMI4b3JgdYJvX+ny9AjJXqkGQlDXSXRP9rP0B4tbciRMOVEKulVOA==", - "dev": true, - "dependencies": { - "esbuild": "^0.21.3", - "postcss": "^8.4.39", - "rollup": "^4.13.0" - }, - "bin": { - "vite": "bin/vite.js" - }, - "engines": { - "node": "^18.0.0 || >=20.0.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - }, - "peerDependencies": { - "@types/node": "^18.0.0 || >=20.0.0", - "less": "*", - "lightningcss": "^1.21.0", - "sass": "*", - "stylus": "*", - "sugarss": "*", - "terser": "^5.4.0" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "less": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "sass": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - } - } - }, - "node_modules/vite-node": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-2.0.4.tgz", - "integrity": "sha512-ZpJVkxcakYtig5iakNeL7N3trufe3M6vGuzYAr4GsbCTwobDeyPJpE4cjDhhPluv8OvQCFzu2LWp6GkoKRITXA==", - "dev": true, - "dependencies": { - "cac": "^6.7.14", - "debug": "^4.3.5", - "pathe": "^1.1.2", - "tinyrainbow": "^1.2.0", - "vite": "^5.0.0" - }, - "bin": { - "vite-node": "vite-node.mjs" - }, - "engines": { - "node": "^18.0.0 || >=20.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" + "node": ">=18" } }, - "node_modules/vite-node/node_modules/debug": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", - "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "node_modules/tsx/node_modules/@esbuild/linux-s390x": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.23.1.tgz", + "integrity": "sha512-9ygs73tuFCe6f6m/Tb+9LtYxWR4c9yg7zjt2cYkjDbDpV/xVn+68cQxMXCjUpYwEkze2RcU/rMnfIXNRFmSoDw==", + "cpu": [ + "s390x" + ], "dev": true, - "dependencies": { - "ms": "2.1.2" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "node": ">=18" } }, - "node_modules/vite/node_modules/@esbuild/aix-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", - "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "node_modules/tsx/node_modules/@esbuild/linux-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.23.1.tgz", + "integrity": "sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ==", "cpu": [ - "ppc64" + "x64" ], "dev": true, "optional": true, "os": [ - "aix" + "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, - "node_modules/vite/node_modules/@esbuild/android-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", - "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "node_modules/tsx/node_modules/@esbuild/netbsd-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.23.1.tgz", + "integrity": "sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA==", "cpu": [ - "arm" + "x64" ], "dev": true, "optional": true, "os": [ - "android" + "netbsd" ], "engines": { - "node": ">=12" + "node": ">=18" } }, - "node_modules/vite/node_modules/@esbuild/android-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", - "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "node_modules/tsx/node_modules/@esbuild/openbsd-arm64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.23.1.tgz", + "integrity": "sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q==", "cpu": [ "arm64" ], "dev": true, "optional": true, "os": [ - "android" + "openbsd" ], "engines": { - "node": ">=12" + "node": ">=18" } }, - "node_modules/vite/node_modules/@esbuild/android-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", - "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "node_modules/tsx/node_modules/@esbuild/openbsd-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.23.1.tgz", + "integrity": "sha512-aY2gMmKmPhxfU+0EdnN+XNtGbjfQgwZj43k8G3fyrDM/UdZww6xrWxmDkuz2eCZchqVeABjV5BpildOrUbBTqA==", "cpu": [ "x64" ], "dev": true, "optional": true, "os": [ - "android" + "openbsd" ], "engines": { - "node": ">=12" + "node": ">=18" } }, - "node_modules/vite/node_modules/@esbuild/darwin-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", - "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "node_modules/tsx/node_modules/@esbuild/sunos-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.23.1.tgz", + "integrity": "sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA==", "cpu": [ - "arm64" + "x64" ], "dev": true, "optional": true, "os": [ - "darwin" + "sunos" ], "engines": { - "node": ">=12" + "node": ">=18" } }, - "node_modules/vite/node_modules/@esbuild/darwin-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", - "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "node_modules/tsx/node_modules/@esbuild/win32-arm64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.23.1.tgz", + "integrity": "sha512-4O+gPR5rEBe2FpKOVyiJ7wNDPA8nGzDuJ6gN4okSA1gEOYZ67N8JPk58tkWtdtPeLz7lBnY6I5L3jdsr3S+A6A==", "cpu": [ - "x64" + "arm64" ], "dev": true, "optional": true, "os": [ - "darwin" + "win32" ], "engines": { - "node": ">=12" + "node": ">=18" } }, - "node_modules/vite/node_modules/@esbuild/freebsd-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", - "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "node_modules/tsx/node_modules/@esbuild/win32-ia32": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.23.1.tgz", + "integrity": "sha512-BcaL0Vn6QwCwre3Y717nVHZbAa4UBEigzFm6VdsVdT/MbZ38xoj1X9HPkZhbmaBGUD1W8vxAfffbDe8bA6AKnQ==", "cpu": [ - "arm64" + "ia32" ], "dev": true, "optional": true, "os": [ - "freebsd" + "win32" ], "engines": { - "node": ">=12" + "node": ">=18" } }, - "node_modules/vite/node_modules/@esbuild/freebsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", - "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "node_modules/tsx/node_modules/@esbuild/win32-x64": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.23.1.tgz", + "integrity": "sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg==", "cpu": [ "x64" ], "dev": true, "optional": true, "os": [ - "freebsd" + "win32" ], "engines": { - "node": ">=12" + "node": ">=18" } }, - "node_modules/vite/node_modules/@esbuild/linux-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", - "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", - "cpu": [ - "arm" + "node_modules/tsx/node_modules/esbuild": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.23.1.tgz", + "integrity": "sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.23.1", + "@esbuild/android-arm": "0.23.1", + "@esbuild/android-arm64": "0.23.1", + "@esbuild/android-x64": "0.23.1", + "@esbuild/darwin-arm64": "0.23.1", + "@esbuild/darwin-x64": "0.23.1", + "@esbuild/freebsd-arm64": "0.23.1", + "@esbuild/freebsd-x64": "0.23.1", + "@esbuild/linux-arm": "0.23.1", + "@esbuild/linux-arm64": "0.23.1", + "@esbuild/linux-ia32": "0.23.1", + "@esbuild/linux-loong64": "0.23.1", + "@esbuild/linux-mips64el": "0.23.1", + "@esbuild/linux-ppc64": "0.23.1", + "@esbuild/linux-riscv64": "0.23.1", + "@esbuild/linux-s390x": "0.23.1", + "@esbuild/linux-x64": "0.23.1", + "@esbuild/netbsd-x64": "0.23.1", + "@esbuild/openbsd-arm64": "0.23.1", + "@esbuild/openbsd-x64": "0.23.1", + "@esbuild/sunos-x64": "0.23.1", + "@esbuild/win32-arm64": "0.23.1", + "@esbuild/win32-ia32": "0.23.1", + "@esbuild/win32-x64": "0.23.1" + } + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==" + }, + "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, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", + "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=12.20" + }, + "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==", + "dev": true, + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", + "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", + "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.3.tgz", + "integrity": "sha512-GsvTyUHTriq6o/bHcTd0vM7OQ9JEdlvluu9YISaA7+KzDzPaIzEeDFNkTfhdE3MYcNhNi0vq/LlegYgIs5yPAw==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13", + "reflect.getprototypeof": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", + "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0", + "reflect.getprototypeof": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/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==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/typescript-eslint": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.20.0.tgz", + "integrity": "sha512-Kxz2QRFsgbWj6Xcftlw3Dd154b3cEPFqQC+qMZrMypSijPd4UanKKvoKDrJ4o8AIfZFKAF+7sMaEIR8mTElozA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/eslint-plugin": "8.20.0", + "@typescript-eslint/parser": "8.20.0", + "@typescript-eslint/utils": "8.20.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" + } + }, + "node_modules/unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/unbzip2-stream": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", + "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "buffer": "^5.2.1", + "through": "^2.3.8" + } + }, + "node_modules/unbzip2-stream/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" + } ], - "dev": true, "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" + "peer": true, + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" } }, - "node_modules/vite/node_modules/@esbuild/linux-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", - "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", - "cpu": [ - "arm64" - ], + "node_modules/undici": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.21.0.tgz", + "integrity": "sha512-BUgJXc752Kou3oOIuU1i+yZZypyZRqNPW0vqoMPl8VaoalSfeR0D8/t4iAS3yirs79SSMTxTag+ZC86uswv+Cw==", "dev": true, "optional": true, - "os": [ - "linux" - ], + "peer": true, "engines": { - "node": ">=12" + "node": ">=18.17" } }, - "node_modules/vite/node_modules/@esbuild/linux-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", - "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", - "cpu": [ - "ia32" - ], + "node_modules/undici-types": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", + "dev": true + }, + "node_modules/union": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/union/-/union-0.5.0.tgz", + "integrity": "sha512-N6uOhuW6zO95P3Mel2I2zMsbsanvvtgn6jVqJv4vbVcz/JN0OkL9suomjQGmWtxJQXOCqUJvquc1sMeNz/IwlA==", "dev": true, - "optional": true, - "os": [ - "linux" - ], + "dependencies": { + "qs": "^6.4.0" + }, "engines": { - "node": ">=12" + "node": ">= 0.8.0" } }, - "node_modules/vite/node_modules/@esbuild/linux-loong64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", - "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", - "cpu": [ - "loong64" - ], + "node_modules/universalify": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", "dev": true, - "optional": true, - "os": [ - "linux" - ], "engines": { - "node": ">=12" + "node": ">= 4.0.0" } }, - "node_modules/vite/node_modules/@esbuild/linux-mips64el": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", - "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", - "cpu": [ - "mips64el" - ], + "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, - "optional": true, - "os": [ - "linux" - ], "engines": { - "node": ">=12" + "node": ">= 0.8" } }, - "node_modules/vite/node_modules/@esbuild/linux-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", - "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", - "cpu": [ - "ppc64" - ], + "node_modules/update-browserslist-db": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", + "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", "dev": true, - "optional": true, - "os": [ - "linux" + "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" + } ], - "engines": { - "node": ">=12" + "optional": true, + "peer": true, + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" } }, - "node_modules/vite/node_modules/@esbuild/linux-riscv64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", - "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dependencies": { + "punycode": "^2.1.0" } }, - "node_modules/vite/node_modules/@esbuild/linux-s390x": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", - "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", - "cpu": [ - "s390x" - ], + "node_modules/url-join": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", + "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==", + "dev": true + }, + "node_modules/url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" } }, - "node_modules/vite/node_modules/@esbuild/linux-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", - "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", - "cpu": [ - "x64" - ], + "node_modules/urlpattern-polyfill": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-10.0.0.tgz", + "integrity": "sha512-H/A06tKD7sS1O1X2SshBVeA5FLycRpjqiBeqGKmBwBDBy28EnRjORxTNe269KSSr5un5qyWi1iL61wLxpd+ZOg==", "dev": true, "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } + "peer": true }, - "node_modules/vite/node_modules/@esbuild/netbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", - "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", - "cpu": [ - "x64" - ], + "node_modules/userhome": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/userhome/-/userhome-1.0.1.tgz", + "integrity": "sha512-5cnLm4gseXjAclKowC4IjByaGsjtAoV6PrOQOljplNB54ReUYJP8HdAFq2muHinSDAh09PPX/uXDPfdxRHvuSA==", "dev": true, "optional": true, - "os": [ - "netbsd" - ], + "peer": true, "engines": { - "node": ">=12" + "node": ">= 0.8.0" } }, - "node_modules/vite/node_modules/@esbuild/openbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", - "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", - "cpu": [ - "x64" - ], + "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==", "dev": true, - "optional": true, - "os": [ - "openbsd" - ], "engines": { - "node": ">=12" + "node": ">= 0.4.0" } }, - "node_modules/vite/node_modules/@esbuild/sunos-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", - "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" + "node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "bin": { + "uuid": "bin/uuid" } }, - "node_modules/vite/node_modules/@esbuild/win32-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", - "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", - "cpu": [ - "arm64" - ], + "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, - "optional": true, - "os": [ - "win32" - ], "engines": { - "node": ">=12" + "node": ">= 0.8" } }, - "node_modules/vite/node_modules/@esbuild/win32-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", - "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" + "node_modules/verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", + "engines": [ + "node >=0.6.0" ], - "engines": { - "node": ">=12" + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" } }, - "node_modules/vite/node_modules/@esbuild/win32-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", - "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", - "cpu": [ - "x64" - ], + "node_modules/verror/node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==" + }, + "node_modules/vite": { + "version": "6.0.7", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.0.7.tgz", + "integrity": "sha512-RDt8r/7qx9940f8FcOIAH9PTViRrghKaK2K1jY3RaAURrEUbm9Du1mJ72G+jlhtG3WwodnfzY8ORQZbBavZEAQ==", "dev": true, - "optional": true, - "os": [ - "win32" - ], + "license": "MIT", + "dependencies": { + "esbuild": "^0.24.2", + "postcss": "^8.4.49", + "rollup": "^4.23.0" + }, + "bin": { + "vite": "bin/vite.js" + }, "engines": { - "node": ">=12" + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "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 + } } }, - "node_modules/vite/node_modules/esbuild": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", - "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "node_modules/vite-node": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.0.2.tgz", + "integrity": "sha512-hsEQerBAHvVAbv40m3TFQe/lTEbOp7yDpyqMJqr2Tnd+W58+DEYOt+fluQgekOePcsNBmR77lpVAnIU2Xu4SvQ==", "dev": true, - "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "cac": "^6.7.14", + "debug": "^4.4.0", + "es-module-lexer": "^1.6.0", + "pathe": "^2.0.1", + "vite": "^5.0.0 || ^6.0.0" + }, "bin": { - "esbuild": "bin/esbuild" + "vite-node": "vite-node.mjs" }, "engines": { - "node": ">=12" + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.21.5", - "@esbuild/android-arm": "0.21.5", - "@esbuild/android-arm64": "0.21.5", - "@esbuild/android-x64": "0.21.5", - "@esbuild/darwin-arm64": "0.21.5", - "@esbuild/darwin-x64": "0.21.5", - "@esbuild/freebsd-arm64": "0.21.5", - "@esbuild/freebsd-x64": "0.21.5", - "@esbuild/linux-arm": "0.21.5", - "@esbuild/linux-arm64": "0.21.5", - "@esbuild/linux-ia32": "0.21.5", - "@esbuild/linux-loong64": "0.21.5", - "@esbuild/linux-mips64el": "0.21.5", - "@esbuild/linux-ppc64": "0.21.5", - "@esbuild/linux-riscv64": "0.21.5", - "@esbuild/linux-s390x": "0.21.5", - "@esbuild/linux-x64": "0.21.5", - "@esbuild/netbsd-x64": "0.21.5", - "@esbuild/openbsd-x64": "0.21.5", - "@esbuild/sunos-x64": "0.21.5", - "@esbuild/win32-arm64": "0.21.5", - "@esbuild/win32-ia32": "0.21.5", - "@esbuild/win32-x64": "0.21.5" + "funding": { + "url": "https://opencollective.com/vitest" } }, "node_modules/vitest": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-2.0.4.tgz", - "integrity": "sha512-luNLDpfsnxw5QSW4bISPe6tkxVvv5wn2BBs/PuDRkhXZ319doZyLOBr1sjfB5yCEpTiU7xCAdViM8TNVGPwoog==", - "dev": true, - "dependencies": { - "@ampproject/remapping": "^2.3.0", - "@vitest/expect": "2.0.4", - "@vitest/pretty-format": "^2.0.4", - "@vitest/runner": "2.0.4", - "@vitest/snapshot": "2.0.4", - "@vitest/spy": "2.0.4", - "@vitest/utils": "2.0.4", - "chai": "^5.1.1", - "debug": "^4.3.5", - "execa": "^8.0.1", - "magic-string": "^0.30.10", - "pathe": "^1.1.2", - "std-env": "^3.7.0", - "tinybench": "^2.8.0", - "tinypool": "^1.0.0", - "tinyrainbow": "^1.2.0", - "vite": "^5.0.0", - "vite-node": "2.0.4", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.0.2.tgz", + "integrity": "sha512-5bzaHakQ0hmVVKLhfh/jXf6oETDBtgPo8tQCHYB+wftNgFJ+Hah67IsWc8ivx4vFL025Ow8UiuTf4W57z4izvQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/expect": "3.0.2", + "@vitest/mocker": "3.0.2", + "@vitest/pretty-format": "^3.0.2", + "@vitest/runner": "3.0.2", + "@vitest/snapshot": "3.0.2", + "@vitest/spy": "3.0.2", + "@vitest/utils": "3.0.2", + "chai": "^5.1.2", + "debug": "^4.4.0", + "expect-type": "^1.1.0", + "magic-string": "^0.30.17", + "pathe": "^2.0.1", + "std-env": "^3.8.0", + "tinybench": "^2.9.0", + "tinyexec": "^0.3.2", + "tinypool": "^1.0.2", + "tinyrainbow": "^2.0.0", + "vite": "^5.0.0 || ^6.0.0", + "vite-node": "3.0.2", "why-is-node-running": "^2.3.0" }, "bin": { "vitest": "vitest.mjs" }, "engines": { - "node": "^18.0.0 || >=20.0.0" + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" }, "funding": { "url": "https://opencollective.com/vitest" }, "peerDependencies": { "@edge-runtime/vm": "*", - "@types/node": "^18.0.0 || >=20.0.0", - "@vitest/browser": "2.0.4", - "@vitest/ui": "2.0.4", + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "@vitest/browser": "3.0.2", + "@vitest/ui": "3.0.2", "happy-dom": "*", "jsdom": "*" }, @@ -14443,28 +14812,6 @@ } } }, - "node_modules/vitest/node_modules/debug": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", - "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/vlq": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/vlq/-/vlq-0.2.3.tgz", - "integrity": "sha512-DRibZL6DsNhIgYQ+wNdWDL2SL3bKPlVrRiBqV5yuMm++op8W4kGFtaQfCs4KEJn0wBZcHVHJ3eoywX8983k1ow==" - }, "node_modules/w3c-hr-time": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", @@ -14474,11 +14821,25 @@ "browser-process-hrtime": "^1.0.0" } }, + "node_modules/w3c-xmlserializer": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", + "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", + "dev": true, + "dependencies": { + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/wait-port": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/wait-port/-/wait-port-1.1.0.tgz", "integrity": "sha512-3e04qkoN3LxTMLakdqeWth8nih8usyg+sf1Bgdf9wwUkp05iuK1eSY/QpLvscT/+F/gA89+LpUmmgBtesbqI2Q==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "chalk": "^4.1.2", "commander": "^9.3.0", @@ -14496,6 +14857,8 @@ "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.1.tgz", "integrity": "sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.1.2" @@ -14513,111 +14876,152 @@ "minimalistic-assert": "^1.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==", - "dev": true, - "dependencies": { - "defaults": "^1.0.3" - } - }, "node_modules/web-streams-polyfill": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", "dev": true, + "optional": true, + "peer": true, "engines": { "node": ">= 8" } }, "node_modules/webdriver": { - "version": "8.39.0", - "resolved": "https://registry.npmjs.org/webdriver/-/webdriver-8.39.0.tgz", - "integrity": "sha512-Kc3+SfiH4ufyrIht683VT2vnJocx0pfH8rYdyPvEh1b2OYewtFTHK36k9rBDHZiBmk6jcSXs4M2xeFgOuon9Lg==", + "version": "9.4.1", + "resolved": "https://registry.npmjs.org/webdriver/-/webdriver-9.4.1.tgz", + "integrity": "sha512-vFDdxMj/9W1+6jhpHSiRYfO8dix23HjAUtLx7aOv9ejEsntC0EzCIAftJ59YsF3Ppu184+FkdDVhnivpkZPTFw==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "@types/node": "^20.1.0", "@types/ws": "^8.5.3", - "@wdio/config": "8.39.0", - "@wdio/logger": "8.38.0", - "@wdio/protocols": "8.38.0", - "@wdio/types": "8.39.0", - "@wdio/utils": "8.39.0", - "deepmerge-ts": "^5.1.0", - "got": "^12.6.1", - "ky": "^0.33.0", + "@wdio/config": "9.2.8", + "@wdio/logger": "9.1.3", + "@wdio/protocols": "9.2.2", + "@wdio/types": "9.2.2", + "@wdio/utils": "9.2.8", + "deepmerge-ts": "^7.0.3", + "undici": "^6.20.1", "ws": "^8.8.0" }, "engines": { - "node": "^16.13 || >=18" + "node": ">=18.20.0" } }, - "node_modules/webdriverio": { - "version": "8.39.1", - "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-8.39.1.tgz", - "integrity": "sha512-dPwLgLNtP+l4vnybz+YFxxH8nBKOP7j6VVzKtfDyTLDQg9rz3U8OA4xMMQCBucnrVXy3KcKxGqlnMa+c4IfWCQ==", + "node_modules/webdriver/node_modules/@types/node": { + "version": "20.17.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.10.tgz", + "integrity": "sha512-/jrvh5h6NXhEauFFexRin69nA0uHJ5gwk4iDivp/DeoEua3uwCUto6PC86IpRITBOs4+6i2I56K5x5b6WYGXHA==", "dev": true, + "optional": true, + "peer": true, "dependencies": { - "@types/node": "^20.1.0", - "@wdio/config": "8.39.0", - "@wdio/logger": "8.38.0", - "@wdio/protocols": "8.38.0", - "@wdio/repl": "8.24.12", - "@wdio/types": "8.39.0", - "@wdio/utils": "8.39.0", - "archiver": "^7.0.0", - "aria-query": "^5.0.0", + "undici-types": "~6.19.2" + } + }, + "node_modules/webdriver/node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/webdriverio": { + "version": "9.4.1", + "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-9.4.1.tgz", + "integrity": "sha512-XIPtRnxSES4CoxH2BfUY/6QzNgEgJEUjMYu7t7SJR8bVfbLRVXAA1ie9kM0MtdLs4oZ2Pr8rR8fqytsA1CjEWw==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@types/node": "^20.11.30", + "@types/sinonjs__fake-timers": "^8.1.5", + "@wdio/config": "9.2.8", + "@wdio/logger": "9.1.3", + "@wdio/protocols": "9.2.2", + "@wdio/repl": "9.0.8", + "@wdio/types": "9.2.2", + "@wdio/utils": "9.2.8", + "archiver": "^7.0.1", + "aria-query": "^5.3.0", + "cheerio": "^1.0.0-rc.12", "css-shorthand-properties": "^1.1.1", "css-value": "^0.0.1", - "devtools-protocol": "^0.0.1302984", - "grapheme-splitter": "^1.0.2", + "grapheme-splitter": "^1.0.4", + "htmlfy": "^0.3.0", "import-meta-resolve": "^4.0.0", "is-plain-obj": "^4.1.0", "jszip": "^3.10.1", "lodash.clonedeep": "^4.5.0", "lodash.zip": "^4.2.0", - "minimatch": "^9.0.0", - "puppeteer-core": "^20.9.0", - "query-selector-shadow-dom": "^1.0.0", - "resq": "^1.9.1", + "minimatch": "^9.0.3", + "query-selector-shadow-dom": "^1.0.1", + "resq": "^1.11.0", "rgb2hex": "0.2.5", - "serialize-error": "^11.0.1", - "webdriver": "8.39.0" + "serialize-error": "^11.0.3", + "urlpattern-polyfill": "^10.0.0", + "webdriver": "9.4.1" }, "engines": { - "node": "^16.13 || >=18" + "node": ">=18.20.0" }, "peerDependencies": { - "devtools": "^8.14.0" + "puppeteer-core": "^22.3.0" }, "peerDependenciesMeta": { - "devtools": { + "puppeteer-core": { "optional": true } } }, + "node_modules/webdriverio/node_modules/@types/node": { + "version": "20.17.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.10.tgz", + "integrity": "sha512-/jrvh5h6NXhEauFFexRin69nA0uHJ5gwk4iDivp/DeoEua3uwCUto6PC86IpRITBOs4+6i2I56K5x5b6WYGXHA==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "undici-types": "~6.19.2" + } + }, + "node_modules/webdriverio/node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "dev": true, + "optional": true, + "peer": true + }, "node_modules/webidl-conversions": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", - "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==" + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "dev": true, + "engines": { + "node": ">=12" + } }, "node_modules/webpack": { - "version": "5.93.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.93.0.tgz", - "integrity": "sha512-Y0m5oEY1LRuwly578VqluorkXbvXKh7U3rLoQCEO04M97ScRr44afGVkI0FQFsXzysk5OgFAxjZAb9rsGQVihA==", - "dev": true, - "dependencies": { - "@types/eslint-scope": "^3.7.3", - "@types/estree": "^1.0.5", - "@webassemblyjs/ast": "^1.12.1", - "@webassemblyjs/wasm-edit": "^1.12.1", - "@webassemblyjs/wasm-parser": "^1.12.1", - "acorn": "^8.7.1", - "acorn-import-attributes": "^1.9.5", - "browserslist": "^4.21.10", + "version": "5.97.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.97.1.tgz", + "integrity": "sha512-EksG6gFY3L1eFMROS/7Wzgrii5mBAFe4rIr3r2BTfo7bcc+DWwFZ4OJ/miOuHJO/A85HwyI4eQ0F6IKXesO7Fg==", + "dev": true, + "optional": true, + "peer": true, + "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.0", + "enhanced-resolve": "^5.17.1", "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", "events": "^3.2.0", @@ -14714,195 +15118,18 @@ } } }, - "node_modules/webpack-cli": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.4.tgz", - "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==", - "dev": true, - "dependencies": { - "@discoveryjs/json-ext": "^0.5.0", - "@webpack-cli/configtest": "^2.1.1", - "@webpack-cli/info": "^2.0.2", - "@webpack-cli/serve": "^2.0.5", - "colorette": "^2.0.14", - "commander": "^10.0.1", - "cross-spawn": "^7.0.3", - "envinfo": "^7.7.3", - "fastest-levenshtein": "^1.0.12", - "import-local": "^3.0.2", - "interpret": "^3.1.1", - "rechoir": "^0.8.0", - "webpack-merge": "^5.7.3" - }, - "bin": { - "webpack-cli": "bin/cli.js" - }, - "engines": { - "node": ">=14.15.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "5.x.x" - }, - "peerDependenciesMeta": { - "@webpack-cli/generators": { - "optional": true - }, - "webpack-bundle-analyzer": { - "optional": true - }, - "webpack-dev-server": { - "optional": true - } - } - }, - "node_modules/webpack-cli/node_modules/commander": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", - "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", - "dev": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/webpack-cli/node_modules/webpack-merge": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz", - "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==", - "dev": true, - "dependencies": { - "clone-deep": "^4.0.1", - "flat": "^5.0.2", - "wildcard": "^2.0.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/webpack-dev-middleware": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-7.1.1.tgz", - "integrity": "sha512-NmRVq4AvRQs66dFWyDR4GsFDJggtSi2Yn38MXLk0nffgF9n/AIP4TFBg2TQKYaRAN4sHuKOTiz9BnNCENDLEVA==", - "dev": true, - "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" - }, - "engines": { - "node": ">= 18.12.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.0.0" - }, - "peerDependenciesMeta": { - "webpack": { - "optional": true - } - } - }, - "node_modules/webpack-dev-middleware/node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/webpack-dev-middleware/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/webpack-dev-middleware/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/webpack-dev-middleware/node_modules/schema-utils": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", - "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", - "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.9.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.1.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/webpack-dev-server": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-5.0.4.tgz", - "integrity": "sha512-dljXhUgx3HqKP2d8J/fUMvhxGhzjeNVarDLcbO/EWMSgRizDkxHQDZQaLFL5VJY9tRBj2Gz+rvCEYYvhbqPHNA==", - "dev": true, - "dependencies": { - "@types/bonjour": "^3.5.13", - "@types/connect-history-api-fallback": "^1.5.4", - "@types/express": "^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", - "default-gateway": "^6.0.3", - "express": "^4.17.3", - "graceful-fs": "^4.2.6", - "html-entities": "^2.4.0", - "http-proxy-middleware": "^2.0.3", - "ipaddr.js": "^2.1.0", - "launch-editor": "^2.6.1", - "open": "^10.0.3", - "p-retry": "^6.2.0", - "rimraf": "^5.0.5", - "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.1.0", - "ws": "^8.16.0" - }, - "bin": { - "webpack-dev-server": "bin/webpack-dev-server.js" + "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==", + "dev": true, + "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" }, "engines": { "node": ">= 18.12.0" @@ -14917,29 +15144,26 @@ "peerDependenciesMeta": { "webpack": { "optional": true - }, - "webpack-cli": { - "optional": true } } }, - "node_modules/webpack-dev-server/node_modules/ajv": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "node_modules/webpack-dev-middleware/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.1", + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" + "require-from-string": "^2.0.2" }, "funding": { "type": "github", "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/webpack-dev-server/node_modules/ajv-keywords": { + "node_modules/webpack-dev-middleware/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==", @@ -14951,91 +15175,16 @@ "ajv": "^8.8.2" } }, - "node_modules/webpack-dev-server/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" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/webpack-dev-server/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==", - "dev": true, - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" - } - }, - "node_modules/webpack-dev-server/node_modules/json-schema-traverse": { + "node_modules/webpack-dev-middleware/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/webpack-dev-server/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/webpack-dev-server/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==", - "dev": true, - "dependencies": { - "lru-cache": "^10.2.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" - }, - "engines": { - "node": ">=16 || 14 >=14.18" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/webpack-dev-server/node_modules/rimraf": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.5.tgz", - "integrity": "sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A==", - "dev": true, - "dependencies": { - "glob": "^10.3.7" - }, - "bin": { - "rimraf": "dist/esm/bin.mjs" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/webpack-dev-server/node_modules/schema-utils": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", - "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "node_modules/webpack-dev-middleware/node_modules/schema-utils": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.0.tgz", + "integrity": "sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==", "dev": true, "dependencies": { "@types/json-schema": "^7.0.9", @@ -15044,7 +15193,7 @@ "ajv-keywords": "^5.1.0" }, "engines": { - "node": ">= 12.13.0" + "node": ">= 10.13.0" }, "funding": { "type": "opencollective", @@ -15065,21 +15214,13 @@ "node": ">=18.0.0" } }, - "node_modules/webpack-sources": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", - "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", - "dev": true, - "dependencies": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" - } - }, "node_modules/webpack/node_modules/eslint-scope": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^4.1.1" @@ -15093,6 +15234,8 @@ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "dev": true, + "optional": true, + "peer": true, "engines": { "node": ">=4.0" } @@ -15102,6 +15245,8 @@ "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", "dev": true, + "optional": true, + "peer": true, "engines": { "node": ">=0.8.x" } @@ -15111,6 +15256,8 @@ "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", "dev": true, + "optional": true, + "peer": true, "engines": { "node": ">=10.13.0" } @@ -15139,26 +15286,49 @@ } }, "node_modules/whatwg-encoding": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", - "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", + "dev": true, "dependencies": { - "iconv-lite": "0.4.24" + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-encoding/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==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, "node_modules/whatwg-mimetype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", - "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==" + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", + "dev": true, + "engines": { + "node": ">=18" + } }, "node_modules/whatwg-url": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-6.5.0.tgz", - "integrity": "sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ==", + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.1.0.tgz", + "integrity": "sha512-jlf/foYIKywAt3x/XWKZ/3rz8OSJPiWktjmk891alJUEjiVxKX9LEO92qH3hv4aJ0mN3MWPvGMCy8jQi95xK4w==", + "dev": true, "dependencies": { - "lodash.sortby": "^4.7.0", - "tr46": "^1.0.1", - "webidl-conversions": "^4.0.2" + "tr46": "^5.0.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=18" } }, "node_modules/which": { @@ -15191,17 +15361,62 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/which-builtin-type": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.0.tgz", + "integrity": "sha512-I+qLGQ/vucCby4tf5HsLmGueEla4ZhwTBSqaooS+Y0BuxN4Cp+okmGuV+8mXZ84KDI9BA+oklo+RzKg0ONdSUA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", + "is-async-function": "^2.0.0", + "is-date-object": "^1.0.5", + "is-finalizationregistry": "^1.1.0", + "is-generator-function": "^1.0.10", + "is-regex": "^1.1.4", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.0.2", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.15" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-collection": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", + "dev": true, + "dependencies": { + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/which-typed-array": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.13.tgz", - "integrity": "sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow==", + "version": "1.1.16", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.16.tgz", + "integrity": "sha512-g+N+GAWiRj66DngFwHvISJd+ITsyphZvD1vChfVg6cEdnzy53GzB3oy0fUNlvhz7H7+MiqhYr26qxQShCpKTTQ==", "dev": true, "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.4", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", "for-each": "^0.3.3", "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0" + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -15226,26 +15441,75 @@ "node": ">=8" } }, - "node_modules/widest-line": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-4.0.1.tgz", - "integrity": "sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==", + "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/winston": { + "version": "3.17.0", + "resolved": "https://registry.npmjs.org/winston/-/winston-3.17.0.tgz", + "integrity": "sha512-DLiFIXYC5fMPxaRg832S6F5mJYvePtmO5G9v9IgUFPhXm9/GkXarH/TUrBAVzhTCzAj9anE/+GjrgXp/54nOgw==", "dev": true, "dependencies": { - "string-width": "^5.0.1" + "@colors/colors": "^1.6.0", + "@dabh/diagnostics": "^2.0.2", + "async": "^3.2.3", + "is-stream": "^2.0.0", + "logform": "^2.7.0", + "one-time": "^1.0.0", + "readable-stream": "^3.4.0", + "safe-stable-stringify": "^2.3.1", + "stack-trace": "0.0.x", + "triple-beam": "^1.3.0", + "winston-transport": "^4.9.0" }, "engines": { - "node": ">=12" + "node": ">= 12.0.0" + } + }, + "node_modules/winston-transport": { + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.9.0.tgz", + "integrity": "sha512-8drMJ4rkgaPo1Me4zD/3WLfI/zPdA9o2IipKODunnGDcuqbHwjsbB79ylv04LCGGzU0xQ6vTznOMpQGaLhhm6A==", + "dev": true, + "dependencies": { + "logform": "^2.7.0", + "readable-stream": "^3.6.2", + "triple-beam": "^1.3.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">= 12.0.0" } }, - "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/winston-transport/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/winston/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } }, "node_modules/word-wrap": { "version": "1.2.5", @@ -15346,7 +15610,9 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/ws": { "version": "8.18.0", @@ -15370,9 +15636,19 @@ } }, "node_modules/xml-name-validator": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", - "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==" + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", + "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true }, "node_modules/xmldom": { "version": "0.1.31", @@ -15383,14 +15659,6 @@ "node": ">=0.1" } }, - "node_modules/xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "engines": { - "node": ">=0.4" - } - }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", @@ -15400,15 +15668,6 @@ "node": ">=10" } }, - "node_modules/yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", - "dev": true, - "engines": { - "node": ">= 6" - } - }, "node_modules/yargs": { "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", @@ -15457,13 +15716,17 @@ } }, "node_modules/yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-3.2.0.tgz", + "integrity": "sha512-Ow9nuGZE+qp1u4JIPvg+uCiUr7xGQWdff7JQSk5VGYTAZMDe2q8lxJ10ygv10qmSj031Ty/6FNJpLO4o1Sgc+w==", "dev": true, + "license": "MIT", "dependencies": { "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" + "pend": "~1.2.0" + }, + "engines": { + "node": ">=12" } }, "node_modules/yauzl/node_modules/buffer-crc32": { @@ -15475,6 +15738,15 @@ "node": "*" } }, + "node_modules/ylru": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ylru/-/ylru-1.4.0.tgz", + "integrity": "sha512-2OQsPNEmBCvXuFlIni/a+Rn+R2pHW9INm0BxXJ4hVDA8TirqMj+J/Rp9ItLatT/5pZqWwefVrTQcHpixsxnVlA==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", @@ -15504,6 +15776,8 @@ "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-6.0.1.tgz", "integrity": "sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "archiver-utils": "^5.0.0", "compress-commons": "^6.0.2", @@ -15518,6 +15792,8 @@ "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", "dev": true, + "optional": true, + "peer": true, "engines": { "node": ">=0.8.x" } @@ -15527,6 +15803,8 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "abort-controller": "^3.0.0", "buffer": "^6.0.3", @@ -15543,6 +15821,8 @@ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "safe-buffer": "~5.2.0" } diff --git a/package.json b/package.json index 9a9fe3a888..264dc7414e 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "url": "git+https://github.com/google/neuroglancer.git" }, "engines": { - "node": ">=20.10 <21 || >=21.2" + "node": ">=22" }, "browserslist": [ "last 2 Chrome versions", @@ -16,7 +16,7 @@ "last 2 Safari versions" ], "scripts": { - "generate-code": "tsx ./config/generate_code.ts", + "generate-code": "tsx ./build_tools/generate-code.ts", "update-conditions": "tsx ./build_tools/update-conditions.ts", "prepare": "tsx ./build_tools/build-package.ts --inplace --if-not-toplevel", "prepack": "tsx ./build_tools/build-package.ts --inplace", @@ -32,65 +32,78 @@ "test:watch": "vitest watch", "benchmark": "vitest bench --run", "benchmark:watch": "vitest bench", - "lint:check": "eslint .", - "lint:fix": "eslint . --fix", + "lint:check": "oxlint && eslint . --cache --format codeframe", + "lint:fix": "oxlint --fix && eslint . --cache --fix --format codeframe && prettier --cache -w -l .", "format:check": "prettier --cache . -c", "format:fix": "prettier --cache -w -l .", "typecheck": "tsc --noEmit", + "typecheck:watch": "tsc --noEmit --watch", "version": "tsx ./build_tools/after-version-change.ts" }, "devDependencies": { + "@eslint/js": "^9.18.0", + "@iodigital/vite-plugin-msw": "^2.0.0", + "@playwright/browser-chromium": "^1.49.1", + "@rspack/cli": "^1.1.8", + "@rspack/core": "^1.1.8", "@types/codemirror": "5.60.15", "@types/gl-matrix": "^2.4.5", + "@types/http-server": "^0.12.4", + "@types/jsdom": "^21.1.7", "@types/lodash-es": "^4.17.12", - "@types/node": "^20.14.12", - "@types/pako": "^2.0.3", - "@types/yargs": "^17.0.32", - "@typescript-eslint/eslint-plugin": "^7.17.0", - "@typescript-eslint/parser": "^7.17.0", - "@vitest/browser": "^2.0.4", - "@vitest/ui": "^2.0.4", + "@types/node": "^22.10.7", + "@types/nunjucks": "^3.2.6", + "@types/s3rver": "^3.7.4", + "@types/yargs": "^17.0.33", + "@vitest/browser": "^3.0.2", + "@vitest/ui": "^3.0.2", + "@vitest/web-worker": "^3.0.2", + "cookie": "^1.0.2", "css-loader": "^7.1.2", - "esbuild": "^0.23.0", - "esbuild-loader": "^4.2.2", - "eslint": "^8.56.0", + "esbuild": "^0.24.2", + "eslint": "^9.18.0", "eslint-formatter-codeframe": "^7.32.1", - "eslint-import-resolver-typescript": "^3.6.1", - "eslint-interactive": "^10.8.0", - "eslint-plugin-import": "^2.29.1", - "eslint-webpack-plugin": "^4.0.1", - "fork-ts-checker-webpack-plugin": "^6.5.3", - "glob": "^11.0.0", - "html-webpack-plugin": "^5.6.0", - "mini-css-extract-plugin": "^2.9.0", - "prettier": "3.3.3", - "style-loader": "^4.0.0", - "svg-inline-loader": "^0.8.2", - "tsx": "^4.16.2", - "typescript": "^5.5.4", - "vitest": "^2.0.4", - "webdriverio": "^8.39.1", - "webpack": "^5.93.0", + "eslint-import-resolver-typescript": "^3.7.0", + "eslint-plugin-import": "^2.31.0", + "eslint-plugin-oxlint": "^0.15.7", + "eslint-rspack-plugin": "^4.2.1", + "express": "^4.21.2", + "glob": "^11.0.1", + "http-server": "^14.1.1", + "jsdom": "^26.0.0", + "msw": "^2.7.0", + "nunjucks": "^3.2.4", + "oxlint": "^0.15.7", + "playwright": "^1.49.1", + "prettier": "3.4.2", + "s3rver": "^3.7.1", + "ts-checker-rspack-plugin": "^1.1.1", + "tsx": "^4.19.2", + "typescript": "^5.7.3", + "typescript-eslint": "^8.20.0", + "vitest": "^3.0.2", "webpack-bundle-analyzer": "^4.10.2", - "webpack-cli": "^5.1.4", - "webpack-dev-server": "^5.0.4", - "webpack-merge": "^6.0.1" + "webpack-merge": "^6.0.1", + "yargs": "^17.7.2", + "yauzl": "^3.2.0" }, "dependencies": { "codemirror": "^5.61.1", + "core-js": "^3.40.0", + "crc-32": "^1.2.2", "gl-matrix": "3.1.0", - "glsl-editor": "^1.0.0", "ikonate": "github:mikolajdobrucki/ikonate#a86b4107c6ec717e7877f880a930d1ccf0b59d89", "lodash-es": "^4.17.21", "nifti-reader-js": "^0.6.8", - "numcodecs": "^0.3.2", - "pako": "^2.1.0" + "numcodecs": "^0.3.2" }, "overrides": { "@puppeteer/browsers": ">=2" }, "files": [ - "lib/**/*" + "src/**/*", + "typings/**/*", + "tsconfig.json" ], "private": true, "type": "module", @@ -103,292 +116,351 @@ "#src/third_party/jpgjs/jpg.js": "./src/third_party/jpgjs/jpg.js", "#src/*.js": "./src/*.ts", "#src/*": "./src/*", + "#tests/fixtures/msw": { + "node": "./tests/fixtures/msw_node.ts", + "default": "./tests/fixtures/msw_browser.ts" + }, + "#tests/fixtures/gl": { + "node": "./tests/fixtures/gl_node.ts", + "default": "./tests/fixtures/gl_browser.ts" + }, + "#tests/*.js": "./tests/*.ts", "#testdata/*": "./testdata/*", "#datasource/boss/backend": { "neuroglancer/datasource/boss:enabled": "./src/datasource/boss/backend.ts", "neuroglancer/datasource:none_by_default": "./src/util/false.ts", - "neuroglancer/datasource/boss:disabled": "./src/datasource/boss/backend.ts", + "neuroglancer/datasource/boss:disabled": "./src/util/false.ts", "default": "./src/datasource/boss/backend.ts" }, "#datasource/boss/async_computation": { "neuroglancer/datasource/boss:enabled": "./src/datasource/boss/async_computation.ts", "neuroglancer/datasource:none_by_default": "./src/util/false.ts", - "neuroglancer/datasource/boss:disabled": "./src/datasource/boss/async_computation.ts", + "neuroglancer/datasource/boss:disabled": "./src/util/false.ts", "default": "./src/datasource/boss/async_computation.ts" }, "#datasource/boss/register_default": { "neuroglancer/datasource/boss:enabled": "./src/datasource/boss/register_default.ts", "neuroglancer/datasource:none_by_default": "./src/util/false.ts", - "neuroglancer/datasource/boss:disabled": "./src/datasource/boss/register_default.ts", + "neuroglancer/datasource/boss:disabled": "./src/util/false.ts", "default": "./src/datasource/boss/register_default.ts" }, "#datasource/boss/register_credentials_provider": { "neuroglancer/python": "./src/util/false.ts", "neuroglancer/datasource/boss:enabled": "./src/datasource/boss/register_credentials_provider.ts", "neuroglancer/datasource:none_by_default": "./src/util/false.ts", - "neuroglancer/datasource/boss:disabled": "./src/datasource/boss/register_credentials_provider.ts", + "neuroglancer/datasource/boss:disabled": "./src/util/false.ts", "default": "./src/datasource/boss/register_credentials_provider.ts" }, "#datasource/brainmaps/backend": { "neuroglancer/datasource/brainmaps:enabled": "./src/datasource/brainmaps/backend.ts", "neuroglancer/datasource:none_by_default": "./src/util/false.ts", - "neuroglancer/datasource/brainmaps:disabled": "./src/datasource/brainmaps/backend.ts", + "neuroglancer/datasource/brainmaps:disabled": "./src/util/false.ts", "default": "./src/datasource/brainmaps/backend.ts" }, "#datasource/brainmaps/async_computation": { "neuroglancer/datasource/brainmaps:enabled": "./src/datasource/brainmaps/async_computation.ts", "neuroglancer/datasource:none_by_default": "./src/util/false.ts", - "neuroglancer/datasource/brainmaps:disabled": "./src/datasource/brainmaps/async_computation.ts", + "neuroglancer/datasource/brainmaps:disabled": "./src/util/false.ts", "default": "./src/datasource/brainmaps/async_computation.ts" }, "#datasource/brainmaps/register_default": { "neuroglancer/datasource/brainmaps:enabled": "./src/datasource/brainmaps/register_default.ts", "neuroglancer/datasource:none_by_default": "./src/util/false.ts", - "neuroglancer/datasource/brainmaps:disabled": "./src/datasource/brainmaps/register_default.ts", + "neuroglancer/datasource/brainmaps:disabled": "./src/util/false.ts", "default": "./src/datasource/brainmaps/register_default.ts" }, "#datasource/brainmaps/register_credentials_provider": { "neuroglancer/python": "./src/util/false.ts", "neuroglancer/datasource/brainmaps:enabled": "./src/datasource/brainmaps/register_credentials_provider.ts", "neuroglancer/datasource:none_by_default": "./src/util/false.ts", - "neuroglancer/datasource/brainmaps:disabled": "./src/datasource/brainmaps/register_credentials_provider.ts", + "neuroglancer/datasource/brainmaps:disabled": "./src/util/false.ts", "default": "./src/datasource/brainmaps/register_credentials_provider.ts" }, "#datasource/deepzoom/backend": { "neuroglancer/datasource/deepzoom:enabled": "./src/datasource/deepzoom/backend.ts", "neuroglancer/datasource:none_by_default": "./src/util/false.ts", - "neuroglancer/datasource/deepzoom:disabled": "./src/datasource/deepzoom/backend.ts", + "neuroglancer/datasource/deepzoom:disabled": "./src/util/false.ts", "default": "./src/datasource/deepzoom/backend.ts" }, "#datasource/deepzoom/async_computation": { "neuroglancer/datasource/deepzoom:enabled": "./src/datasource/deepzoom/async_computation.ts", "neuroglancer/datasource:none_by_default": "./src/util/false.ts", - "neuroglancer/datasource/deepzoom:disabled": "./src/datasource/deepzoom/async_computation.ts", + "neuroglancer/datasource/deepzoom:disabled": "./src/util/false.ts", "default": "./src/datasource/deepzoom/async_computation.ts" }, "#datasource/deepzoom/register_default": { "neuroglancer/datasource/deepzoom:enabled": "./src/datasource/deepzoom/register_default.ts", "neuroglancer/datasource:none_by_default": "./src/util/false.ts", - "neuroglancer/datasource/deepzoom:disabled": "./src/datasource/deepzoom/register_default.ts", + "neuroglancer/datasource/deepzoom:disabled": "./src/util/false.ts", "default": "./src/datasource/deepzoom/register_default.ts" }, "#datasource/dvid/backend": { "neuroglancer/datasource/dvid:enabled": "./src/datasource/dvid/backend.ts", "neuroglancer/datasource:none_by_default": "./src/util/false.ts", - "neuroglancer/datasource/dvid:disabled": "./src/datasource/dvid/backend.ts", + "neuroglancer/datasource/dvid:disabled": "./src/util/false.ts", "default": "./src/datasource/dvid/backend.ts" }, "#datasource/dvid/async_computation": { "neuroglancer/datasource/dvid:enabled": "./src/datasource/dvid/async_computation.ts", "neuroglancer/datasource:none_by_default": "./src/util/false.ts", - "neuroglancer/datasource/dvid:disabled": "./src/datasource/dvid/async_computation.ts", + "neuroglancer/datasource/dvid:disabled": "./src/util/false.ts", "default": "./src/datasource/dvid/async_computation.ts" }, "#datasource/dvid/register_default": { "neuroglancer/datasource/dvid:enabled": "./src/datasource/dvid/register_default.ts", "neuroglancer/datasource:none_by_default": "./src/util/false.ts", - "neuroglancer/datasource/dvid:disabled": "./src/datasource/dvid/register_default.ts", + "neuroglancer/datasource/dvid:disabled": "./src/util/false.ts", "default": "./src/datasource/dvid/register_default.ts" }, "#datasource/dvid/register_credentials_provider": { "neuroglancer/python": "./src/util/false.ts", "neuroglancer/datasource/dvid:enabled": "./src/datasource/dvid/register_credentials_provider.ts", "neuroglancer/datasource:none_by_default": "./src/util/false.ts", - "neuroglancer/datasource/dvid:disabled": "./src/datasource/dvid/register_credentials_provider.ts", + "neuroglancer/datasource/dvid:disabled": "./src/util/false.ts", "default": "./src/datasource/dvid/register_credentials_provider.ts" }, "#datasource/graphene/backend": { "neuroglancer/datasource/graphene:enabled": "./src/datasource/graphene/backend.ts", "neuroglancer/datasource:none_by_default": "./src/util/false.ts", - "neuroglancer/datasource/graphene:disabled": "./src/datasource/graphene/backend.ts", + "neuroglancer/datasource/graphene:disabled": "./src/util/false.ts", "default": "./src/datasource/graphene/backend.ts" }, "#datasource/graphene/async_computation": { "neuroglancer/datasource/graphene:enabled": "./src/datasource/graphene/async_computation.ts", "neuroglancer/datasource:none_by_default": "./src/util/false.ts", - "neuroglancer/datasource/graphene:disabled": "./src/datasource/graphene/async_computation.ts", + "neuroglancer/datasource/graphene:disabled": "./src/util/false.ts", "default": "./src/datasource/graphene/async_computation.ts" }, "#datasource/graphene/register_default": { "neuroglancer/datasource/graphene:enabled": "./src/datasource/graphene/register_default.ts", "neuroglancer/datasource:none_by_default": "./src/util/false.ts", - "neuroglancer/datasource/graphene:disabled": "./src/datasource/graphene/register_default.ts", + "neuroglancer/datasource/graphene:disabled": "./src/util/false.ts", "default": "./src/datasource/graphene/register_default.ts" }, - "#datasource/middleauth/register_credentials_provider": { - "neuroglancer/python": "./src/util/false.ts", - "neuroglancer/datasource/middleauth:enabled": "./src/datasource/middleauth/register_credentials_provider.ts", - "neuroglancer/datasource:none_by_default": "./src/util/false.ts", - "neuroglancer/datasource/middleauth:disabled": "./src/datasource/middleauth/register_credentials_provider.ts", - "default": "./src/datasource/middleauth/register_credentials_provider.ts" - }, "#datasource/n5/backend": { "neuroglancer/datasource/n5:enabled": "./src/datasource/n5/backend.ts", "neuroglancer/datasource:none_by_default": "./src/util/false.ts", - "neuroglancer/datasource/n5:disabled": "./src/datasource/n5/backend.ts", + "neuroglancer/datasource/n5:disabled": "./src/util/false.ts", "default": "./src/datasource/n5/backend.ts" }, "#datasource/n5/async_computation": { "neuroglancer/datasource/n5:enabled": "./src/datasource/n5/async_computation.ts", "neuroglancer/datasource:none_by_default": "./src/util/false.ts", - "neuroglancer/datasource/n5:disabled": "./src/datasource/n5/async_computation.ts", + "neuroglancer/datasource/n5:disabled": "./src/util/false.ts", "default": "./src/datasource/n5/async_computation.ts" }, "#datasource/n5/register_default": { "neuroglancer/datasource/n5:enabled": "./src/datasource/n5/register_default.ts", "neuroglancer/datasource:none_by_default": "./src/util/false.ts", - "neuroglancer/datasource/n5:disabled": "./src/datasource/n5/register_default.ts", + "neuroglancer/datasource/n5:disabled": "./src/util/false.ts", "default": "./src/datasource/n5/register_default.ts" }, - "#datasource/ngauth/register_credentials_provider": { - "neuroglancer/python": "./src/util/false.ts", - "neuroglancer/datasource/ngauth:enabled": "./src/datasource/ngauth/register_credentials_provider.ts", - "neuroglancer/datasource:none_by_default": "./src/util/false.ts", - "neuroglancer/datasource/ngauth:disabled": "./src/datasource/ngauth/register_credentials_provider.ts", - "default": "./src/datasource/ngauth/register_credentials_provider.ts" - }, - "#datasource/nggraph/backend": { - "neuroglancer/datasource/nggraph:enabled": "./src/datasource/nggraph/backend.ts", - "neuroglancer/datasource:none_by_default": "./src/util/false.ts", - "neuroglancer/datasource/nggraph:disabled": "./src/datasource/nggraph/backend.ts", - "default": "./src/datasource/nggraph/backend.ts" - }, "#datasource/nggraph/register_default": { "neuroglancer/datasource/nggraph:enabled": "./src/datasource/nggraph/register_default.ts", "neuroglancer/datasource:none_by_default": "./src/util/false.ts", - "neuroglancer/datasource/nggraph:disabled": "./src/datasource/nggraph/register_default.ts", + "neuroglancer/datasource/nggraph:disabled": "./src/util/false.ts", "default": "./src/datasource/nggraph/register_default.ts" }, "#datasource/nifti/backend": { "neuroglancer/datasource/nifti:enabled": "./src/datasource/nifti/backend.ts", "neuroglancer/datasource:none_by_default": "./src/util/false.ts", - "neuroglancer/datasource/nifti:disabled": "./src/datasource/nifti/backend.ts", + "neuroglancer/datasource/nifti:disabled": "./src/util/false.ts", "default": "./src/datasource/nifti/backend.ts" }, - "#datasource/nifti/async_computation": { - "neuroglancer/datasource/nifti:enabled": "./src/datasource/nifti/async_computation.ts", - "neuroglancer/datasource:none_by_default": "./src/util/false.ts", - "neuroglancer/datasource/nifti:disabled": "./src/datasource/nifti/async_computation.ts", - "default": "./src/datasource/nifti/async_computation.ts" - }, "#datasource/nifti/register_default": { "neuroglancer/datasource/nifti:enabled": "./src/datasource/nifti/register_default.ts", "neuroglancer/datasource:none_by_default": "./src/util/false.ts", - "neuroglancer/datasource/nifti:disabled": "./src/datasource/nifti/register_default.ts", + "neuroglancer/datasource/nifti:disabled": "./src/util/false.ts", "default": "./src/datasource/nifti/register_default.ts" }, "#datasource/obj/backend": { "neuroglancer/datasource/obj:enabled": "./src/datasource/obj/backend.ts", "neuroglancer/datasource:none_by_default": "./src/util/false.ts", - "neuroglancer/datasource/obj:disabled": "./src/datasource/obj/backend.ts", + "neuroglancer/datasource/obj:disabled": "./src/util/false.ts", "default": "./src/datasource/obj/backend.ts" }, "#datasource/obj/async_computation": { "neuroglancer/datasource/obj:enabled": "./src/datasource/obj/async_computation.ts", "neuroglancer/datasource:none_by_default": "./src/util/false.ts", - "neuroglancer/datasource/obj:disabled": "./src/datasource/obj/async_computation.ts", + "neuroglancer/datasource/obj:disabled": "./src/util/false.ts", "default": "./src/datasource/obj/async_computation.ts" }, "#datasource/obj/register_default": { "neuroglancer/datasource/obj:enabled": "./src/datasource/obj/register_default.ts", "neuroglancer/datasource:none_by_default": "./src/util/false.ts", - "neuroglancer/datasource/obj:disabled": "./src/datasource/obj/register_default.ts", + "neuroglancer/datasource/obj:disabled": "./src/util/false.ts", "default": "./src/datasource/obj/register_default.ts" }, "#datasource/precomputed/backend": { "neuroglancer/datasource/precomputed:enabled": "./src/datasource/precomputed/backend.ts", "neuroglancer/datasource:none_by_default": "./src/util/false.ts", - "neuroglancer/datasource/precomputed:disabled": "./src/datasource/precomputed/backend.ts", + "neuroglancer/datasource/precomputed:disabled": "./src/util/false.ts", "default": "./src/datasource/precomputed/backend.ts" }, "#datasource/precomputed/async_computation": { "neuroglancer/datasource/precomputed:enabled": "./src/datasource/precomputed/async_computation.ts", "neuroglancer/datasource:none_by_default": "./src/util/false.ts", - "neuroglancer/datasource/precomputed:disabled": "./src/datasource/precomputed/async_computation.ts", + "neuroglancer/datasource/precomputed:disabled": "./src/util/false.ts", "default": "./src/datasource/precomputed/async_computation.ts" }, "#datasource/precomputed/register_default": { "neuroglancer/datasource/precomputed:enabled": "./src/datasource/precomputed/register_default.ts", "neuroglancer/datasource:none_by_default": "./src/util/false.ts", - "neuroglancer/datasource/precomputed:disabled": "./src/datasource/precomputed/register_default.ts", + "neuroglancer/datasource/precomputed:disabled": "./src/util/false.ts", "default": "./src/datasource/precomputed/register_default.ts" }, "#datasource/python/backend": { "neuroglancer/python": "./src/datasource/python/backend.ts", "default": "./src/util/false.ts" }, + "#datasource/python/register_default": { + "neuroglancer/python": "./src/datasource/python/register_default.ts", + "default": "./src/util/false.ts" + }, "#datasource/render/backend": { "neuroglancer/datasource/render:enabled": "./src/datasource/render/backend.ts", "neuroglancer/datasource:none_by_default": "./src/util/false.ts", - "neuroglancer/datasource/render:disabled": "./src/datasource/render/backend.ts", + "neuroglancer/datasource/render:disabled": "./src/util/false.ts", "default": "./src/datasource/render/backend.ts" }, "#datasource/render/async_computation": { "neuroglancer/datasource/render:enabled": "./src/datasource/render/async_computation.ts", "neuroglancer/datasource:none_by_default": "./src/util/false.ts", - "neuroglancer/datasource/render:disabled": "./src/datasource/render/async_computation.ts", + "neuroglancer/datasource/render:disabled": "./src/util/false.ts", "default": "./src/datasource/render/async_computation.ts" }, "#datasource/render/register_default": { "neuroglancer/datasource/render:enabled": "./src/datasource/render/register_default.ts", "neuroglancer/datasource:none_by_default": "./src/util/false.ts", - "neuroglancer/datasource/render:disabled": "./src/datasource/render/register_default.ts", + "neuroglancer/datasource/render:disabled": "./src/util/false.ts", "default": "./src/datasource/render/register_default.ts" }, "#datasource/vtk/backend": { "neuroglancer/datasource/vtk:enabled": "./src/datasource/vtk/backend.ts", "neuroglancer/datasource:none_by_default": "./src/util/false.ts", - "neuroglancer/datasource/vtk:disabled": "./src/datasource/vtk/backend.ts", + "neuroglancer/datasource/vtk:disabled": "./src/util/false.ts", "default": "./src/datasource/vtk/backend.ts" }, "#datasource/vtk/async_computation": { "neuroglancer/datasource/vtk:enabled": "./src/datasource/vtk/async_computation.ts", "neuroglancer/datasource:none_by_default": "./src/util/false.ts", - "neuroglancer/datasource/vtk:disabled": "./src/datasource/vtk/async_computation.ts", + "neuroglancer/datasource/vtk:disabled": "./src/util/false.ts", "default": "./src/datasource/vtk/async_computation.ts" }, "#datasource/vtk/register_default": { "neuroglancer/datasource/vtk:enabled": "./src/datasource/vtk/register_default.ts", "neuroglancer/datasource:none_by_default": "./src/util/false.ts", - "neuroglancer/datasource/vtk:disabled": "./src/datasource/vtk/register_default.ts", + "neuroglancer/datasource/vtk:disabled": "./src/util/false.ts", "default": "./src/datasource/vtk/register_default.ts" }, "#datasource/zarr/backend": { "neuroglancer/datasource/zarr:enabled": "./src/datasource/zarr/backend.ts", "neuroglancer/datasource:none_by_default": "./src/util/false.ts", - "neuroglancer/datasource/zarr:disabled": "./src/datasource/zarr/backend.ts", + "neuroglancer/datasource/zarr:disabled": "./src/util/false.ts", "default": "./src/datasource/zarr/backend.ts" }, "#datasource/zarr/async_computation": { "neuroglancer/datasource/zarr:enabled": "./src/datasource/zarr/async_computation.ts", "neuroglancer/datasource:none_by_default": "./src/util/false.ts", - "neuroglancer/datasource/zarr:disabled": "./src/datasource/zarr/async_computation.ts", + "neuroglancer/datasource/zarr:disabled": "./src/util/false.ts", "default": "./src/datasource/zarr/async_computation.ts" }, "#datasource/zarr/register_default": { "neuroglancer/datasource/zarr:enabled": "./src/datasource/zarr/register_default.ts", "neuroglancer/datasource:none_by_default": "./src/util/false.ts", - "neuroglancer/datasource/zarr:disabled": "./src/datasource/zarr/register_default.ts", + "neuroglancer/datasource/zarr:disabled": "./src/util/false.ts", "default": "./src/datasource/zarr/register_default.ts" }, + "#kvstore/byte_range/register": { + "neuroglancer/kvstore/byte_range:enabled": "./src/kvstore/byte_range/register.ts", + "neuroglancer/kvstore:none_by_default": "./src/util/false.ts", + "neuroglancer/kvstore/byte_range:disabled": "./src/util/false.ts", + "default": "./src/kvstore/byte_range/register.ts" + }, + "#kvstore/gcs/register": { + "neuroglancer/kvstore/gcs:enabled": "./src/kvstore/gcs/register.ts", + "neuroglancer/kvstore:none_by_default": "./src/util/false.ts", + "neuroglancer/kvstore/gcs:disabled": "./src/util/false.ts", + "default": "./src/kvstore/gcs/register.ts" + }, + "#kvstore/gzip/register": { + "neuroglancer/kvstore/gzip:enabled": "./src/kvstore/gzip/register.ts", + "neuroglancer/kvstore:none_by_default": "./src/util/false.ts", + "neuroglancer/kvstore/gzip:disabled": "./src/util/false.ts", + "default": "./src/kvstore/gzip/register.ts" + }, + "#kvstore/http/register": { + "neuroglancer/kvstore/http:enabled": "./src/kvstore/http/register.ts", + "neuroglancer/kvstore:none_by_default": "./src/util/false.ts", + "neuroglancer/kvstore/http:disabled": "./src/util/false.ts", + "default": "./src/kvstore/http/register.ts" + }, + "#kvstore/middleauth/register": { + "neuroglancer/kvstore/middleauth:enabled": "./src/kvstore/middleauth/register.ts", + "neuroglancer/kvstore:none_by_default": "./src/util/false.ts", + "neuroglancer/kvstore/middleauth:disabled": "./src/util/false.ts", + "default": "./src/kvstore/middleauth/register.ts" + }, + "#kvstore/middleauth/register_credentials_provider": { + "neuroglancer/python": "./src/util/false.ts", + "neuroglancer/kvstore/middleauth:enabled": "./src/kvstore/middleauth/register_credentials_provider.ts", + "neuroglancer/kvstore:none_by_default": "./src/util/false.ts", + "neuroglancer/kvstore/middleauth:disabled": "./src/util/false.ts", + "default": "./src/kvstore/middleauth/register_credentials_provider.ts" + }, + "#kvstore/ngauth/register": { + "neuroglancer/kvstore/ngauth:enabled": "./src/kvstore/ngauth/register.ts", + "neuroglancer/kvstore:none_by_default": "./src/util/false.ts", + "neuroglancer/kvstore/ngauth:disabled": "./src/util/false.ts", + "default": "./src/kvstore/ngauth/register.ts" + }, + "#kvstore/ngauth/register_credentials_provider": { + "neuroglancer/python": "./src/util/false.ts", + "neuroglancer/kvstore/ngauth:enabled": "./src/kvstore/ngauth/register_credentials_provider.ts", + "neuroglancer/kvstore:none_by_default": "./src/util/false.ts", + "neuroglancer/kvstore/ngauth:disabled": "./src/util/false.ts", + "default": "./src/kvstore/ngauth/register_credentials_provider.ts" + }, + "#kvstore/s3/register": { + "neuroglancer/kvstore/s3:enabled": "./src/kvstore/s3/register.ts", + "neuroglancer/kvstore:none_by_default": "./src/util/false.ts", + "neuroglancer/kvstore/s3:disabled": "./src/util/false.ts", + "default": "./src/kvstore/s3/register.ts" + }, + "#kvstore/zip/register_frontend": { + "neuroglancer/kvstore/zip:enabled": "./src/kvstore/zip/register_frontend.ts", + "neuroglancer/kvstore:none_by_default": "./src/util/false.ts", + "neuroglancer/kvstore/zip:disabled": "./src/util/false.ts", + "default": "./src/kvstore/zip/register_frontend.ts" + }, + "#kvstore/zip/register_backend": { + "neuroglancer/kvstore/zip:enabled": "./src/kvstore/zip/register_backend.ts", + "neuroglancer/kvstore:none_by_default": "./src/util/false.ts", + "neuroglancer/kvstore/zip:disabled": "./src/util/false.ts", + "default": "./src/kvstore/zip/register_backend.ts" + }, "#layer/annotation": { "neuroglancer/layer/annotation:enabled": "./src/layer/annotation/index.ts", "neuroglancer/layer:none_by_default": "./src/util/false.ts", + "neuroglancer/layer/annotation:disabled": "./src/util/false.ts", "default": "./src/layer/annotation/index.ts" }, "#layer/image": { "neuroglancer/layer/image:enabled": "./src/layer/image/index.ts", "neuroglancer/layer:none_by_default": "./src/util/false.ts", + "neuroglancer/layer/image:disabled": "./src/util/false.ts", "default": "./src/layer/image/index.ts" }, "#layer/segmentation": { "neuroglancer/layer/segmentation:enabled": "./src/layer/segmentation/index.ts", "neuroglancer/layer:none_by_default": "./src/util/false.ts", + "neuroglancer/layer/segmentation:disabled": "./src/util/false.ts", "default": "./src/layer/segmentation/index.ts" }, "#layer/single_mesh": { "neuroglancer/layer/single_mesh:enabled": "./src/layer/single_mesh/index.ts", "neuroglancer/layer:none_by_default": "./src/util/false.ts", + "neuroglancer/layer/single_mesh:disabled": "./src/util/false.ts", "default": "./src/layer/single_mesh/index.ts" }, "#main": { diff --git a/pyproject.toml b/pyproject.toml index 3474d58d80..c78059e51e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,6 +31,7 @@ exclude = [ "/guide_video_recorder/", "^docs/", "^build/", + "^testdata/", ] [[tool.mypy.overrides]] diff --git a/python/neuroglancer/coordinate_space.py b/python/neuroglancer/coordinate_space.py index 26c361a44c..4e14c42546 100644 --- a/python/neuroglancer/coordinate_space.py +++ b/python/neuroglancer/coordinate_space.py @@ -237,6 +237,7 @@ def __init__( names_tuple = tuple(names) rank = len(names_tuple) self.names = names_tuple + scales_array: np.typing.NDArray[np.float64] if scales is None: scales_array = np.ones(rank, dtype=np.float64) else: diff --git a/python/neuroglancer/server.py b/python/neuroglancer/server.py index f3408f6e36..11e7ea47d7 100644 --- a/python/neuroglancer/server.py +++ b/python/neuroglancer/server.py @@ -538,6 +538,8 @@ def set_dev_server_content_source(): "dev-server-python", "--", "--port=0", + "--no-lint", + "--no-typecheck", ], cwd=root_dir, stdin=subprocess.PIPE, diff --git a/python/neuroglancer/viewer_config_state.py b/python/neuroglancer/viewer_config_state.py index 27bb04d596..ee069dbdae 100644 --- a/python/neuroglancer/viewer_config_state.py +++ b/python/neuroglancer/viewer_config_state.py @@ -334,6 +334,9 @@ class ConfigState(JsonObjectWrapper): show_layer_side_panel_button = showLayerSidePanelButton = wrapped_property( "showLayerSidePanelButton", optional(bool, True) ) + show_tool_palette_button = showToolPaletteButton = wrapped_property( + "showToolPaletteButton", optional(bool, True) + ) show_layer_list_panel_button = showLayerListPanelButton = wrapped_property( "showLayerListPanelButton", optional(bool, True) ) diff --git a/python/neuroglancer/viewer_state.py b/python/neuroglancer/viewer_state.py index 723edb993e..7f10f557e6 100644 --- a/python/neuroglancer/viewer_state.py +++ b/python/neuroglancer/viewer_state.py @@ -152,6 +152,17 @@ def export_tool(tool_class): return tool_class +@export +class LayerTool(Tool): + __slots__ = () + + layer = wrapped_property("layer", optional(str)) + """Name of the layer to which this tool applies. + + Only valid for tools contained within `~ToolPalette.tools`. + """ + + @export_tool class PlacePointTool(Tool): __slots__ = () @@ -177,164 +188,164 @@ class PlaceEllipsoidTool(Tool): @export_tool -class BlendTool(Tool): +class BlendTool(LayerTool): __slots__ = () TOOL_TYPE = "blend" @export_tool -class OpacityTool(Tool): +class OpacityTool(LayerTool): __slots__ = () TOOL_TYPE = "opacity" @export_tool -class VolumeRenderingTool(Tool): +class VolumeRenderingTool(LayerTool): __slots__ = () TOOL_TYPE = "volumeRendering" @export_tool -class VolumeRenderingGainTool(Tool): +class VolumeRenderingGainTool(LayerTool): __slots__ = () TOOL_TYPE = "volumeRenderingGain" @export_tool -class VolumeRenderingDepthSamplesTool(Tool): +class VolumeRenderingDepthSamplesTool(LayerTool): __slots__ = () TOOL_TYPE = "volumeRenderingDepthSamples" @export_tool -class CrossSectionRenderScaleTool(Tool): +class CrossSectionRenderScaleTool(LayerTool): __slots__ = () TOOL_TYPE = "crossSectionRenderScale" @export_tool -class SelectedAlphaTool(Tool): +class SelectedAlphaTool(LayerTool): __slots__ = () TOOL_TYPE = "selectedAlpha" @export_tool -class NotSelectedAlphaTool(Tool): +class NotSelectedAlphaTool(LayerTool): __slots__ = () TOOL_TYPE = "notSelectedAlpha" @export_tool -class ObjectAlphaTool(Tool): +class ObjectAlphaTool(LayerTool): __slots__ = () TOOL_TYPE = "objectAlpha" @export_tool -class HideSegmentZeroTool(Tool): +class HideSegmentZeroTool(LayerTool): __slots__ = () TOOL_TYPE = "hideSegmentZero" @export_tool -class HoverHighlightTool(Tool): +class HoverHighlightTool(LayerTool): __slots__ = () TOOL_TYPE = "hoverHighlight" @export_tool -class BaseSegmentColoringTool(Tool): +class BaseSegmentColoringTool(LayerTool): __slots__ = () TOOL_TYPE = "baseSegmentColoring" @export_tool -class IgnoreNullVisibleSetTool(Tool): +class IgnoreNullVisibleSetTool(LayerTool): __slots__ = () TOOL_TYPE = "ignoreNullVisibleSet" @export_tool -class ColorSeedTool(Tool): +class ColorSeedTool(LayerTool): __slots__ = () TOOL_TYPE = "colorSeed" @export_tool -class SegmentDefaultColorTool(Tool): +class SegmentDefaultColorTool(LayerTool): __slots__ = () TOOL_TYPE = "segmentDefaultColor" @export_tool -class MeshRenderScaleTool(Tool): +class MeshRenderScaleTool(LayerTool): __slots__ = () TOOL_TYPE = "meshRenderScale" @export_tool -class MeshSilhouetteRenderingTool(Tool): +class MeshSilhouetteRenderingTool(LayerTool): __slots__ = () TOOL_TYPE = "meshSilhouetteRendering" @export_tool -class SaturationTool(Tool): +class SaturationTool(LayerTool): __slots__ = () TOOL_TYPE = "saturation" @export_tool -class SkeletonRenderingMode2dTool(Tool): +class SkeletonRenderingMode2dTool(LayerTool): __slots__ = () TOOL_TYPE = "skeletonRendering.mode2d" @export_tool -class SkeletonRenderingMode3dTool(Tool): +class SkeletonRenderingMode3dTool(LayerTool): __slots__ = () TOOL_TYPE = "skeletonRendering.mode3d" @export_tool -class SkeletonRenderingLineWidth2dTool(Tool): +class SkeletonRenderingLineWidth2dTool(LayerTool): __slots__ = () TOOL_TYPE = "skeletonRendering.lineWidth2d" @export_tool -class SkeletonRenderingLineWidth3dTool(Tool): +class SkeletonRenderingLineWidth3dTool(LayerTool): __slots__ = () TOOL_TYPE = "skeletonRendering.lineWidth3d" @export_tool -class ShaderControlTool(Tool): +class ShaderControlTool(LayerTool): __slots__ = () TOOL_TYPE = "shaderControl" control = wrapped_property("control", str) @export_tool -class MergeSegmentsTool(Tool): +class MergeSegmentsTool(LayerTool): __slots__ = () TOOL_TYPE = "mergeSegments" @export_tool -class SplitSegmentsTool(Tool): +class SplitSegmentsTool(LayerTool): __slots__ = () TOOL_TYPE = "splitSegments" @export_tool -class SelectSegmentsTool(Tool): +class SelectSegmentsTool(LayerTool): __slots__ = () TOOL_TYPE = "selectSegments" @export_tool -class DimensionTool(Tool): +class DimensionTool(LayerTool): __slots__ = () TOOL_TYPE = "dimension" dimension = wrapped_property("dimension", str) @@ -342,6 +353,7 @@ class DimensionTool(Tool): @export class SidePanelLocation(JsonObjectWrapper): + __slots__ = () side = wrapped_property("side", optional(str)) visible = wrapped_property("visible", optional(bool)) size = wrapped_property("size", optional(int)) @@ -350,8 +362,16 @@ class SidePanelLocation(JsonObjectWrapper): col = wrapped_property("col", optional(int)) +@export +class ToolPalette(SidePanelLocation): + __slots__ = () + tools = wrapped_property("tools", typed_list(Tool)) + query = wrapped_property("query", optional(str)) + + @export class SelectedLayerState(SidePanelLocation): + __slots__ = () layer = wrapped_property("layer", optional(str)) @@ -1827,6 +1847,9 @@ class ViewerState(JsonObjectWrapper): tool_bindings = toolBindings = wrapped_property( "toolBindings", typed_map(key_type=str, value_type=Tool) ) + tool_palettes = toolPalettes = wrapped_property( + "toolPalettes", typed_map(key_type=str, value_type=ToolPalette) + ) @staticmethod def interpolate(a, b, t): diff --git a/python/neuroglancer/webdriver.py b/python/neuroglancer/webdriver.py index ed93f73f75..83b5255bd5 100644 --- a/python/neuroglancer/webdriver.py +++ b/python/neuroglancer/webdriver.py @@ -35,6 +35,7 @@ def __init__( self, headless=True, browser="chrome", + browser_binary_path: Optional[str] = None, window_size=(1920, 1080), debug=False, docker=False, @@ -50,6 +51,7 @@ def __init__( list(extra_command_line_args) if extra_command_line_args else [] ) self.debug = debug + self.browser_binary_path = browser_binary_path self._log_listeners_lock = threading.Lock() self._log_listeners: dict[LogListener, None] = {} @@ -70,6 +72,8 @@ def _init_chrome(self): if self.headless: chrome_options.add_argument("--headless=new") chrome_options.add_experimental_option("excludeSwitches", ["enable-automation"]) + if self.browser_binary_path: + chrome_options.binary_location = self.browser_binary_path if self.docker: # https://www.intricatecloud.io/2019/05/running-webdriverio-tests-using-headless-chrome-inside-a-container/ chrome_options.add_argument("--no-sandbox") @@ -90,6 +94,8 @@ def _init_firefox(self): if self.headless: options.add_argument("--headless") options.arguments.extend(self.extra_command_line_args) + if self.browser_binary_path: + options.binary_location = self.browser_binary_path self.driver = selenium.webdriver.Firefox( options=options, ) diff --git a/python/neuroglancer/write_annotations.py b/python/neuroglancer/write_annotations.py index 272cd80cf6..8a204e0fc1 100644 --- a/python/neuroglancer/write_annotations.py +++ b/python/neuroglancer/write_annotations.py @@ -82,6 +82,8 @@ def _get_dtype_for_properties( class AnnotationWriter: annotations: list[Annotation] related_annotations: list[dict[int, list[Annotation]]] + lower_bound: np.typing.NDArray[np.float64] + upper_bound: np.typing.NDArray[np.float64] def __init__( self, @@ -172,11 +174,11 @@ def _add_two_point_obj( def _add_obj(self, coords: Sequence[float], id: Optional[int], **kwargs): encoded = np.zeros(shape=(), dtype=self.dtype) - encoded[()]["geometry"] = coords + encoded[()]["geometry"] = coords # type: ignore[call-overload] for i, p in enumerate(self.properties): if p.id in kwargs: - encoded[()][f"property{i}"] = kwargs.pop(p.id) + encoded[()][f"property{i}"] = kwargs.pop(p.id) # type: ignore[call-overload] related_ids = [] for relationship in self.relationships: diff --git a/python/tests/client_test.py b/python/tests/client_test.py index 50f45ce3d4..c21d474b46 100644 --- a/python/tests/client_test.py +++ b/python/tests/client_test.py @@ -16,6 +16,7 @@ import sys import threading import time +import urllib.request import filelock import neuroglancer.static_file_server @@ -80,6 +81,14 @@ def thread_func(f): assert url is not None + while True: + try: + assert urllib.request.urlopen(url).status == 200 + break + except Exception as e: + print(f"URL {url} not yet ready: {e}") + time.sleep(0.1) + return capture_screenshot(webdriver, url, test_fragment) finally: if sys.platform == "win32": @@ -139,7 +148,7 @@ def capture_screenshot(webdriver, url, test_fragment): webdriver.driver.switch_to.window(original_window_handle) -TEST_FRAGMENT = "#!%7B%22dimensions%22:%7B%22x%22:%5B8e-9%2C%22m%22%5D%2C%22y%22:%5B8e-9%2C%22m%22%5D%2C%22z%22:%5B8e-9%2C%22m%22%5D%7D%2C%22position%22:%5B22316.904296875%2C21921.87890625%2C24029.763671875%5D%2C%22crossSectionScale%22:1%2C%22crossSectionDepth%22:-37.62185354999912%2C%22projectionOrientation%22:%5B-0.1470303237438202%2C0.5691322684288025%2C0.19562694430351257%2C0.7849844694137573%5D%2C%22projectionScale%22:118020.30607575581%2C%22layers%22:%5B%7B%22type%22:%22image%22%2C%22source%22:%22precomputed://gs://neuroglancer-janelia-flyem-hemibrain/emdata/clahe_yz/jpeg%22%2C%22tab%22:%22source%22%2C%22name%22:%22emdata%22%7D%2C%7B%22type%22:%22segmentation%22%2C%22source%22:%22precomputed://gs://neuroglancer-janelia-flyem-hemibrain/v1.0/segmentation%22%2C%22tab%22:%22segments%22%2C%22segments%22:%5B%221944507292%22%5D%2C%22name%22:%22segmentation%22%7D%5D%2C%22showSlices%22:false%2C%22selectedLayer%22:%7B%22layer%22:%22segmentation%22%7D%2C%22layout%22:%22xy-3d%22%7D" +TEST_FRAGMENT = "#!%7B%22dimensions%22:%7B%22x%22:%5B8e-9%2C%22m%22%5D%2C%22y%22:%5B8e-9%2C%22m%22%5D%2C%22z%22:%5B8e-9%2C%22m%22%5D%7D%2C%22position%22:%5B22316.904296875%2C21921.87890625%2C24029.763671875%5D%2C%22crossSectionScale%22:1%2C%22crossSectionDepth%22:-37.62185354999912%2C%22projectionOrientation%22:%5B-0.1470303237438202%2C0.5691322684288025%2C0.19562694430351257%2C0.7849844694137573%5D%2C%22projectionScale%22:118020.30607575581%2C%22layers%22:%5B%7B%22type%22:%22image%22%2C%22source%22:%22precomputed://gs://neuroglancer-janelia-flyem-hemibrain/emdata/clahe_yz/jpeg%22%2C%22tab%22:%22rendering%22%2C%22crossSectionRenderScale%22:4%2C%22name%22:%22emdata%22%7D%2C%7B%22type%22:%22segmentation%22%2C%22source%22:%22precomputed://gs://neuroglancer-janelia-flyem-hemibrain/v1.0/segmentation%22%2C%22tab%22:%22rendering%22%2C%22segments%22:%5B%221944507292%22%5D%2C%22name%22:%22segmentation%22%7D%5D%2C%22showSlices%22:false%2C%22selectedLayer%22:%7B%22layer%22:%22emdata%22%7D%2C%22layout%22:%22xy-3d%22%2C%22statistics%22:%7B%22size%22:232%7D%7D" @pytest.fixture(scope="session") @@ -162,6 +171,8 @@ def expected_screenshot(request, webdriver_generic): # Disable parcel since it currently has "failed to resolve bundle" errors. # "parcel", "webpack", + "rsbuild", + "rspack", ] for package in ["source", "built"] ] @@ -201,7 +212,11 @@ def do_build(): subprocess.run( ["npm", "install", "--no-fund", "--no-audit"], cwd=root_dir, check=True ) - subprocess.run(["npm", "run", "build-package"], cwd=root_dir, check=True) + subprocess.run( + ["npm", "run", "build-package", "--", "--skip-declarations"], + cwd=root_dir, + check=True, + ) get_xdist_session_value( do_build, @@ -270,7 +285,6 @@ def compare_screenshot(screenshot, expected_screenshot, extras, threshold=20): pytest.fail(f"Screenshots don't match, max_difference={max_difference}") -# Flaky due to https://github.com/parcel-bundler/parcel/issues/9476 @pytest.mark.flaky(reruns=5) @pytest.mark.timeout(timeout=60, func_only=True) def test_dev_server( @@ -292,7 +306,6 @@ def test_dev_server( ) -# Flaky due to https://github.com/parcel-bundler/parcel/issues/9476 @pytest.mark.flaky(reruns=5) @pytest.mark.timeout(timeout=60, func_only=True) def test_build( @@ -314,6 +327,7 @@ def test_build( ) +@pytest.mark.flaky(reruns=5) @pytest.mark.timeout(timeout=60, func_only=True) def test_root_build( request, diff --git a/python/tests/conftest.py b/python/tests/conftest.py index 23fcb184bc..6c6df3c33b 100644 --- a/python/tests/conftest.py +++ b/python/tests/conftest.py @@ -62,6 +62,10 @@ def pytest_addoption(parser): default="chrome", help="Specifies the browser to use.", ) + parser.addoption( + "--browser-binary-path", + help="Overrides default browser executable path.", + ) parser.addoption( "--skip-browser-tests", action="store_true", @@ -89,6 +93,7 @@ def _webdriver_internal(request): docker=request.config.getoption("--webdriver-docker"), debug=request.config.getoption("--debug-webdriver"), browser=request.config.getoption("--browser"), + browser_binary_path=request.config.getoption("--browser-binary-path"), ) if request.config.getoption("--neuroglancer-server-debug"): neuroglancer.server.debug = True @@ -105,6 +110,7 @@ def webdriver_generic(request): docker=request.config.getoption("--webdriver-docker"), debug=request.config.getoption("--debug-webdriver"), browser=request.config.getoption("--browser"), + browser_binary_path=request.config.getoption("--browser-binary-path"), ) atexit.register(webdriver.driver.close) return webdriver diff --git a/python/tests/n5_test.py b/python/tests/n5_test.py index d03e23009e..d9432b46a1 100644 --- a/python/tests/n5_test.py +++ b/python/tests/n5_test.py @@ -19,14 +19,16 @@ import numpy as np import pytest -TEST_DATA_DIR = pathlib.Path(__file__).parent.parent / "testdata" - @pytest.mark.parametrize( "spec", [ {"driver": "n5", "metadata": {"compression": {"type": "raw"}}}, {"driver": "n5", "metadata": {"compression": {"type": "gzip"}}}, + { + "driver": "n5", + "metadata": {"compression": {"type": "gzip", "useZlib": True}}, + }, { "driver": "n5", "metadata": { @@ -38,8 +40,7 @@ } }, }, - # TODO(jbms): Add once tensorstore supports zstd - # {"driver": "n5", "metadata": {"compression": {"type": "zstd"}}}, + {"driver": "n5", "metadata": {"compression": {"type": "zstd"}}}, ], ids=str, ) diff --git a/python/tests/on_demand_mesh_generator_test.py b/python/tests/on_demand_mesh_generator_test.py index b1f265d043..8e28af49b5 100644 --- a/python/tests/on_demand_mesh_generator_test.py +++ b/python/tests/on_demand_mesh_generator_test.py @@ -20,7 +20,7 @@ import pytest from neuroglancer import local_volume, test_util, viewer_state -testdata_dir = os.path.join(os.path.dirname(__file__), "..", "testdata", "mesh") +testdata_dir = os.path.join(os.path.dirname(__file__), "..", "..", "testdata", "mesh") @pytest.mark.xfail( diff --git a/python/tests/precomputed_test.py b/python/tests/precomputed_test.py new file mode 100644 index 0000000000..53e9f6040e --- /dev/null +++ b/python/tests/precomputed_test.py @@ -0,0 +1,93 @@ +# @license +# Copyright 2023 Google Inc. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Tests the n5 datasource.""" + +import pathlib + +import neuroglancer +import numpy as np +import pytest + + +@pytest.mark.parametrize( + "spec", + [ + { + "driver": "neuroglancer_precomputed", + "scale_metadata": {"encoding": "png", "chunk_size": [8, 9, 1]}, + "dtype": "uint8", + "schema": {"domain": {"shape": [10, 20, 5, num_channels]}}, + } + for num_channels in [1, 2, 3, 4] + ] + + [ + # Currently TensorStore does not support uint16 with more than one channel. + { + "driver": "neuroglancer_precomputed", + "scale_metadata": {"encoding": "png"}, + "dtype": "uint16", + "schema": {"domain": {"shape": [10, 20, 5, 1]}}, + } + ] + + [ + # Due to a tensorstore bug (https://github.com/google/neuroglancer/issues/677) + # the block shape must be square. + { + "driver": "neuroglancer_precomputed", + "scale_metadata": {"encoding": "jpeg", "chunk_size": [10, 10, 1]}, + "dtype": "uint8", + "schema": {"domain": {"shape": [10, 20, 1, num_channels]}}, + } + for num_channels in [1, 3] + ], + ids=str, +) +def test_precomputed(tempdir_server: tuple[pathlib.Path, str], webdriver, spec): + import tensorstore as ts + + tmp_path, server_url = tempdir_server + + full_spec = { + "kvstore": { + "driver": "file", + "path": str(tmp_path), + } + } + full_spec.update(spec) + + store = ts.open(full_spec, create=True).result() + + a = np.arange(np.prod(store.shape), dtype=store.dtype.numpy_dtype).reshape( + store.shape + ) + + store[...] = a + + with webdriver.viewer.txn() as s: + s.layers.append( + name="a", + layer=neuroglancer.ImageLayer(source=f"precomputed://{server_url}"), + ) + + if store.shape[-1] == 1: + # Neuroglancer elides the channel dimension if there is only 1 channel + store = store[..., 0] + + vol = webdriver.viewer.volume("a").result() + b = vol.read().result() + + if spec["scale_metadata"]["encoding"] == "jpeg": + np.testing.assert_allclose(store.read().result(), b, atol=4, rtol=0) + else: + np.testing.assert_equal(store.read().result(), b) diff --git a/python/tests/zarr_test.py b/python/tests/zarr_test.py index 74b3586ccd..860c7dbadb 100644 --- a/python/tests/zarr_test.py +++ b/python/tests/zarr_test.py @@ -19,13 +19,16 @@ import numpy as np import pytest -TEST_DATA_DIR = pathlib.Path(__file__).parent.parent / "testdata" +TEST_DATA_DIR = ( + pathlib.Path(__file__).parent.parent.parent / "testdata" / "datasource" / "zarr" +) @pytest.mark.parametrize( "spec", [ {"driver": "zarr"}, + {"driver": "zarr", "metadata": {"compressor": {"id": "zlib"}}}, {"driver": "zarr", "schema": {"chunk_layout": {"inner_order": [2, 1, 0]}}}, {"driver": "zarr3"}, {"driver": "zarr3", "schema": {"chunk_layout": {"inner_order": [2, 1, 0]}}}, @@ -155,6 +158,53 @@ def test_zarr(tempdir_server: tuple[pathlib.Path, str], webdriver, spec): np.testing.assert_equal(a, b) +def test_zarr_corrupt(tempdir_server: tuple[pathlib.Path, str], webdriver): + import tensorstore as ts + + tmp_path, server_url = tempdir_server + + shape = [10, 20, 30] + + a = np.arange(np.prod(shape), dtype=np.int32).reshape(shape) + + full_spec_for_chunks = { + "driver": "zarr3", + "kvstore": { + "driver": "file", + "path": str(tmp_path), + }, + "metadata": {"codecs": ["zstd"]}, + } + + full_spec_for_metadata = { + "driver": "zarr3", + "kvstore": { + "driver": "file", + "path": str(tmp_path), + }, + "metadata": {"codecs": ["gzip"]}, + } + + ts.open(full_spec_for_metadata, create=True, dtype=ts.int32, shape=shape).result() + store = ts.open( + full_spec_for_chunks, + open=True, + assume_metadata=True, + dtype=ts.int32, + shape=shape, + ).result() + store[...] = a + + with webdriver.viewer.txn() as s: + s.layers.append( + name="a", layer=neuroglancer.ImageLayer(source=f"zarr3://{server_url}") + ) + + vol = webdriver.viewer.volume("a").result() + with pytest.raises(ValueError, match=".*Failed to decode gzip"): + vol.read().result() + + EXCLUDED_ZARR_V2_CASES = { ".zgroup", ".zattrs", diff --git a/webpack.config.js b/rspack.config.js similarity index 65% rename from webpack.config.js rename to rspack.config.js index 7047d01fd8..2b1b7db474 100644 --- a/webpack.config.js +++ b/rspack.config.js @@ -1,10 +1,7 @@ import path from "node:path"; -import { EsbuildPlugin } from "esbuild-loader"; -import HtmlWebpackPlugin from "html-webpack-plugin"; -import MiniCssExtractPlugin from "mini-css-extract-plugin"; -import webpack from "webpack"; -import StartupChunkDependenciesPlugin from "webpack/lib/runtime/StartupChunkDependenciesPlugin.js"; -import { normalizeConfigurationWithDefine } from "./build_tools/webpack/configuration_with_define.js"; +import { HtmlRspackPlugin, ProgressPlugin } from "@rspack/core"; +import { normalizeConfigurationWithDefine } from "./build_tools/rspack/configuration_with_define.js"; +import packageJson from "./package.json"; export default (env, args) => { const mode = args.mode === "production" ? "production" : "development"; @@ -23,13 +20,6 @@ export default (env, args) => { splitChunks: { chunks: "all", }, - minimizer: [ - new EsbuildPlugin({ - target: "es2020", - format: "esm", - css: true, - }), - ], }, devtool: "source-map", module: { @@ -37,11 +27,19 @@ export default (env, args) => { // Needed to support Neuroglancer TypeScript sources. { test: /\.tsx?$/, - loader: "esbuild-loader", + loader: "builtin:swc-loader", options: { - // Needed to ensure `import.meta.url` is available. - target: "es2020", + jsc: { + parser: { + syntax: "typescript", + decorators: true, + }, + }, + env: { + targets: packageJson.browserslist, + }, }, + type: "javascript/auto", }, { test: /\.wasm$/, @@ -64,19 +62,6 @@ export default (env, args) => { filename: "[name][ext]", }, }, - // Necessary to handle CSS files. - { - test: /\.css$/, - use: [ - { - loader: - mode === "production" - ? MiniCssExtractPlugin.loader - : "style-loader", - }, - { loader: "css-loader" }, - ], - }, ], }, devServer: { @@ -89,37 +74,23 @@ export default (env, args) => { hot: false, }, plugins: [ - // Fixes esm output with splitChunks - // https://github.com/webpack/webpack/pull/17015/files - new StartupChunkDependenciesPlugin({ - chunkLoading: "import", - asyncChunkLoading: true, - }), - new webpack.ProgressPlugin(), - ...(mode === "production" - ? [new MiniCssExtractPlugin({ filename: "[name].[chunkhash].css" })] - : []), - new HtmlWebpackPlugin({ - title: "Neuroglancer", - scriptLoading: "module", + new ProgressPlugin(), + new HtmlRspackPlugin({ + title: "neuroglancer", }), ], output: { path: path.resolve(import.meta.dirname, "dist", "client"), filename: "[name].[chunkhash].js", chunkFilename: "[name].[contenthash].js", - chunkLoading: "import", - workerChunkLoading: "import", - chunkFormat: "module", asyncChunks: true, - module: true, clean: true, }, - target: ["es2020", "web"], + target: ["web", "browserslist"], experiments: { - outputModule: true, + css: true, }, - // Additional defines, to be added via `webpack.DefinePlugin`. This is not a + // Additional defines, to be added via `DefinePlugin`. This is not a // standard webpack configuration property, but is handled specially by // `normalizeConfigurationWithDefine`. define: { @@ -146,6 +117,9 @@ export default (env, args) => { // NEUROGLANCER_GOOGLE_TAG_MANAGER: JSON.stringify('GTM-XXXXXX'), }, + watchOptions: { + ignored: /node_modules/, + }, }; return env.NEUROGLANCER_CLI ? config diff --git a/setup.py b/setup.py index 7fd8e08317..35c0fc3cad 100755 --- a/setup.py +++ b/setup.py @@ -130,7 +130,7 @@ class BundleClientCommand( ): editable_mode: bool = False - user_options = [ + user_options = [ # type: ignore[assignment] ( "client-bundle-type=", None, diff --git a/src/annotation/backend.ts b/src/annotation/backend.ts index febc1812db..1c8444e9a1 100644 --- a/src/annotation/backend.ts +++ b/src/annotation/backend.ts @@ -66,7 +66,6 @@ import { } from "#src/sliceview/backend.js"; import type { TransformedSource } from "#src/sliceview/base.js"; import { registerNested, WatchableValue } from "#src/trackable_value.js"; -import type { CancellationToken } from "#src/util/cancellation.js"; import type { Borrowed } from "#src/util/disposable.js"; import type { Uint64 } from "#src/util/uint64.js"; import { @@ -100,7 +99,7 @@ export class AnnotationMetadataChunk extends Chunk { } export class AnnotationGeometryData implements SerializedAnnotations { - data: Uint8Array; + data: Uint8Array; typeToOffset: number[]; typeToIds: string[][]; typeToIdMaps: Map[]; @@ -149,11 +148,11 @@ function GeometryChunkMixin( export class AnnotationGeometryChunk extends GeometryChunkMixin( SliceViewChunk, ) { - source: AnnotationGeometryChunkSourceBackend; + declare source: AnnotationGeometryChunkSourceBackend; } export class AnnotationSubsetGeometryChunk extends GeometryChunkMixin(Chunk) { - source: AnnotationSubsetGeometryChunkSource; + declare source: AnnotationSubsetGeometryChunkSource; objectId: Uint64; } @@ -171,11 +170,8 @@ class AnnotationMetadataChunkSource extends ChunkSource { return chunk; } - download( - chunk: AnnotationMetadataChunk, - cancellationToken: CancellationToken, - ) { - return this.parent!.downloadMetadata(chunk, cancellationToken); + download(chunk: AnnotationMetadataChunk, signal: AbortSignal) { + return this.parent!.downloadMetadata(chunk, signal); } } @@ -195,7 +191,7 @@ AnnotationGeometryChunkSourceBackend.prototype.chunkConstructor = @registerSharedObject(ANNOTATION_SUBSET_GEOMETRY_CHUNK_SOURCE_RPC_ID) class AnnotationSubsetGeometryChunkSource extends ChunkSource { parent: Borrowed | undefined = undefined; - chunks: Map; + declare chunks: Map; relationshipIndex: number; getChunk(objectId: Uint64) { const key = getObjectKey(objectId); @@ -209,14 +205,11 @@ class AnnotationSubsetGeometryChunkSource extends ChunkSource { } return chunk; } - download( - chunk: AnnotationSubsetGeometryChunk, - cancellationToken: CancellationToken, - ) { + download(chunk: AnnotationSubsetGeometryChunk, signal: AbortSignal) { return this.parent!.downloadSegmentFilteredGeometry( chunk, this.relationshipIndex, - cancellationToken, + signal, ); } } @@ -227,12 +220,12 @@ export interface AnnotationSource { // TypeScript supports mixins with abstract classes. downloadMetadata( chunk: AnnotationMetadataChunk, - cancellationToken: CancellationToken, + signal: AbortSignal, ): Promise; downloadSegmentFilteredGeometry( chunk: AnnotationSubsetGeometryChunk, relationshipIndex: number, - cancellationToken: CancellationToken, + signal: AbortSignal, ): Promise; } diff --git a/src/annotation/bounding_box.ts b/src/annotation/bounding_box.ts index 60100918f9..00ed93eba1 100644 --- a/src/annotation/bounding_box.ts +++ b/src/annotation/bounding_box.ts @@ -37,7 +37,7 @@ import type { SliceViewPanelRenderContext } from "#src/sliceview/renderlayer.js" import { tile2dArray } from "#src/util/array.js"; import { getViewFrustrumWorldBounds, mat4 } from "#src/util/geom.js"; import { CORNERS_PER_BOX, EDGES_PER_BOX } from "#src/webgl/bounding_box.js"; -import { Buffer } from "#src/webgl/buffer.js"; +import { GLBuffer } from "#src/webgl/buffer.js"; import { defineCircleShader, drawCircles, @@ -293,7 +293,7 @@ void setBoundingBoxFillColor(vec4 color) { class PerspectiveViewRenderHelper extends RenderHelper { private edgeBoxCornerOffsetsBuffer = this.registerDisposer( - Buffer.fromData( + GLBuffer.fromData( this.gl, tile2dArray( edgeBoxCornerOffsetData, @@ -346,7 +346,7 @@ emitAnnotation(vec4(vColor.rgb, getLineAlpha() * vClipCoefficient)); ); private boxCornerOffsetsBuffer = this.registerDisposer( - Buffer.fromData( + GLBuffer.fromData( this.gl, tile2dArray( vertexBasePositions, diff --git a/src/annotation/frontend_source.ts b/src/annotation/frontend_source.ts index 1d6bc9423b..c33e684172 100644 --- a/src/annotation/frontend_source.ts +++ b/src/annotation/frontend_source.ts @@ -61,7 +61,7 @@ import { ENDIANNESS, Endianness } from "#src/util/endian.js"; import * as matrix from "#src/util/matrix.js"; import type { Signal } from "#src/util/signal.js"; import { NullarySignal } from "#src/util/signal.js"; -import type { Buffer } from "#src/webgl/buffer.js"; +import type { GLBuffer } from "#src/webgl/buffer.js"; import type { GL } from "#src/webgl/context.js"; import type { RPC } from "#src/worker_rpc.js"; import { @@ -90,7 +90,7 @@ export function computeNumPickIds( } export class AnnotationGeometryData { - buffer: Buffer | undefined; + buffer: GLBuffer | undefined; bufferValid = false; serializedAnnotations: SerializedAnnotations; numPickIds = 0; @@ -115,7 +115,7 @@ export class AnnotationGeometryData { } export class AnnotationSubsetGeometryChunk extends Chunk { - source: AnnotationSubsetGeometryChunkSource; + declare source: AnnotationSubsetGeometryChunkSource; // undefined indicates chunk not found data: AnnotationGeometryData | undefined; constructor(source: AnnotationSubsetGeometryChunkSource, x: any) { @@ -139,7 +139,7 @@ export class AnnotationSubsetGeometryChunk extends Chunk { } export class AnnotationGeometryChunk extends SliceViewChunk { - source: AnnotationGeometryChunkSource; + declare source: AnnotationGeometryChunkSource; // undefined indicates chunk not found data: AnnotationGeometryData | undefined; @@ -168,7 +168,7 @@ export class AnnotationGeometryChunkSource extends SliceViewChunkSource< AnnotationGeometryChunkSpecification, AnnotationGeometryChunk > { - OPTIONS: AnnotationGeometryChunkSourceOptions; + declare OPTIONS: AnnotationGeometryChunkSourceOptions; parent: Borrowed; immediateChunkUpdates = true; @@ -226,7 +226,7 @@ export class AnnotationGeometryChunkSource extends SliceViewChunkSource< @registerSharedObjectOwner(ANNOTATION_SUBSET_GEOMETRY_CHUNK_SOURCE_RPC_ID) export class AnnotationSubsetGeometryChunkSource extends ChunkSource { immediateChunkUpdates = true; - chunks: Map; + declare chunks: Map; constructor( chunkManager: Borrowed, @@ -256,7 +256,7 @@ export class AnnotationMetadataChunk extends Chunk { @registerSharedObjectOwner(ANNOTATION_METADATA_CHUNK_SOURCE_RPC_ID) export class AnnotationMetadataChunkSource extends ChunkSource { - chunks: Map; + declare chunks: Map; constructor( chunkManager: Borrowed, public parent: Borrowed, @@ -290,7 +290,7 @@ function copyOtherAnnotations( propertySerializers: AnnotationPropertySerializer[], excludedType: AnnotationType, excludedTypeAdjustment: number, -): Uint8Array { +): Uint8Array { const newData = new Uint8Array( serializedAnnotations.data.length + excludedTypeAdjustment, ); @@ -510,9 +510,7 @@ export class MultiscaleAnnotationSource { OPTIONS: object; key: any; - metadataChunkSource = this.registerDisposer( - new AnnotationMetadataChunkSource(this.chunkManager, this), - ); + metadataChunkSource: AnnotationMetadataChunkSource; segmentFilteredSources: Owned[]; spatiallyIndexedSources = new Set>(); rank: number; @@ -528,6 +526,9 @@ export class MultiscaleAnnotationSource }, ) { super(); + this.metadataChunkSource = this.registerDisposer( + new AnnotationMetadataChunkSource(this.chunkManager, this), + ); this.rank = options.rank; this.properties = options.properties; this.annotationPropertySerializers = makeAnnotationPropertySerializers( diff --git a/src/annotation/index.ts b/src/annotation/index.ts index f920d1a96d..db2dded24e 100644 --- a/src/annotation/index.ts +++ b/src/annotation/index.ts @@ -1363,7 +1363,7 @@ export function makeDataBoundsBoundingBoxAnnotationSet( } export interface SerializedAnnotations { - data: Uint8Array; + data: Uint8Array; typeToIds: string[][]; typeToOffset: number[]; typeToIdMaps: Map[]; diff --git a/src/annotation/renderlayer.ts b/src/annotation/renderlayer.ts index 836fa8dd13..b0ab74f9e4 100644 --- a/src/annotation/renderlayer.ts +++ b/src/annotation/renderlayer.ts @@ -128,7 +128,7 @@ import type { AnyConstructor, MixinConstructor } from "#src/util/mixin.js"; import { NullarySignal } from "#src/util/signal.js"; import type { Uint64 } from "#src/util/uint64.js"; import { withSharedVisibility } from "#src/visibility_priority/frontend.js"; -import { Buffer } from "#src/webgl/buffer.js"; +import { GLBuffer } from "#src/webgl/buffer.js"; import type { ParameterizedContextDependentShaderGetter } from "#src/webgl/dynamic_shader.js"; import { parameterizedEmitterDependentShaderGetter } from "#src/webgl/dynamic_shader.js"; import type { @@ -228,7 +228,7 @@ export class AnnotationLayer extends RefCounted { /** * Stores a serialized representation of the information needed to render the annotations. */ - buffer: Buffer | undefined; + buffer: GLBuffer | undefined; numPickIds = 0; @@ -265,32 +265,9 @@ export class AnnotationLayer extends RefCounted { return sharedObject.visibility; } - segmentationStates = this.registerDisposer( - makeCachedDerivedWatchableValue( - (_relationshipStates, _ignoreNullSegmentFilter) => { - const { displayState, source } = this.state; - const { relationshipStates } = displayState; - return displayState.displayUnfiltered.value - ? undefined - : source.relationships.map((relationship) => { - const state = relationshipStates.get(relationship); - return state.showMatches.value - ? state.segmentationState.value - : undefined; - }); - }, - [ - this.state.displayState.relationshipStates, - this.state.displayState.ignoreNullSegmentFilter, - ], - (a, b) => { - if (a === undefined || b === undefined) { - return a === b; - } - return arraysEqual(a, b); - }, - ), - ); + segmentationStates: WatchableValueInterface< + OptionalSegmentationDisplayState[] | undefined + >; constructor( public chunkManager: ChunkManager, @@ -298,6 +275,32 @@ export class AnnotationLayer extends RefCounted { ) { super(); this.registerDisposer(state); + this.segmentationStates = this.registerDisposer( + makeCachedDerivedWatchableValue( + (_relationshipStates, _ignoreNullSegmentFilter) => { + const { displayState, source } = this.state; + const { relationshipStates } = displayState; + return displayState.displayUnfiltered.value + ? undefined + : source.relationships.map((relationship) => { + const state = relationshipStates.get(relationship); + return state.showMatches.value + ? state.segmentationState.value + : undefined; + }); + }, + [ + this.state.displayState.relationshipStates, + this.state.displayState.ignoreNullSegmentFilter, + ], + (a, b) => { + if (a === undefined || b === undefined) { + return a === b; + } + return arraysEqual(a, b); + }, + ), + ); this.registerDisposer( this.source.changed.add(this.handleChangeAffectingBuffer), ); @@ -364,7 +367,7 @@ export class AnnotationLayer extends RefCounted { let { buffer } = this; if (buffer === undefined) { buffer = this.buffer = this.registerDisposer( - new Buffer(this.chunkManager.gl), + new GLBuffer(this.chunkManager.gl), ); } this.generation = generation; @@ -382,7 +385,7 @@ export class AnnotationLayer extends RefCounted { interface AnnotationGeometryDataInterface { serializedAnnotations: SerializedAnnotations; - buffer: Buffer; + buffer: GLBuffer; numPickIds: number; } @@ -606,7 +609,7 @@ function AnnotationRenderLayer< if (!chunk.bufferValid) { let { buffer } = chunk; if (buffer === undefined) { - buffer = chunk.buffer = new Buffer(this.gl); + buffer = chunk.buffer = new GLBuffer(this.gl); } const { serializedAnnotations } = chunk; buffer.setData(serializedAnnotations.data); diff --git a/src/annotation/type_handler.ts b/src/annotation/type_handler.ts index 4e6af18194..dc2f25f638 100644 --- a/src/annotation/type_handler.ts +++ b/src/annotation/type_handler.ts @@ -31,7 +31,7 @@ import type { SliceViewPanelRenderContext } from "#src/sliceview/renderlayer.js" import type { WatchableValueInterface } from "#src/trackable_value.js"; import { RefCounted } from "#src/util/disposable.js"; import type { mat4 } from "#src/util/geom.js"; -import type { Buffer } from "#src/webgl/buffer.js"; +import type { GLBuffer } from "#src/webgl/buffer.js"; import { glsl_COLORMAPS } from "#src/webgl/colormaps.js"; import type { GL } from "#src/webgl/context.js"; import type { @@ -65,7 +65,7 @@ export type AnnotationShaderGetter = ParameterizedContextDependentShaderGetter< >; export interface AnnotationRenderContext { - buffer: Buffer; + buffer: GLBuffer; annotationLayer: AnnotationLayer; renderContext: SliceViewPanelRenderContext | PerspectiveViewRenderContext; bufferOffset: number; diff --git a/src/async_computation.bundle.js b/src/async_computation.bundle.js index 25801ea045..329ef67e3c 100644 --- a/src/async_computation.bundle.js +++ b/src/async_computation.bundle.js @@ -1,6 +1,7 @@ // Note: This file uses ".js" rather than ".ts" extension because we cannot rely // on Node.js subpath imports to translate paths for Workers since those paths // must be valid for use in `new URL` with multiple bundlers. +import "#src/util/polyfills.js"; import "#src/async_computation/encode_compressed_segmentation.js"; import "#src/datasource/enabled_async_computation_modules.js"; import "#src/async_computation/handler.js"; diff --git a/src/async_computation/decode_blosc.ts b/src/async_computation/decode_blosc.ts index effe9a723f..efca39e514 100644 --- a/src/async_computation/decode_blosc.ts +++ b/src/async_computation/decode_blosc.ts @@ -17,9 +17,9 @@ import { decodeBlosc } from "#src/async_computation/decode_blosc_request.js"; import { registerAsyncComputation } from "#src/async_computation/handler.js"; -registerAsyncComputation(decodeBlosc, async (data: Uint8Array) => { +registerAsyncComputation(decodeBlosc, async (data) => { const { default: Blosc } = await import("numcodecs/blosc"); const codec = Blosc.fromConfig({ id: "blosc" }); - const result = await codec.decode(data); + const result = (await codec.decode(data)) as Uint8Array; return { value: result, transfer: [result.buffer] }; }); diff --git a/src/async_computation/decode_blosc_request.ts b/src/async_computation/decode_blosc_request.ts index 54f577b5da..b5d5f9ed3e 100644 --- a/src/async_computation/decode_blosc_request.ts +++ b/src/async_computation/decode_blosc_request.ts @@ -17,4 +17,6 @@ import { asyncComputation } from "#src/async_computation/index.js"; export const decodeBlosc = - asyncComputation<(data: Uint8Array) => Uint8Array>("decodeBlosc"); + asyncComputation<(data: Uint8Array) => Uint8Array>( + "decodeBlosc", + ); diff --git a/src/async_computation/decode_compresso.ts b/src/async_computation/decode_compresso.ts index 377c345d07..e9813a92c0 100644 --- a/src/async_computation/decode_compresso.ts +++ b/src/async_computation/decode_compresso.ts @@ -18,7 +18,7 @@ import { decodeCompresso } from "#src/async_computation/decode_compresso_request import { registerAsyncComputation } from "#src/async_computation/handler.js"; import { decompressCompresso } from "#src/sliceview/compresso/index.js"; -registerAsyncComputation(decodeCompresso, async (data: Uint8Array) => { +registerAsyncComputation(decodeCompresso, async (data) => { const result = await decompressCompresso(data); return { value: result, transfer: [result.buffer] }; }); diff --git a/src/async_computation/decode_compresso_request.ts b/src/async_computation/decode_compresso_request.ts index 3c36ad518b..d955a26295 100644 --- a/src/async_computation/decode_compresso_request.ts +++ b/src/async_computation/decode_compresso_request.ts @@ -17,4 +17,6 @@ import { asyncComputation } from "#src/async_computation/index.js"; export const decodeCompresso = - asyncComputation<(data: Uint8Array) => Uint8Array>("decodeCompresso"); + asyncComputation<(data: Uint8Array) => Uint8Array>( + "decodeCompresso", + ); diff --git a/src/async_computation/decode_jpeg.ts b/src/async_computation/decode_jpeg.ts index c20dbea214..bf073c7769 100644 --- a/src/async_computation/decode_jpeg.ts +++ b/src/async_computation/decode_jpeg.ts @@ -22,7 +22,7 @@ import { transposeArray2d } from "#src/util/array.js"; registerAsyncComputation( decodeJpeg, async ( - data: Uint8Array, + data, width: number | undefined, height: number | undefined, area: number | undefined, @@ -52,7 +52,7 @@ registerAsyncComputation( ); } numComponents = parser.numComponents; - let result: Uint8Array; + let result: Uint8Array; if (parser.numComponents === 1) { result = parser.getData( parser.width, diff --git a/src/async_computation/decode_jpeg_request.ts b/src/async_computation/decode_jpeg_request.ts index c5b9a7d1df..1aa9722520 100644 --- a/src/async_computation/decode_jpeg_request.ts +++ b/src/async_computation/decode_jpeg_request.ts @@ -18,7 +18,7 @@ import { asyncComputation } from "#src/async_computation/index.js"; export const decodeJpeg = asyncComputation< ( - data: Uint8Array, + data: Uint8Array, width: number | undefined, height: number | undefined, // Expected width * height diff --git a/src/async_computation/decode_png.ts b/src/async_computation/decode_png.ts index ed33df0763..57e37a3c48 100644 --- a/src/async_computation/decode_png.ts +++ b/src/async_computation/decode_png.ts @@ -21,7 +21,7 @@ import { decompressPng } from "#src/sliceview/png/index.js"; registerAsyncComputation( decodePng, async ( - data: Uint8Array, + data, width: number | undefined, height: number | undefined, // Expected width * height diff --git a/src/async_computation/decode_png_request.ts b/src/async_computation/decode_png_request.ts index 0980b4e453..46d05a2228 100644 --- a/src/async_computation/decode_png_request.ts +++ b/src/async_computation/decode_png_request.ts @@ -19,12 +19,12 @@ export interface DecodedImage { width: number; height: number; numComponents: number; - uint8Array: Uint8Array; + uint8Array: Uint8Array; } export const decodePng = asyncComputation< ( - data: Uint8Array, + data: Uint8Array, width: number | undefined, height: number | undefined, // Expected width * height diff --git a/src/async_computation/decode_zstd.ts b/src/async_computation/decode_zstd.ts index becdaf5901..f4808b7c89 100644 --- a/src/async_computation/decode_zstd.ts +++ b/src/async_computation/decode_zstd.ts @@ -17,9 +17,9 @@ import { decodeZstd } from "#src/async_computation/decode_zstd_request.js"; import { registerAsyncComputation } from "#src/async_computation/handler.js"; -registerAsyncComputation(decodeZstd, async (data: Uint8Array) => { +registerAsyncComputation(decodeZstd, async (data) => { const { default: Zstd } = await import("numcodecs/zstd"); const codec = Zstd.fromConfig({ id: "blosc" }); - const result = await codec.decode(data); + const result = (await codec.decode(data)) as Uint8Array; return { value: result, transfer: [result.buffer] }; }); diff --git a/src/async_computation/decode_zstd_request.ts b/src/async_computation/decode_zstd_request.ts index 25c709d366..b895e9f4d3 100644 --- a/src/async_computation/decode_zstd_request.ts +++ b/src/async_computation/decode_zstd_request.ts @@ -17,4 +17,6 @@ import { asyncComputation } from "#src/async_computation/index.js"; export const decodeZstd = - asyncComputation<(data: Uint8Array) => Uint8Array>("decodeZstd"); + asyncComputation<(data: Uint8Array) => Uint8Array>( + "decodeZstd", + ); diff --git a/src/async_computation/obj_mesh.ts b/src/async_computation/obj_mesh.ts index 68646946d0..35ec5820a3 100644 --- a/src/async_computation/obj_mesh.ts +++ b/src/async_computation/obj_mesh.ts @@ -24,8 +24,7 @@ import { Uint32ArrayBuilder } from "#src/util/uint32array_builder.js"; registerAsyncComputation( parseOBJFromArrayBuffer, async (buffer: ArrayBuffer) => { - buffer = await maybeDecompressGzip(buffer); - let text = new TextDecoder().decode(buffer); + let text = new TextDecoder().decode(await maybeDecompressGzip(buffer)); // Strip comments text = text.replace(/#.*/g, ""); const vertexPositions = new Float32ArrayBuilder(); diff --git a/src/async_computation/request.ts b/src/async_computation/request.ts index 05ddd5c106..9497ffeb78 100644 --- a/src/async_computation/request.ts +++ b/src/async_computation/request.ts @@ -15,21 +15,18 @@ */ import type { AsyncComputationSpec } from "#src/async_computation/index.js"; -import type { CancellationToken } from "#src/util/cancellation.js"; -import { CANCELED } from "#src/util/cancellation.js"; let numWorkers = 0; const freeWorkers: Worker[] = []; const pendingTasks = new Map< number, - { msg: any; transfer: Transferable[] | undefined } + { msg: any; transfer: Transferable[] | undefined; cleanup?: () => void } >(); const tasks = new Map< number, { resolve: (value: any) => void; reject: (error: any) => void; - cleanup: () => void; } >(); // On Safari, `navigator.hardwareConcurrency` is not defined. @@ -42,6 +39,7 @@ let nextTaskId = 0; function returnWorker(worker: Worker) { for (const [id, task] of pendingTasks) { pendingTasks.delete(id); + task.cleanup?.(); worker.postMessage(task.msg, task.transfer as Transferable[]); return; } @@ -75,7 +73,6 @@ function launchWorker() { const callbacks = tasks.get(id)!; tasks.delete(id); if (callbacks === undefined) return; - callbacks.cleanup(); if (error !== undefined) { callbacks.reject(new Error(error)); } else { @@ -88,27 +85,40 @@ export function requestAsyncComputation< Signature extends (...args: any) => any, >( request: AsyncComputationSpec, - cancellationToken: CancellationToken, + signal: AbortSignal | undefined, transfer: Transferable[] | undefined, ...args: Parameters ): Promise> { - if (cancellationToken.isCanceled) return Promise.reject(CANCELED); const id = nextTaskId++; const msg = { t: request.id, id, args: args }; - const cleanup = cancellationToken.add(() => { - pendingTasks.delete(id); - tasks.delete(id); - }); + + signal?.throwIfAborted(); + const promise = new Promise>((resolve, reject) => { - tasks.set(id, { resolve, reject, cleanup }); + tasks.set(id, { resolve, reject }); }); + if (freeWorkers.length !== 0) { freeWorkers.pop()!.postMessage(msg, transfer as Transferable[]); } else { - pendingTasks.set(id, { msg, transfer }); + let cleanup: (() => void) | undefined; + if (signal !== undefined) { + function abortHandler() { + pendingTasks.delete(id); + const task = tasks.get(id)!; + tasks.delete(id); + task.reject(signal!.reason); + } + signal.addEventListener("abort", abortHandler, { once: true }); + cleanup = () => { + signal.removeEventListener("abort", abortHandler); + }; + } + pendingTasks.set(id, { msg, transfer, cleanup }); if (tasks.size > numWorkers && numWorkers < maxWorkers) { launchWorker(); } } + return promise; } diff --git a/src/axes_lines.ts b/src/axes_lines.ts index d281948665..e13d90c011 100644 --- a/src/axes_lines.ts +++ b/src/axes_lines.ts @@ -17,7 +17,7 @@ import type { ProjectionParameters } from "#src/projection_parameters.js"; import { RefCounted } from "#src/util/disposable.js"; import { mat4 } from "#src/util/geom.js"; -import { Buffer } from "#src/webgl/buffer.js"; +import { GLBuffer } from "#src/webgl/buffer.js"; import type { GL } from "#src/webgl/context.js"; import type { ShaderProgram } from "#src/webgl/shader.js"; import { trivialColorShader } from "#src/webgl/trivial_shaders.js"; @@ -46,14 +46,14 @@ export function computeAxisLineMatrix( } export class AxesLineHelper extends RefCounted { - vertexBuffer: Buffer; - colorBuffer: Buffer; + vertexBuffer: GLBuffer; + colorBuffer: GLBuffer; trivialColorShader: ShaderProgram; constructor(public gl: GL) { super(); this.vertexBuffer = this.registerDisposer( - Buffer.fromData( + GLBuffer.fromData( gl, new Float32Array([ 0, @@ -88,7 +88,7 @@ export class AxesLineHelper extends RefCounted { const alpha = 0.5; this.colorBuffer = this.registerDisposer( - Buffer.fromData( + GLBuffer.fromData( gl, new Float32Array([ 1, diff --git a/src/chunk_manager/backend.ts b/src/chunk_manager/backend.ts index 4c6e7800bf..62457ac015 100644 --- a/src/chunk_manager/backend.ts +++ b/src/chunk_manager/backend.ts @@ -36,8 +36,6 @@ import { } from "#src/chunk_manager/base.js"; import type { SharedWatchableValue } from "#src/shared_watchable_value.js"; import type { TypedArray } from "#src/util/array.js"; -import type { CancellationToken } from "#src/util/cancellation.js"; -import { CancellationTokenSource } from "#src/util/cancellation.js"; import type { Borrowed, Disposable } from "#src/util/disposable.js"; import { RefCounted } from "#src/util/disposable.js"; import LinkedList0 from "#src/util/linked_list.0.js"; @@ -127,10 +125,10 @@ export class Chunk implements Disposable { newRequestedState = ChunkState.NEW; /** - * Cancellation token used to cancel the pending download. Set to undefined except when state !== + * Abort controller used to cancel the pending download. Set to undefined except when state !== * DOWNLOADING. This should not be accessed by code outside this module. */ - downloadCancellationToken: CancellationTokenSource | undefined = undefined; + downloadAbortController: AbortController | undefined = undefined; initialize(key: string) { this.key = key; @@ -414,13 +412,12 @@ export interface ChunkSourceBase { * Note: This method must be defined by subclasses. * * @param chunk Chunk to download. - * @param cancellationToken If this token is canceled, the download/decoding should be aborted if - * possible. + * @param signal Used to abort download. * * TODO(jbms): Move this back to the class definition above and declare this abstract once mixins * are compatible with abstract classes. */ - download(chunk: Chunk, cancellationToken: CancellationToken): Promise; + download(chunk: Chunk, signal: AbortSignal): Promise; } export class ChunkSource extends ChunkSourceBase { @@ -434,13 +431,13 @@ export class ChunkSource extends ChunkSourceBase { } function startChunkDownload(chunk: Chunk) { - const downloadCancellationToken = (chunk.downloadCancellationToken = - new CancellationTokenSource()); + const downloadAbortController = (chunk.downloadAbortController = + new AbortController()); const startTime = Date.now(); - chunk.source!.download(chunk, downloadCancellationToken).then( + chunk.source!.download(chunk, downloadAbortController.signal).then( () => { - if (chunk.downloadCancellationToken === downloadCancellationToken) { - chunk.downloadCancellationToken = undefined; + if (chunk.downloadAbortController === downloadAbortController) { + chunk.downloadAbortController = undefined; const endTime = Date.now(); const { statistics } = chunk.source!; statistics[ @@ -453,8 +450,8 @@ function startChunkDownload(chunk: Chunk) { } }, (error: any) => { - if (chunk.downloadCancellationToken === downloadCancellationToken) { - chunk.downloadCancellationToken = undefined; + if (chunk.downloadAbortController === downloadAbortController) { + chunk.downloadAbortController = undefined; chunk.downloadFailed(error); console.log(`Error retrieving chunk ${chunk}: ${error}`); } @@ -463,9 +460,9 @@ function startChunkDownload(chunk: Chunk) { } function cancelChunkDownload(chunk: Chunk) { - const token = chunk.downloadCancellationToken!; - chunk.downloadCancellationToken = undefined; - token.cancel(); + const controller = chunk.downloadAbortController!; + chunk.downloadAbortController = undefined; + controller.abort(new DOMException("chunk download cancelled", "AbortError")); } class ChunkPriorityQueue { @@ -893,6 +890,11 @@ export class ChunkQueueManager extends SharedObjectCounterpart { this.scheduleUpdate(); } + markRecentlyUsed(chunk: Chunk) { + this.removeChunkFromQueues_(chunk); + this.addChunkToQueues_(chunk); + } + private processGPUPromotions_() { const queueManager = this; function evictFromGPUMemory(chunk: Chunk) { diff --git a/src/chunk_manager/frontend.ts b/src/chunk_manager/frontend.ts index bc85aea127..3df76ce075 100644 --- a/src/chunk_manager/frontend.ts +++ b/src/chunk_manager/frontend.ts @@ -29,8 +29,6 @@ import { import { SharedWatchableValue } from "#src/shared_watchable_value.js"; import { TrackableBoolean } from "#src/trackable_boolean.js"; import { TrackableValue } from "#src/trackable_value.js"; -import type { CancellationToken } from "#src/util/cancellation.js"; -import { CANCELED } from "#src/util/cancellation.js"; import type { Borrowed } from "#src/util/disposable.js"; import { stableStringify } from "#src/util/json.js"; import { StringMemoize } from "#src/util/memoize.js"; @@ -198,9 +196,9 @@ export class ChunkQueueManager extends SharedObject { } private handleFetch_(source: ChunkSource, update: any) { - const { resolve, reject, cancellationToken } = update.promise; - if ((cancellationToken).isCanceled) { - reject(CANCELED); + const { resolve, reject, signal } = update.promise; + if (signal.aborted) { + reject(signal.reason); return; } @@ -350,15 +348,12 @@ registerRPC("Chunk.update", function (x) { updateChunk(this, x); }); -registerPromiseRPC( - "Chunk.retrieve", - function (x, cancellationToken): RPCPromise { - return new Promise<{ value: any }>((resolve, reject) => { - x.promise = { resolve, reject, cancellationToken }; - updateChunk(this, x); - }); - }, -); +registerPromiseRPC("Chunk.retrieve", function (x, signal): RPCPromise { + return new Promise<{ value: any }>((resolve, reject) => { + x.promise = { resolve, reject, signal }; + updateChunk(this, x); + }); +}); registerRPC(CHUNK_LAYER_STATISTICS_RPC_ID, function (x) { const chunkManager = this.get(x.id) as ChunkManager; @@ -432,7 +427,7 @@ export interface ChunkRequesterState { // eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging export class ChunkSource extends SharedObject { - OPTIONS: object; + declare OPTIONS: object; chunks = new Map(); chunkRequesters: Map | undefined; @@ -508,7 +503,7 @@ export function WithParameters< }; @registerSharedObjectOwner(parametersConstructor.RPC_ID) class C extends Base { - OPTIONS: WithParametersOptions; + declare OPTIONS: WithParametersOptions; parameters: Parameters; constructor(...args: any[]) { super(...args); diff --git a/src/chunk_manager/generic_file_source.ts b/src/chunk_manager/generic_file_source.ts index 6a90579489..308e18ffe4 100644 --- a/src/chunk_manager/generic_file_source.ts +++ b/src/chunk_manager/generic_file_source.ts @@ -21,256 +21,25 @@ import type { ChunkManager } from "#src/chunk_manager/backend.js"; import { Chunk, ChunkSourceBase } from "#src/chunk_manager/backend.js"; -import { ChunkPriorityTier, ChunkState } from "#src/chunk_manager/base.js"; -import type { CancellationToken } from "#src/util/cancellation.js"; -import { - CANCELED, - makeCancelablePromise, - MultipleConsumerCancellationTokenSource, -} from "#src/util/cancellation.js"; -import type { Borrowed, Owned } from "#src/util/disposable.js"; -import { responseArrayBuffer } from "#src/util/http_request.js"; +import { ChunkState } from "#src/chunk_manager/base.js"; +import type { SharedKvStoreContextCounterpart } from "#src/kvstore/backend.js"; +import type { ReadResponse } from "#src/kvstore/index.js"; +import type { Owned } from "#src/util/disposable.js"; import { stableStringify } from "#src/util/json.js"; +import type { AsyncMemoize } from "#src/util/memoize.js"; +import { asyncMemoizeWithProgress } from "#src/util/memoize.js"; import { getObjectId } from "#src/util/object_id.js"; -import type { SpecialProtocolCredentialsProvider } from "#src/util/special_protocol_request.js"; -import { cancellableFetchSpecialOk } from "#src/util/special_protocol_request.js"; - -export type PriorityGetter = () => { - priorityTier: ChunkPriorityTier; - priority: number; -}; - -interface FileDataRequester { - resolve: (data: Data) => void; - reject: (error: any) => void; - getPriority: PriorityGetter; -} - -class GenericSharedDataChunk extends Chunk { - decodedKey?: Key; - data?: Data; - requesters?: Set>; - - initialize(key: string) { - super.initialize(key); - this.requesters = new Set>(); - } - - downloadSucceeded() { - super.downloadSucceeded(); - const { requesters, data } = this; - this.requesters = undefined; - for (const requester of requesters!) { - requester.resolve(data!); - } - } - - downloadFailed(error: any) { - super.downloadFailed(error); - const { requesters } = this; - this.requesters = undefined; - for (const requester of requesters!) { - requester.reject(error); - } - } - - freeSystemMemory() { - this.data = undefined; - } -} - -export interface GenericSharedDataSourceOptions { - encodeKey?: (key: Key) => string; - download: ( - key: Key, - cancellationToken: CancellationToken, - ) => Promise<{ size: number; data: Data }>; - sourceQueueLevel?: number; -} - -export class GenericSharedDataSource extends ChunkSourceBase { - chunks: Map>; - - private encodeKeyFunction: (key: Key) => string; - - private downloadFunction: ( - key: Key, - cancellationToken: CancellationToken, - ) => Promise<{ size: number; data: Data }>; - - constructor( - chunkManager: Owned, - options: GenericSharedDataSourceOptions, - ) { - super(chunkManager); - this.registerDisposer(chunkManager); - const { encodeKey = stableStringify } = options; - this.downloadFunction = options.download; - this.encodeKeyFunction = encodeKey; - const { sourceQueueLevel = 0 } = options; - this.sourceQueueLevel = sourceQueueLevel; - - // This source is unusual in that it updates its own chunk priorities. - this.registerDisposer( - this.chunkManager.recomputeChunkPrioritiesLate.add(() => { - this.updateChunkPriorities(); - }), - ); - } - - updateChunkPriorities() { - const { chunkManager } = this; - for (const chunk of this.chunks.values()) { - const { requesters } = chunk; - if (requesters !== undefined) { - for (const requester of requesters) { - const { priorityTier, priority } = requester.getPriority(); - if (priorityTier === ChunkPriorityTier.RECENT) continue; - chunkManager.requestChunk( - chunk, - priorityTier, - priority, - ChunkState.SYSTEM_MEMORY_WORKER, - ); - } - } - } - } - - async download( - chunk: GenericSharedDataChunk, - cancellationToken: CancellationToken, - ) { - const { size, data } = await this.downloadFunction( - chunk.decodedKey!, - cancellationToken, - ); - chunk.systemMemoryBytes = size; - chunk.data = data; - } - - /** - * Precondition: priorityTier <= ChunkPriorityTier.LAST_ORDERED_TIER - */ - getData( - key: Key, - getPriority: PriorityGetter, - cancellationToken: CancellationToken, - ) { - const encodedKey = this.encodeKeyFunction(key); - let chunk = this.chunks.get(encodedKey); - if (chunk === undefined) { - chunk = this.getNewChunk_>( - GenericSharedDataChunk, - ); - chunk.decodedKey = key; - chunk.initialize(encodedKey); - this.addChunk(chunk); - } - return makeCancelablePromise( - cancellationToken, - (resolve, reject, token) => { - // If the data is already available or the request has already failed, resolve/reject the - // promise immediately. - switch (chunk!.state) { - case ChunkState.FAILED: - reject(chunk!.error); - return; - - case ChunkState.SYSTEM_MEMORY_WORKER: - resolve(chunk!.data!); - return; - } - const requester: FileDataRequester = { - resolve, - reject, - getPriority, - }; - chunk!.requesters!.add(requester); - token.add(() => { - const { requesters } = chunk!; - if (requesters !== undefined) { - requesters.delete(requester); - this.chunkManager.scheduleUpdateChunkPriorities(); - } - reject(CANCELED); - }); - this.chunkManager.scheduleUpdateChunkPriorities(); - }, - ); - } - - static get( - chunkManager: Borrowed, - memoizeKey: string, - options: GenericSharedDataSourceOptions, - ) { - return chunkManager.memoize.get( - `getFileSource:${memoizeKey}`, - () => new GenericSharedDataSource(chunkManager.addRef(), options), - ); - } - - static getData( - chunkManager: Borrowed, - memoizeKey: string, - options: GenericSharedDataSourceOptions, - key: Key, - getPriority: PriorityGetter, - cancellationToken: CancellationToken, - ) { - const source = GenericSharedDataSource.get( - chunkManager, - memoizeKey, - options, - ); - const result = source.getData(key, getPriority, cancellationToken); - source.dispose(); - return result; - } - - static getUrl( - chunkManager: Borrowed, - credentialsProvider: SpecialProtocolCredentialsProvider, - decodeFunction: ( - buffer: ArrayBuffer, - cancellationToken: CancellationToken, - ) => Promise<{ size: number; data: Data }>, - url: string, - getPriority: PriorityGetter, - cancellationToken: CancellationToken, - ) { - return GenericSharedDataSource.getData( - chunkManager, - `${getObjectId(decodeFunction)}`, - { - download: (url: string, cancellationToken: CancellationToken) => - cancellableFetchSpecialOk( - credentialsProvider, - url, - {}, - responseArrayBuffer, - cancellationToken, - ).then((response) => decodeFunction(response, cancellationToken)), - }, - url, - getPriority, - cancellationToken, - ); - } -} +import type { ProgressOptions } from "#src/util/progress_listener.js"; class AsyncCacheChunk extends Chunk { - promise: Promise | undefined; - cancellationSource: MultipleConsumerCancellationTokenSource | undefined; + asyncMemoize: AsyncMemoize | undefined; initialize(key: string) { super.initialize(key); } freeSystemMemory() { - this.promise = undefined; - this.cancellationSource = undefined; + this.asyncMemoize = undefined; } } @@ -278,12 +47,12 @@ export interface SimpleAsyncCacheOptions { encodeKey?: (key: Key) => string; get: ( key: Key, - cancellationToken: CancellationToken, + progressOptions: ProgressOptions, ) => Promise<{ size: number; data: Value }>; } export class SimpleAsyncCache extends ChunkSourceBase { - chunks: Map>; + declare chunks: Map>; constructor( chunkManager: Owned, @@ -297,10 +66,10 @@ export class SimpleAsyncCache extends ChunkSourceBase { encodeKeyFunction: (key: Key) => string; downloadFunction: ( key: Key, - cancellationToken: CancellationToken, + progressOptions: ProgressOptions, ) => Promise<{ size: number; data: Value }>; - get(key: Key, cancellationToken: CancellationToken): Promise { + get(key: Key, options: Partial): Promise { const encodedKey = this.encodeKeyFunction(key); let chunk = this.chunks.get(encodedKey); if (chunk === undefined) { @@ -308,20 +77,12 @@ export class SimpleAsyncCache extends ChunkSourceBase { chunk.initialize(encodedKey); this.addChunk(chunk); } - if (chunk.promise === undefined) { - let completed = false; - const cancellationSource = (chunk!.cancellationSource = - new MultipleConsumerCancellationTokenSource()); - cancellationSource.add(() => { - if (!completed) { - chunk!.promise = undefined; - } - }); - chunk.promise = (async () => { + if (chunk.asyncMemoize === undefined) { + chunk.asyncMemoize = asyncMemoizeWithProgress(async (progressOptions) => { try { const { data, size } = await this.downloadFunction( key, - cancellationSource, + progressOptions, ); chunk.systemMemoryBytes = size; chunk!.queueManager.updateChunkState( @@ -332,13 +93,13 @@ export class SimpleAsyncCache extends ChunkSourceBase { } catch (e) { chunk!.queueManager.updateChunkState(chunk!, ChunkState.FAILED); throw e; - } finally { - completed = true; } - })(); + }); + } + if (chunk.state === ChunkState.SYSTEM_MEMORY) { + chunk.chunkManager.queueManager.markRecentlyUsed(chunk); } - chunk.cancellationSource!.addConsumer(cancellationToken); - return chunk.promise; + return chunk.asyncMemoize(options); } } @@ -352,3 +113,38 @@ export function makeSimpleAsyncCache( () => new SimpleAsyncCache(chunkManager.addRef(), options), ); } + +export function getCachedDecodedUrl( + sharedKvStoreContext: SharedKvStoreContextCounterpart, + url: string, + decodeFunction: ( + readResponse: ReadResponse | undefined, + options: ProgressOptions, + ) => Promise<{ size: number; data: Data }>, + options: Partial, +): Promise { + const cache = sharedKvStoreContext.chunkManager.memoize.get( + `getCachedDecodedUrl:${getObjectId(decodeFunction)}`, + () => { + const cache = new SimpleAsyncCache( + sharedKvStoreContext.chunkManager.addRef(), + { + get: async (url: string, options: ProgressOptions) => { + const readResponse = await sharedKvStoreContext.kvStoreContext.read( + url, + options, + ); + try { + return decodeFunction(readResponse, options); + } catch (e) { + throw new Error("Error reading ${url}", { cause: e }); + } + }, + }, + ); + cache.registerDisposer(sharedKvStoreContext.addRef()); + return cache; + }, + ); + return cache.get(url, options); +} diff --git a/src/chunk_worker.bundle.js b/src/chunk_worker.bundle.js index 159e988adc..a463171535 100644 --- a/src/chunk_worker.bundle.js +++ b/src/chunk_worker.bundle.js @@ -1,11 +1,14 @@ // Note: This file uses ".js" rather than ".ts" extension because we cannot rely // on Node.js subpath imports to translate paths for Workers since those paths // must be valid for use in `new URL` with multiple bundlers. +import "#src/util/polyfills.js"; import "#src/shared_watchable_value.js"; import "#src/chunk_manager/backend.js"; +import "#src/kvstore/backend.js"; import "#src/sliceview/backend.js"; import "#src/perspective_view/backend.js"; import "#src/volume_rendering/backend.js"; import "#src/annotation/backend.js"; import "#src/datasource/enabled_backend_modules.js"; +import "#src/kvstore/enabled_backend_modules.js"; import "#src/worker_rpc_context.js"; diff --git a/src/coordinate_transform.ts b/src/coordinate_transform.ts index 99a9fdc07c..2b2a2fd09f 100644 --- a/src/coordinate_transform.ts +++ b/src/coordinate_transform.ts @@ -1414,7 +1414,7 @@ export class CoordinateSpaceCombiner { private retainCount = 0; - private prevCombined: CoordinateSpace | undefined = this.combined.value; + private prevCombined: CoordinateSpace | undefined; dimensionRefCounts = new Map(); @@ -1454,6 +1454,7 @@ export class CoordinateSpaceCombiner { includeDimensionPredicate: (name: string) => boolean, ) { this.includeDimensionPredicate_ = includeDimensionPredicate; + this.prevCombined = this.combined.value; } private update() { diff --git a/src/credentials_provider/chunk_source_frontend.ts b/src/credentials_provider/chunk_source_frontend.ts index e0dfb35a36..5f7a07cce0 100644 --- a/src/credentials_provider/chunk_source_frontend.ts +++ b/src/credentials_provider/chunk_source_frontend.ts @@ -69,7 +69,7 @@ export function WithCredentialsProvider() { }; class C extends Base { credentialsProvider: MaybeOptionalCredentialsProvider; - OPTIONS: WithCredentialsOptions; + declare OPTIONS: WithCredentialsOptions; constructor(...args: any[]) { super(...args); const options: WithCredentialsOptions = args[1]; diff --git a/src/credentials_provider/default_manager.ts b/src/credentials_provider/default_manager.ts index dea60b764c..c95fb6a874 100644 --- a/src/credentials_provider/default_manager.ts +++ b/src/credentials_provider/default_manager.ts @@ -18,7 +18,23 @@ * @file CredentialsManager for globally registering a CredentialsProvider */ -import { CachingMapBasedCredentialsManager } from "#src/credentials_provider/index.js"; +import { + CachingMapBasedCredentialsManager, + type ProviderGetter, +} from "#src/credentials_provider/index.js"; -export const defaultCredentialsManager = - new CachingMapBasedCredentialsManager(); +const providers = new Map>(); +export function registerDefaultCredentialsProvider( + key: string, + providerGetter: ProviderGetter, +) { + providers.set(key, providerGetter); +} + +export function getDefaultCredentialsManager() { + const manager = new CachingMapBasedCredentialsManager(); + for (const [key, provider] of providers) { + manager.register(key, provider); + } + return manager; +} diff --git a/src/credentials_provider/http_request.ts b/src/credentials_provider/http_request.ts index 825dd5b705..bdf8bec3f0 100644 --- a/src/credentials_provider/http_request.ts +++ b/src/credentials_provider/http_request.ts @@ -18,32 +18,25 @@ import type { CredentialsProvider, CredentialsWithGeneration, } from "#src/credentials_provider/index.js"; -import type { CancellationToken } from "#src/util/cancellation.js"; -import { throwIfCanceled, uncancelableToken } from "#src/util/cancellation.js"; -import type { ResponseTransform } from "#src/util/http_request.js"; -import { - cancellableFetchOk, - HttpError, - pickDelay, -} from "#src/util/http_request.js"; +import type { FetchOk } from "#src/util/http_request.js"; +import { fetchOk, HttpError, pickDelay } from "#src/util/http_request.js"; +import type { ProgressListener } from "#src/util/progress_listener.js"; const maxCredentialsAttempts = 3; -export async function fetchWithCredentials( +export async function fetchOkWithCredentials( credentialsProvider: CredentialsProvider, input: RequestInfo | ((credentials: Credentials) => RequestInfo), - init: RequestInit, - transformResponse: ResponseTransform, + init: RequestInit & { progressListener?: ProgressListener }, applyCredentials: ( credentials: Credentials, - requestInit: RequestInit, - ) => RequestInit, + requestInit: RequestInit & { progressListener?: ProgressListener }, + ) => RequestInit & { progressListener?: ProgressListener }, errorHandler: (httpError: HttpError, credentials: Credentials) => "refresh", - cancellationToken: CancellationToken = uncancelableToken, -): Promise { +): Promise { let credentials: CredentialsWithGeneration | undefined; for (let credentialsAttempt = 0; ; ) { - throwIfCanceled(cancellationToken); + init.signal?.throwIfAborted(); if (credentialsAttempt > 1) { // Don't delay on the first attempt, and also don't delay on the second attempt, since if the // credentials have expired and there is no problem on the server there is no reason to delay @@ -52,13 +45,14 @@ export async function fetchWithCredentials( setTimeout(resolve, pickDelay(credentialsAttempt - 2)), ); } - credentials = await credentialsProvider.get(credentials, cancellationToken); + credentials = await credentialsProvider.get(credentials, { + signal: init.signal ?? undefined, + progressListener: init.progressListener, + }); try { - return await cancellableFetchOk( + return await fetchOk( typeof input === "function" ? input(credentials.credentials) : input, applyCredentials(credentials.credentials, init), - transformResponse, - cancellationToken, ); } catch (error) { if (error instanceof HttpError) { @@ -71,3 +65,21 @@ export async function fetchWithCredentials( } } } + +export function fetchOkWithCredentialsAdapter( + credentialsProvider: CredentialsProvider, + applyCredentials: ( + credentials: Credentials, + requestInit: RequestInit & { progressListener?: ProgressListener }, + ) => RequestInit & { progressListener?: ProgressListener }, + errorHandler: (httpError: HttpError, credentials: Credentials) => "refresh", +): FetchOk { + return (input, init = {}) => + fetchOkWithCredentials( + credentialsProvider, + input, + init, + applyCredentials, + errorHandler, + ); +} diff --git a/src/credentials_provider/index.ts b/src/credentials_provider/index.ts index c0aab02d6f..1290e24036 100644 --- a/src/credentials_provider/index.ts +++ b/src/credentials_provider/index.ts @@ -18,11 +18,11 @@ * @file Generic facility for providing authentication/authorization credentials. */ -import type { CancellationToken } from "#src/util/cancellation.js"; -import { MultipleConsumerCancellationTokenSource } from "#src/util/cancellation.js"; import type { Owned } from "#src/util/disposable.js"; import { RefCounted } from "#src/util/disposable.js"; -import { StringMemoize } from "#src/util/memoize.js"; +import type { AsyncMemoizeWithProgress } from "#src/util/memoize.js"; +import { asyncMemoizeWithProgress, StringMemoize } from "#src/util/memoize.js"; +import type { ProgressOptions } from "#src/util/progress_listener.js"; /** * Wraps an arbitrary JSON credentials object with a generation number. @@ -43,70 +43,50 @@ export abstract class CredentialsProvider extends RefCounted { */ abstract get: ( invalidCredentials?: CredentialsWithGeneration, - cancellationToken?: CancellationToken, + options?: Partial, ) => Promise>; } export function makeCachedCredentialsGetter( getUncached: ( invalidCredentials: CredentialsWithGeneration | undefined, - cancellationToken: CancellationToken, + options: ProgressOptions, ) => Promise>, ) { let cachedCredentials: CredentialsWithGeneration | undefined; let pendingCredentials: - | Promise> + | AsyncMemoizeWithProgress> | undefined; - let pendingCancellationToken: - | MultipleConsumerCancellationTokenSource - | undefined; - return ( + return async ( invalidCredentials?: CredentialsWithGeneration, - cancellationToken?: CancellationToken, + options?: Partial, ) => { + // Check if a new credential request needs to be made. if ( - pendingCredentials !== undefined && - (cachedCredentials === undefined || - invalidCredentials === undefined || - cachedCredentials.generation !== invalidCredentials.generation) + pendingCredentials === undefined || + (invalidCredentials !== undefined && + cachedCredentials?.generation === invalidCredentials.generation) ) { - if (cachedCredentials === undefined) { - pendingCancellationToken!.addConsumer(cancellationToken); - } - return pendingCredentials; + cachedCredentials = undefined; + pendingCredentials = asyncMemoizeWithProgress(async (progressOptions) => { + cachedCredentials = await getUncached( + invalidCredentials, + progressOptions, + ); + return cachedCredentials; + }); } - cachedCredentials = undefined; - pendingCancellationToken = new MultipleConsumerCancellationTokenSource(); - pendingCredentials = getUncached( - invalidCredentials, - pendingCancellationToken, - ).then( - (credentials) => { - cachedCredentials = credentials; - pendingCancellationToken = undefined; - return credentials; - }, - (reason) => { - if (pendingCancellationToken!.isCanceled) { - pendingCancellationToken = undefined; - pendingCredentials = undefined; - } - throw reason; - }, - ); - return pendingCredentials; + return pendingCredentials(options ?? {}); }; } export function makeCredentialsGetter( - getWithoutGeneration: ( - cancellationToken: CancellationToken, - ) => Promise, + getWithoutGeneration: (options: ProgressOptions) => Promise, ) { let generation = 0; return makeCachedCredentialsGetter( - (_invalidCredentials, cancellationToken) => - getWithoutGeneration(cancellationToken).then((credentials) => ({ + (_invalidCredentials, options) => + getWithoutGeneration(options).then((credentials) => ({ generation: ++generation, credentials, })), @@ -132,13 +112,7 @@ export type ProviderGetter = ( * CredentialsManager that supports registration. */ export class MapBasedCredentialsManager implements CredentialsManager { - providers = new Map< - string, - ( - parameters: any, - credentialsManager: CredentialsManager, - ) => Owned> - >(); + providers = new Map>(); topLevelManager: CredentialsManager = this; register( key: string, @@ -216,7 +190,10 @@ export class AnonymousFirstCredentialsProvider< } get = makeCachedCredentialsGetter( - (invalidCredentials?: CredentialsWithGeneration) => { + ( + invalidCredentials: CredentialsWithGeneration | undefined, + options: ProgressOptions, + ) => { if (this.anonymous && invalidCredentials === undefined) { return Promise.resolve({ generation: -10, @@ -224,7 +201,7 @@ export class AnonymousFirstCredentialsProvider< }); } this.anonymous = false; - return this.baseProvider.get(invalidCredentials); + return this.baseProvider.get(invalidCredentials, options); }, ); } diff --git a/src/credentials_provider/interactive_credentials_provider.ts b/src/credentials_provider/interactive_credentials_provider.ts new file mode 100644 index 0000000000..b10e7f7bdd --- /dev/null +++ b/src/credentials_provider/interactive_credentials_provider.ts @@ -0,0 +1,130 @@ +/** + * @license + * Copyright 2016 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { StatusMessage } from "#src/status.js"; +import { scopedAbortCallback } from "#src/util/abort.js"; + +export function getCredentialsWithStatus( + options: { + description: string; + requestDescription?: string; + supportsImmediate?: boolean; + get: (signal: AbortSignal, immediate: boolean) => Promise; + }, + signal: AbortSignal, +): Promise { + const { requestDescription = "login" } = options; + const status = new StatusMessage(/*delay=*/ true); + let abortController: AbortController | undefined; + return new Promise((resolve, reject) => { + const disposeAbortCallback = scopedAbortCallback(signal, (reason) => { + if (abortController !== undefined) { + abortController.abort(reason); + abortController = undefined; + status.dispose(); + reject(reason); + } + }); + function dispose() { + if (abortController === undefined) return; + abortController = undefined; + status.dispose(); + disposeAbortCallback?.[Symbol.dispose](); + } + function writeLoginStatus( + msg = `${options.description} ${requestDescription} required.`, + linkMessage = `Request ${requestDescription}.`, + ) { + status.setText(msg + " "); + const button = document.createElement("button"); + button.textContent = linkMessage; + status.element.appendChild(button); + button.addEventListener("click", () => { + login(/*immediate=*/ false); + }); + } + function login(immediate: boolean) { + abortController?.abort(); + abortController = new AbortController(); + writeLoginStatus( + `Waiting for ${options.description} ${requestDescription}...`, + "Retry", + ); + options.get(abortController.signal, immediate).then( + (token) => { + dispose(); + resolve(token); + }, + (reason) => { + if (abortController === undefined) { + // Already completed, ignore. + return; + } + abortController = undefined; + status.setVisible(true); + status.setModal(true); + if (immediate) { + writeLoginStatus(); + } else { + writeLoginStatus( + `${options.description} ${requestDescription} failed: ${reason}.`, + "Retry", + ); + } + }, + ); + } + if (options.supportsImmediate === true) { + login(/*immediate=*/ true); + } else { + writeLoginStatus(); + status.setVisible(true); + status.setModal(true); + } + }); +} + +export class AuthWindowClosedError extends Error { + constructor() { + super("Authentication window was closed"); + } +} + +export function monitorAuthPopupWindow( + popup: Window, + abortController: AbortController, +) { + window.addEventListener( + "beforeunload", + () => { + popup.close(); + }, + { signal: abortController.signal }, + ); + const checkClosed = setInterval(() => { + if (popup.closed) { + abortController.abort(new AuthWindowClosedError()); + } + }, 1000); + abortController.signal.addEventListener("abort", () => { + try { + popup.close(); + } catch { + // Ignore error closing window. + } + clearInterval(checkClosed); + }); +} diff --git a/src/credentials_provider/oauth2.ts b/src/credentials_provider/oauth2.ts index 444b5fd95a..3fee4084fa 100644 --- a/src/credentials_provider/oauth2.ts +++ b/src/credentials_provider/oauth2.ts @@ -14,12 +14,13 @@ * limitations under the License. */ -import { fetchWithCredentials } from "#src/credentials_provider/http_request.js"; +import { + fetchOkWithCredentials, + fetchOkWithCredentialsAdapter, +} from "#src/credentials_provider/http_request.js"; import type { CredentialsProvider } from "#src/credentials_provider/index.js"; -import type { CancellationToken } from "#src/util/cancellation.js"; -import { uncancelableToken } from "#src/util/cancellation.js"; -import type { ResponseTransform } from "#src/util/http_request.js"; -import { cancellableFetchOk } from "#src/util/http_request.js"; +import type { FetchOk, HttpError } from "#src/util/http_request.js"; +import { fetchOk } from "#src/util/http_request.js"; /** * OAuth2 token @@ -30,52 +31,64 @@ export interface OAuth2Credentials { email?: string; } -export function fetchWithOAuth2Credentials( +function applyCredentials( + credentials: OAuth2Credentials, + init: RequestInit, +): RequestInit { + if (!credentials.accessToken) return init; + const headers = new Headers(init.headers); + headers.set( + "Authorization", + `${credentials.tokenType} ${credentials.accessToken}`, + ); + return { ...init, headers }; +} + +function errorHandler( + error: HttpError, + credentials: OAuth2Credentials, +): "refresh" { + const { status } = error; + if (status === 401) { + // 401: Authorization needed. OAuth2 token may have expired. + return "refresh"; + } + if (status === 403 && !credentials.accessToken) { + // Anonymous access denied. Request credentials. + return "refresh"; + } + if (error instanceof Error && credentials.email !== undefined) { + error.message += ` (Using credentials for ${JSON.stringify( + credentials.email, + )})`; + } + throw error; +} + +export function fetchOkWithOAuth2Credentials( credentialsProvider: CredentialsProvider | undefined, input: RequestInfo, init: RequestInit, - transformResponse: ResponseTransform, - cancellationToken: CancellationToken = uncancelableToken, -): Promise { +): Promise { if (credentialsProvider === undefined) { - return cancellableFetchOk( - input, - init, - transformResponse, - cancellationToken, - ); + return fetchOk(input, init); } - return fetchWithCredentials( + return fetchOkWithCredentials( credentialsProvider, input, init, - transformResponse, - (credentials, init) => { - if (!credentials.accessToken) return init; - const headers = new Headers(init.headers); - headers.set( - "Authorization", - `${credentials.tokenType} ${credentials.accessToken}`, - ); - return { ...init, headers }; - }, - (error, credentials) => { - const { status } = error; - if (status === 401) { - // 401: Authorization needed. OAuth2 token may have expired. - return "refresh"; - } - if (status === 403 && !credentials.accessToken) { - // Anonymous access denied. Request credentials. - return "refresh"; - } - if (error instanceof Error && credentials.email !== undefined) { - error.message += ` (Using credentials for ${JSON.stringify( - credentials.email, - )})`; - } - throw error; - }, - cancellationToken, + applyCredentials, + errorHandler, + ); +} + +export function fetchOkWithOAuth2CredentialsAdapter( + credentialsProvider: CredentialsProvider | undefined, +): FetchOk { + if (credentialsProvider === undefined) return fetchOk; + return fetchOkWithCredentialsAdapter( + credentialsProvider, + applyCredentials, + errorHandler, ); } diff --git a/src/credentials_provider/shared.ts b/src/credentials_provider/shared.ts index 60308ec9e6..60153312f9 100644 --- a/src/credentials_provider/shared.ts +++ b/src/credentials_provider/shared.ts @@ -19,15 +19,18 @@ */ import type { + CredentialsManager, CredentialsProvider, CredentialsWithGeneration, } from "#src/credentials_provider/index.js"; import { CREDENTIALS_PROVIDER_RPC_ID, CREDENTIALS_PROVIDER_GET_RPC_ID, + CREDENTIALS_MANAGER_RPC_ID, + CREDENTIALS_MANAGER_GET_RPC_ID, } from "#src/credentials_provider/shared_common.js"; -import type { CancellationToken } from "#src/util/cancellation.js"; import type { Owned } from "#src/util/disposable.js"; +import type { ProgressOptions } from "#src/util/progress_listener.js"; import type { RPC, RPCPromise } from "#src/worker_rpc.js"; import { registerPromiseRPC, @@ -51,9 +54,9 @@ export class SharedCredentialsProvider get( invalidCredentials?: CredentialsWithGeneration, - cancellationToken?: CancellationToken, + options?: Partial, ): Promise> { - return this.provider.get(invalidCredentials, cancellationToken); + return this.provider.get(invalidCredentials, options); } } @@ -62,13 +65,53 @@ registerPromiseRPC( function ( this: RPC, x: { providerId: number; invalidCredentials: any }, - cancellationToken: CancellationToken, + progressOptions, ): RPCPromise> { const obj = >this.get(x.providerId); return obj - .get(x.invalidCredentials, cancellationToken) + .get(x.invalidCredentials, progressOptions) .then((credentials) => ({ value: credentials, })); }, ); + +@registerSharedObjectOwner(CREDENTIALS_MANAGER_RPC_ID) +export class SharedCredentialsManager + extends SharedObject + implements CredentialsManager +{ + constructor( + public base: CredentialsManager, + rpc: RPC, + ) { + super(); + this.initializeCounterpart(rpc); + } + + getCredentialsProvider(key: string, parameters?: any) { + return this.base.getCredentialsProvider(key, parameters); + } +} + +registerPromiseRPC( + CREDENTIALS_MANAGER_GET_RPC_ID, + async function ( + this: RPC, + x: { + managerId: number; + key: string; + parameters: any; + invalidCredentials: any; + }, + progressOptions, + ): RPCPromise> { + const manager = this.get(x.managerId) as SharedCredentialsManager; + const provider = manager.base.getCredentialsProvider(x.key, x.parameters); + const credentials = await provider.get( + x.invalidCredentials, + progressOptions, + ); + return { value: credentials }; + }, +); diff --git a/src/credentials_provider/shared_common.ts b/src/credentials_provider/shared_common.ts index a9b435cc9a..ce47289b67 100644 --- a/src/credentials_provider/shared_common.ts +++ b/src/credentials_provider/shared_common.ts @@ -16,3 +16,5 @@ export const CREDENTIALS_PROVIDER_RPC_ID = "CredentialsProvider"; export const CREDENTIALS_PROVIDER_GET_RPC_ID = "CredentialsProvider.get"; +export const CREDENTIALS_MANAGER_RPC_ID = "CredentialsManager"; +export const CREDENTIALS_MANAGER_GET_RPC_ID = "CredentialsManager.get"; diff --git a/src/credentials_provider/shared_counterpart.ts b/src/credentials_provider/shared_counterpart.ts index 7a9910977b..c9ca969bca 100644 --- a/src/credentials_provider/shared_counterpart.ts +++ b/src/credentials_provider/shared_counterpart.ts @@ -20,16 +20,23 @@ */ import type { - CredentialsProvider, + CredentialsManager, CredentialsWithGeneration, MaybeOptionalCredentialsProvider, } from "#src/credentials_provider/index.js"; -import { makeCachedCredentialsGetter } from "#src/credentials_provider/index.js"; import { + CachingCredentialsManager, + makeCachedCredentialsGetter, + CredentialsProvider, +} from "#src/credentials_provider/index.js"; +import { + CREDENTIALS_MANAGER_GET_RPC_ID, + CREDENTIALS_MANAGER_RPC_ID, CREDENTIALS_PROVIDER_GET_RPC_ID, CREDENTIALS_PROVIDER_RPC_ID, } from "#src/credentials_provider/shared_common.js"; -import type { CancellationToken } from "#src/util/cancellation.js"; +import type { ProgressOptions } from "#src/util/progress_listener.js"; +import type { RPC } from "#src/worker_rpc.js"; import { registerSharedObject, SharedObjectCounterpart, @@ -42,13 +49,13 @@ export class SharedCredentialsProviderCounterpart { get = makeCachedCredentialsGetter( ( - invalidCredentials?: CredentialsWithGeneration, - cancellationToken?: CancellationToken, + invalidCredentials: CredentialsWithGeneration | undefined, + options: ProgressOptions, ): Promise> => this.rpc!.promiseInvoke( CREDENTIALS_PROVIDER_GET_RPC_ID, { providerId: this.rpcId, invalidCredentials: invalidCredentials }, - cancellationToken, + { signal: options.signal, progressListener: options.progressListener }, ), ); } @@ -68,3 +75,57 @@ export function WithSharedCredentialsProviderCounterpart() { } }; } + +class ProxyCredentialsProvider< + Credentials, +> extends CredentialsProvider { + constructor( + public rpc: RPC, + public managerId: number, + public key: string, + public parameters?: any, + ) { + super(); + } + get = makeCachedCredentialsGetter( + ( + invalidCredentials: CredentialsWithGeneration | undefined, + options: ProgressOptions, + ): Promise> => + this.rpc.promiseInvoke( + CREDENTIALS_MANAGER_GET_RPC_ID, + { + managerId: this.managerId, + key: this.key, + parameters: this.parameters, + invalidCredentials: invalidCredentials, + }, + { signal: options.signal, progressListener: options.progressListener }, + ), + ); +} + +@registerSharedObject(CREDENTIALS_MANAGER_RPC_ID) +export class SharedCredentialsManagerCounterpart + extends SharedObjectCounterpart + implements CredentialsManager +{ + private impl: CachingCredentialsManager = + new CachingCredentialsManager(this.makeBaseCredentialsManager()); + + private makeBaseCredentialsManager(): CredentialsManager { + return { + getCredentialsProvider: (key: string, parameters?: any) => + new ProxyCredentialsProvider( + this.rpc!, + this.rpcId!, + key, + parameters, + ), + }; + } + + getCredentialsProvider(key: string, parameters?: any) { + return this.impl.getCredentialsProvider(key, parameters); + } +} diff --git a/src/data_management_context.ts b/src/data_management_context.ts new file mode 100644 index 0000000000..d55274c81a --- /dev/null +++ b/src/data_management_context.ts @@ -0,0 +1,79 @@ +/** + * @license + * Copyright 2016 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { FrameNumberCounter } from "#src/chunk_manager/frontend.js"; +import { + CapacitySpecification, + ChunkManager, + ChunkQueueManager, +} from "#src/chunk_manager/frontend.js"; +import { RefCounted } from "#src/util/disposable.js"; +import type { GL } from "#src/webgl/context.js"; +import { RPC } from "#src/worker_rpc.js"; + +export class DataManagementContext extends RefCounted { + worker: Worker; + chunkQueueManager: ChunkQueueManager; + chunkManager: ChunkManager; + + get rpc(): RPC { + return this.chunkQueueManager.rpc!; + } + + constructor( + public gl: GL, + public frameNumberCounter: FrameNumberCounter, + ) { + super(); + // Note: For compatibility with multiple bundlers, a browser-compatible URL + // must be used with `new URL`, which means a Node.js subpath import like + // "#src/chunk_worker.bundle.js" cannot be used. + this.worker = new Worker( + /* webpackChunkName: "neuroglancer_chunk_worker" */ + new URL("./chunk_worker.bundle.js", import.meta.url), + { type: "module" }, + ); + this.chunkQueueManager = this.registerDisposer( + new ChunkQueueManager( + new RPC(this.worker, /*waitUntilReady=*/ true), + this.gl, + this.frameNumberCounter, + { + gpuMemory: new CapacitySpecification({ + defaultItemLimit: 1e6, + defaultSizeLimit: 1e9, + }), + systemMemory: new CapacitySpecification({ + defaultItemLimit: 1e7, + defaultSizeLimit: 2e9, + }), + download: new CapacitySpecification({ + defaultItemLimit: 100, + defaultSizeLimit: Number.POSITIVE_INFINITY, + }), + compute: new CapacitySpecification({ + defaultItemLimit: 128, + defaultSizeLimit: 5e8, + }), + }, + ), + ); + this.chunkQueueManager.registerDisposer(() => this.worker.terminate()); + this.chunkManager = this.registerDisposer( + new ChunkManager(this.chunkQueueManager), + ); + } +} diff --git a/src/datasource/boss/api.ts b/src/datasource/boss/api.ts index 71b3a3e88d..8ca9ff6817 100644 --- a/src/datasource/boss/api.ts +++ b/src/datasource/boss/api.ts @@ -14,12 +14,9 @@ * limitations under the License. */ -import { fetchWithCredentials } from "#src/credentials_provider/http_request.js"; +import { fetchOkWithCredentials } from "#src/credentials_provider/http_request.js"; import type { CredentialsProvider } from "#src/credentials_provider/index.js"; -import type { CancellationToken } from "#src/util/cancellation.js"; -import { uncancelableToken } from "#src/util/cancellation.js"; -import type { ResponseTransform } from "#src/util/http_request.js"; -import { cancellableFetchOk } from "#src/util/http_request.js"; +import { fetchOk } from "#src/util/http_request.js"; export type BossToken = string; @@ -28,19 +25,12 @@ export type BossToken = string; */ export const credentialsKey = "boss"; -export function fetchWithBossCredentials( +export async function fetchWithBossCredentials( credentialsProvider: CredentialsProvider, input: RequestInfo, init: RequestInit, - transformResponse: ResponseTransform, - cancellationToken: CancellationToken = uncancelableToken, -): Promise { - return cancellableFetchOk( - input, - init, - transformResponse, - cancellationToken, - ).catch((error) => { +): Promise { + return fetchOk(input, init).catch((error) => { if ( error.status !== 500 && error.status !== 401 && @@ -51,11 +41,10 @@ export function fetchWithBossCredentials( // has been cancelled throw error; } - return fetchWithCredentials( + return fetchOkWithCredentials( credentialsProvider, input, init, - transformResponse, (credentials) => { const headers = new Headers(init.headers); headers.set("Authorization", `Bearer ${credentials}`); @@ -69,7 +58,6 @@ export function fetchWithBossCredentials( } throw error; }, - cancellationToken, ); }); } diff --git a/src/datasource/boss/async_computation.ts b/src/datasource/boss/async_computation.ts index 69e1442c3a..6ffe0e5ecb 100644 --- a/src/datasource/boss/async_computation.ts +++ b/src/datasource/boss/async_computation.ts @@ -1,2 +1 @@ import "#src/async_computation/decode_jpeg.js"; -import "#src/async_computation/decode_gzip.js"; diff --git a/src/datasource/boss/backend.ts b/src/datasource/boss/backend.ts index 58d6cd40f6..fba370af85 100644 --- a/src/datasource/boss/backend.ts +++ b/src/datasource/boss/backend.ts @@ -35,12 +35,7 @@ import type { ChunkDecoder } from "#src/sliceview/backend_chunk_decoders/index.j import { decodeJpegChunk } from "#src/sliceview/backend_chunk_decoders/jpeg.js"; import type { VolumeChunk } from "#src/sliceview/volume/backend.js"; import { VolumeChunkSource } from "#src/sliceview/volume/backend.js"; -import type { CancellationToken } from "#src/util/cancellation.js"; import { Endianness } from "#src/util/endian.js"; -import { - cancellableFetchOk, - responseArrayBuffer, -} from "#src/util/http_request.js"; import type { SharedObject } from "#src/worker_rpc.js"; import { registerSharedObject } from "#src/worker_rpc.js"; @@ -72,7 +67,7 @@ export class BossVolumeChunkSource extends BossSource( ) { chunkDecoder = chunkDecoders.get(this.parameters.encoding)!; - async download(chunk: VolumeChunk, cancellationToken: CancellationToken) { + async download(chunk: VolumeChunk, signal: AbortSignal) { const { parameters } = this; let url = `${parameters.baseUrl}/latest/cutout/${parameters.collection}/${parameters.experiment}/${parameters.channel}/${parameters.resolution}`; { @@ -92,11 +87,12 @@ export class BossVolumeChunkSource extends BossSource( const response = await fetchWithBossCredentials( this.credentialsProvider, url, - { headers: { Accept: acceptHeaders.get(parameters.encoding)! } }, - responseArrayBuffer, - cancellationToken, + { + signal: signal, + headers: { Accept: acceptHeaders.get(parameters.encoding)! }, + }, ); - await this.chunkDecoder(chunk, cancellationToken, response); + await this.chunkDecoder(chunk, signal, await response.arrayBuffer()); } } @@ -123,23 +119,25 @@ export class BossMeshSource extends BossSource( MeshSource, MeshSourceParameters, ) { - download(chunk: ManifestChunk, cancellationToken: CancellationToken) { + download(chunk: ManifestChunk, signal: AbortSignal) { const { parameters } = this; - return cancellableFetchOk( + return fetchWithBossCredentials( + this.credentialsProvider, `${parameters.baseUrl}${chunk.objectId}`, - {}, - responseArrayBuffer, - cancellationToken, - ).then((response) => decodeManifestChunk(chunk, response)); + { signal: signal }, + ) + .then((response) => response.arrayBuffer()) + .then((response) => decodeManifestChunk(chunk, response)); } - downloadFragment(chunk: FragmentChunk, cancellationToken: CancellationToken) { + downloadFragment(chunk: FragmentChunk, signal: AbortSignal) { const { parameters } = this; - return cancellableFetchOk( + return fetchWithBossCredentials( + this.credentialsProvider, `${parameters.baseUrl}${chunk.fragmentId}`, - {}, - responseArrayBuffer, - cancellationToken, - ).then((response) => decodeFragmentChunk(chunk, response)); + { signal: signal }, + ) + .then((response) => response.arrayBuffer()) + .then((response) => decodeFragmentChunk(chunk, response)); } } diff --git a/src/datasource/boss/credentials_provider.ts b/src/datasource/boss/credentials_provider.ts index cf75d9a030..0a05e79fcc 100644 --- a/src/datasource/boss/credentials_provider.ts +++ b/src/datasource/boss/credentials_provider.ts @@ -23,138 +23,125 @@ import { CredentialsProvider, makeCredentialsGetter, } from "#src/credentials_provider/index.js"; -import { StatusMessage } from "#src/status.js"; import { - CANCELED, - CancellationTokenSource, - uncancelableToken, -} from "#src/util/cancellation.js"; -import { verifyObject, verifyString } from "#src/util/json.js"; + getCredentialsWithStatus, + monitorAuthPopupWindow, +} from "#src/credentials_provider/interactive_credentials_provider.js"; +import { raceWithAbort } from "#src/util/abort.js"; +import { + verifyObject, + verifyObjectProperty, + verifyString, +} from "#src/util/json.js"; +import { ProgressSpan } from "#src/util/progress_listener.js"; import { getRandomHexString } from "#src/util/random.js"; -import { Signal } from "#src/util/signal.js"; export type BossToken = string; -class PendingRequest { - finished = new Signal<(token?: BossToken, error?: any) => void>(); +function makeAuthRequestUrl(options: { + authServer: string; + clientId: string; + redirect_uri: string; + state?: string; + nonce?: string; +}) { + let url = `${options.authServer}/realms/BOSS/protocol/openid-connect/auth?`; + url += `client_id=${encodeURIComponent(options.clientId)}`; + url += `&redirect_uri=${encodeURIComponent(options.redirect_uri)}`; + url += "&response_mode=fragment"; + url += "&response_type=code%20id_token%20token"; + if (options.state) { + url += `&state=${options.state}`; + } + if (options.nonce) { + url += `&nonce=${options.nonce}`; + } + return url; } -class AuthHandler { - oidcCallbackService = "bossAuthCallback"; - relayReadyPromise: Promise; - pendingRequests = new Map(); +function waitForAuthResponseMessage( + source: Window, + state: string, + signal: AbortSignal, +): Promise { + return new Promise((resolve, reject) => { + window.addEventListener( + "message", + (event: MessageEvent) => { + if (event.origin !== location.origin) { + return; + } - constructor() { - this.registerListener(); - } + if (event.source !== source) return; - registerListener() { - addEventListener("message", (event: MessageEvent) => { - if (event.origin !== location.origin) { - // Ignore messages from different origins. - return; - } - try { - const data = verifyObject(JSON.parse(event.data)); - const service = verifyString(data.service); - if (service === this.oidcCallbackService) { - const accessToken = verifyString(data.access_token); - const state = verifyString(data.state); - const request = this.pendingRequests.get(state); - if (request === undefined) { - // Request may have been cancelled. - return; + try { + const obj = verifyObject(JSON.parse(event.data)); + if ( + verifyObjectProperty(obj, "service", verifyString) !== + "bossAuthCallback" + ) { + throw new Error("Unexpected service"); + } + const receivedState = verifyObjectProperty( + obj, + "state", + verifyString, + ); + if (receivedState !== state) { + throw new Error("invalid state"); } - request.finished.dispatch(accessToken); + const accessToken = verifyObjectProperty( + obj, + "access_token", + verifyString, + ); + resolve(accessToken); + } catch (parseError) { + reject( + new Error( + `Received unexpected authentication response: ${parseError.message}`, + ), + ); + console.error("Response received: ", event.data); } - } catch (parseError) { - // Ignore invalid message. - } - }); - } - - addPendingRequest(state: string) { - const request = new PendingRequest(); - this.pendingRequests.set(state, request); - request.finished.add(() => { - this.pendingRequests.delete(state); - }); - return request; - } - - makeAuthRequestUrl(options: { - authServer: string; - clientId: string; - redirect_uri: string; - state?: string; - nonce?: string; - }) { - let url = `${options.authServer}/realms/BOSS/protocol/openid-connect/auth?`; - url += `client_id=${encodeURIComponent(options.clientId)}`; - url += `&redirect_uri=${encodeURIComponent(options.redirect_uri)}`; - url += "&response_mode=fragment"; - url += "&response_type=code%20id_token%20token"; - if (options.state) { - url += `&state=${options.state}`; - } - if (options.nonce) { - url += `&nonce=${options.nonce}`; - } - return url; - } -} - -let authHandlerInstance: AuthHandler; - -function authHandler() { - if (authHandlerInstance === undefined) { - authHandlerInstance = new AuthHandler(); - } - return authHandlerInstance; + }, + { signal: signal }, + ); + }); } /** * Obtain a Keycloak OIDC authentication token. * @return A Promise that resolves to an authentication token. */ -export function authenticateKeycloakOIDC( +export async function authenticateKeycloakOIDC( options: { realm: string; clientId: string; authServer: string }, - cancellationToken = uncancelableToken, -) { + signal: AbortSignal, +): Promise { const state = getRandomHexString(); const nonce = getRandomHexString(); - const handler = authHandler(); - const url = handler.makeAuthRequestUrl({ + const url = makeAuthRequestUrl({ state: state, clientId: options.clientId, redirect_uri: new URL("./bossauth.html", import.meta.url).href, authServer: options.authServer, nonce: nonce, }); - const request = handler.addPendingRequest(state); - const promise = new Promise((resolve, reject) => { - request.finished.add((token: string, error: string) => { - if (token !== undefined) { - resolve(token); - } else { - reject(error); - } - }); - }); - request.finished.add( - cancellationToken.add(() => { - request.finished.dispatch(undefined, CANCELED); - }), - ); - if (!cancellationToken.isCanceled) { + const abortController = new AbortController(); + signal = AbortSignal.any([abortController.signal, signal]); + try { const newWindow = open(url); - if (newWindow !== null) { - request.finished.add(() => { - newWindow.close(); - }); + if (newWindow === null) { + throw new Error("Failed to create authentication popup window"); } + monitorAuthPopupWindow(newWindow, abortController); + return await raceWithAbort( + waitForAuthResponseMessage(newWindow, state, abortController.signal), + signal, + ); + } finally { + abortController.abort(); } - return promise; } export class BossCredentialsProvider extends CredentialsProvider { @@ -162,64 +149,24 @@ export class BossCredentialsProvider extends CredentialsProvider { super(); } - get = makeCredentialsGetter((cancellationToken) => { - const status = new StatusMessage(/*delay=*/ true); - let cancellationSource: CancellationTokenSource | undefined; - return new Promise((resolve, reject) => { - const dispose = () => { - cancellationSource = undefined; - status.dispose(); - }; - cancellationToken.add(() => { - if (cancellationSource !== undefined) { - cancellationSource.cancel(); - cancellationSource = undefined; - status.dispose(); - reject(CANCELED); - } - }); - function writeLoginStatus( - msg = "Boss authorization required.", - linkMessage = "Request authorization.", - ) { - status.setText(msg + " "); - const button = document.createElement("button"); - button.textContent = linkMessage; - status.element.appendChild(button); - button.addEventListener("click", () => { - login(); - }); - status.setVisible(true); - } - const authServer = this.authServer; - function login() { - if (cancellationSource !== undefined) { - cancellationSource.cancel(); - } - cancellationSource = new CancellationTokenSource(); - writeLoginStatus("Waiting for Boss authorization...", "Retry"); - authenticateKeycloakOIDC( - { realm: "boss", clientId: "endpoint", authServer: authServer }, - cancellationSource, - ).then( - (token) => { - if (cancellationSource !== undefined) { - dispose(); - resolve(token); - } - }, - (reason) => { - if (cancellationSource !== undefined) { - cancellationSource = undefined; - writeLoginStatus( - `Boss authorization failed: ${reason}.`, - "Retry", - ); - } - }, - ); - } - writeLoginStatus(); + get = makeCredentialsGetter(async (options) => { + using _span = new ProgressSpan(options.progressListener, { + message: `Requesting Boss access token from ${this.authServer}`, }); + return await getCredentialsWithStatus( + { + description: "Boss", + get: (signal) => + authenticateKeycloakOIDC( + { + realm: "boss", + clientId: "endpoint", + authServer: this.authServer, + }, + signal, + ), + }, + options.signal, + ); }); } diff --git a/src/datasource/boss/frontend.ts b/src/datasource/boss/frontend.ts index 88ad19db0f..ae3cfee2da 100644 --- a/src/datasource/boss/frontend.ts +++ b/src/datasource/boss/frontend.ts @@ -46,8 +46,8 @@ import type { CompletionResult, DataSource, GetDataSourceOptions, + DataSourceProvider, } from "#src/datasource/index.js"; -import { DataSourceProvider } from "#src/datasource/index.js"; import { MeshSource } from "#src/mesh/frontend.js"; import type { SliceViewSingleResolutionSource } from "#src/sliceview/frontend.js"; import type { VolumeSourceOptions } from "#src/sliceview/volume/base.js"; @@ -66,7 +66,6 @@ import { getPrefixMatchesWithDescriptions, } from "#src/util/completion.js"; import { vec2, vec3 } from "#src/util/geom.js"; -import { responseJson } from "#src/util/http_request.js"; import { parseArray, parseQueryStringParameters, @@ -82,6 +81,7 @@ import { verifyOptionalString, verifyString, } from "#src/util/json.js"; +import type { ProgressOptions } from "#src/util/progress_listener.js"; class BossVolumeChunkSource extends WithParameters( WithCredentialsProvider()(VolumeChunkSource), @@ -250,6 +250,7 @@ function parseExperimentInfo( credentialsProvider: CredentialsProvider, collection: string, experiment: string, + options: Partial, ): Promise { verifyObject(obj); @@ -262,6 +263,7 @@ function parseExperimentInfo( experiment, collection, ch, + options, ), ), ); @@ -291,6 +293,7 @@ function parseExperimentInfo( hostname, credentialsProvider, experimentInfo, + options, ); }); } @@ -501,30 +504,34 @@ export function getExperimentInfo( credentialsProvider: CredentialsProvider, experiment: string, collection: string, + options: Partial, ): Promise { - return chunkManager.memoize.getUncounted( + return chunkManager.memoize.getAsync( { hostname: hostname, collection: collection, experiment: experiment, type: "boss:getExperimentInfo", }, - () => + options, + (progressOptions) => fetchWithBossCredentials( credentialsProvider, `${hostname}/latest/collection/${collection}/experiment/${experiment}/`, - {}, - responseJson, - ).then((value) => - parseExperimentInfo( - value, - chunkManager, - hostname, - credentialsProvider, - collection, - experiment, + progressOptions, + ) + .then((response) => response.json()) + .then((value) => + parseExperimentInfo( + value, + chunkManager, + hostname, + credentialsProvider, + collection, + experiment, + progressOptions, + ), ), - ), ); } @@ -535,8 +542,9 @@ export function getChannelInfo( experiment: string, collection: string, channel: string, + options: Partial, ): Promise { - return chunkManager.memoize.getUncounted( + return chunkManager.memoize.getAsync( { hostname: hostname, collection: collection, @@ -544,13 +552,15 @@ export function getChannelInfo( channel: channel, type: "boss:getChannelInfo", }, - () => + options, + (progressOptions) => fetchWithBossCredentials( credentialsProvider, `${hostname}/latest/collection/${collection}/experiment/${experiment}/channel/${channel}/`, - {}, - responseJson, - ).then(parseChannelInfo), + progressOptions, + ) + .then((response) => response.json()) + .then(parseChannelInfo), ); } @@ -561,9 +571,10 @@ export function getDownsampleInfoForChannel( collection: string, experimentInfo: ExperimentInfo, channel: string, + options: Partial, ): Promise { return chunkManager.memoize - .getUncounted( + .getAsync( { hostname: hostname, collection: collection, @@ -572,13 +583,13 @@ export function getDownsampleInfoForChannel( downsample: true, type: "boss:getDownsampleInfoForChannel", }, - () => + options, + (progressOptions) => fetchWithBossCredentials( credentialsProvider, `${hostname}/latest/downsample/${collection}/${experimentInfo.key}/${channel}`, - {}, - responseJson, - ), + progressOptions, + ).then((response) => response.json()), ) .then((downsampleObj) => { return parseDownsampleInfoForChannel( @@ -660,6 +671,7 @@ export function getDataSource( hostname: string, credentialsProvider: CredentialsProvider, path: string, + options: Partial, ) { const match = path.match(pathPattern); if (match === null) { @@ -670,15 +682,17 @@ export function getDataSource( const channel = match[3]; const parameters = parseQueryStringParameters(match[4] || ""); // Warning: If additional arguments are added, the cache key should be updated as well. - return chunkManager.memoize.getUncounted( + return chunkManager.memoize.getAsync( { hostname: hostname, path: path, type: "boss:getVolume" }, - async () => { + options, + async (progressOptions) => { const experimentInfo = await getExperimentInfo( chunkManager, hostname, credentialsProvider, experiment, collection, + progressOptions, ); const experimentInfoWithDownsample = await getDownsampleInfoForChannel( chunkManager, @@ -687,6 +701,7 @@ export function getDataSource( collection, experimentInfo, channel, + progressOptions, ); const volume = new BossMultiscaleVolumeChunkSource( chunkManager, @@ -739,20 +754,23 @@ export function getCollections( chunkManager: ChunkManager, hostname: string, credentialsProvider: CredentialsProvider, + options: Partial, ) { - return chunkManager.memoize.getUncounted( + return chunkManager.memoize.getAsync( { hostname: hostname, type: "boss:getCollections" }, - () => + options, + (progressOptions) => fetchWithBossCredentials( credentialsProvider, `${hostname}/latest/collection/`, - {}, - responseJson, - ).then((value) => - verifyObjectProperty(value, "collections", (x) => - parseArray(x, verifyString), + progressOptions, + ) + .then((response) => response.json()) + .then((value) => + verifyObjectProperty(value, "collections", (x) => + parseArray(x, verifyString), + ), ), - ), ); } @@ -761,20 +779,23 @@ export function getExperiments( hostname: string, credentialsProvider: CredentialsProvider, collection: string, + options: Partial, ) { - return chunkManager.memoize.getUncounted( + return chunkManager.memoize.getAsync( { hostname: hostname, collection: collection, type: "boss:getExperiments" }, - () => + options, + (progressOptions) => fetchWithBossCredentials( credentialsProvider, `${hostname}/latest/collection/${collection}/experiment/`, - {}, - responseJson, - ).then((value) => - verifyObjectProperty(value, "experiments", (x) => - parseArray(x, verifyString), + progressOptions, + ) + .then((response) => response.json()) + .then((value) => + verifyObjectProperty(value, "experiments", (x) => + parseArray(x, verifyString), + ), ), - ), ); } @@ -783,24 +804,27 @@ export function getCoordinateFrame( hostname: string, credentialsProvider: CredentialsProvider, experimentInfo: ExperimentInfo, + options: Partial, ): Promise { const key = experimentInfo.coordFrameKey; - return chunkManager.memoize.getUncounted( + return chunkManager.memoize.getAsync( { hostname: hostname, coordinateframe: key, experimentInfo: experimentInfo, type: "boss:getCoordinateFrame", }, - () => + options, + (progressOptions) => fetchWithBossCredentials( credentialsProvider, `${hostname}/latest/coord/${key}/`, - {}, - responseJson, - ).then((coordinateFrameObj) => - parseCoordinateFrame(coordinateFrameObj, experimentInfo), - ), + progressOptions, + ) + .then((response) => response.json()) + .then((coordinateFrameObj) => + parseCoordinateFrame(coordinateFrameObj, experimentInfo), + ), ); } @@ -809,6 +833,7 @@ export function collectionExperimentChannelCompleter( hostname: string, credentialsProvider: CredentialsProvider, path: string, + options: Partial, ): Promise { const channelMatch = path.match( /^(?:([^/]+)(?:\/?([^/]*)(?:\/?([^/]*)(?:\/?([^/]*)?))?)?)?$/, @@ -824,19 +849,22 @@ export function collectionExperimentChannelCompleter( if (channelMatch[2] === undefined) { const collectionPrefix = channelMatch[1] || ""; // Try to complete the collection. - return getCollections(chunkManager, hostname, credentialsProvider).then( - (collections) => { - return { - offset: 0, - completions: getPrefixMatchesWithDescriptions( - collectionPrefix, - collections, - (x) => x + "/", - () => undefined, - ), - }; - }, - ); + return getCollections( + chunkManager, + hostname, + credentialsProvider, + options, + ).then((collections) => { + return { + offset: 0, + completions: getPrefixMatchesWithDescriptions( + collectionPrefix, + collections, + (x) => x + "/", + () => undefined, + ), + }; + }); } if (channelMatch[3] === undefined) { const experimentPrefix = channelMatch[2] || ""; @@ -845,6 +873,7 @@ export function collectionExperimentChannelCompleter( hostname, credentialsProvider, channelMatch[1], + options, ).then((experiments) => { return { offset: channelMatch![1].length + 1, @@ -863,6 +892,7 @@ export function collectionExperimentChannelCompleter( credentialsProvider, channelMatch[2], channelMatch[1], + options, ).then((experimentInfo) => { const completions = getPrefixMatchesWithDescriptions( channelMatch![3], @@ -890,18 +920,17 @@ function getAuthServer(endpoint: string): string { return authServer; } -export class BossDataSource extends DataSourceProvider { - constructor(public credentialsManager: CredentialsManager) { - super(); +export class BossDataSource implements DataSourceProvider { + get scheme() { + return "boss"; } - get description() { return "bossDB: Block & Object Storage System"; } - getCredentialsProvider(path: string) { + getCredentialsProvider(credentialsManager: CredentialsManager, path: string) { const authServer = getAuthServer(path); - return this.credentialsManager.getCredentialsProvider( + return credentialsManager.getCredentialsProvider( credentialsKey, authServer, ); @@ -915,13 +944,15 @@ export class BossDataSource extends DataSourceProvider { ); } const credentialsProvider = this.getCredentialsProvider( + options.registry.credentialsManager, options.providerUrl, ); return getDataSource( - options.chunkManager, + options.registry.chunkManager, match[1], credentialsProvider, match[2], + options, ); } @@ -932,13 +963,17 @@ export class BossDataSource extends DataSourceProvider { throw null; } const hostname = match[1]; - const credentialsProvider = this.getCredentialsProvider(match[1]); + const credentialsProvider = this.getCredentialsProvider( + options.registry.credentialsManager, + match[1], + ); const path = match[2]; const completions = await collectionExperimentChannelCompleter( - options.chunkManager, + options.registry.chunkManager, hostname, credentialsProvider, path, + options, ); return applyCompletionOffset(match![1].length + 1, completions); } diff --git a/src/datasource/boss/register_credentials_provider.ts b/src/datasource/boss/register_credentials_provider.ts index fcdbe1eeac..47ec688d32 100644 --- a/src/datasource/boss/register_credentials_provider.ts +++ b/src/datasource/boss/register_credentials_provider.ts @@ -14,11 +14,11 @@ * limitations under the License. */ -import { defaultCredentialsManager } from "#src/credentials_provider/default_manager.js"; +import { registerDefaultCredentialsProvider } from "#src/credentials_provider/default_manager.js"; import { credentialsKey } from "#src/datasource/boss/api.js"; import { BossCredentialsProvider } from "#src/datasource/boss/credentials_provider.js"; -defaultCredentialsManager.register( +registerDefaultCredentialsProvider( credentialsKey, (authServer) => new BossCredentialsProvider(authServer), ); diff --git a/src/datasource/boss/register_default.ts b/src/datasource/boss/register_default.ts index 399f13a1a5..acdf432402 100644 --- a/src/datasource/boss/register_default.ts +++ b/src/datasource/boss/register_default.ts @@ -17,7 +17,4 @@ import { BossDataSource } from "#src/datasource/boss/frontend.js"; import { registerProvider } from "#src/datasource/default_provider.js"; -registerProvider( - "boss", - (options) => new BossDataSource(options.credentialsManager), -); +registerProvider(new BossDataSource()); diff --git a/src/datasource/brainmaps/api.ts b/src/datasource/brainmaps/api.ts index 4809b30b57..941e7ccffd 100644 --- a/src/datasource/brainmaps/api.ts +++ b/src/datasource/brainmaps/api.ts @@ -16,10 +16,8 @@ import type { CredentialsProvider } from "#src/credentials_provider/index.js"; import type { OAuth2Credentials } from "#src/credentials_provider/oauth2.js"; -import { fetchWithOAuth2Credentials } from "#src/credentials_provider/oauth2.js"; -import type { CancellationToken } from "#src/util/cancellation.js"; -import { uncancelableToken } from "#src/util/cancellation.js"; -import { responseArrayBuffer, responseJson } from "#src/util/http_request.js"; +import { fetchOkWithOAuth2Credentials } from "#src/credentials_provider/oauth2.js"; +import type { RequestInitWithProgress } from "#src/util/http_request.js"; export type { OAuth2Credentials }; @@ -96,36 +94,15 @@ export interface BatchMeshFragmentPayload { batches: BatchMeshFragment[]; } -export interface HttpCall { - method: "GET" | "POST"; - path: string; - payload?: string; -} - -export function makeRequest( - instance: BrainmapsInstance, - credentialsProvider: BrainmapsCredentialsProvider, - httpCall: HttpCall & { responseType: "arraybuffer" }, - cancellationToken?: CancellationToken, -): Promise; -export function makeRequest( - instance: BrainmapsInstance, - credentialsProvider: BrainmapsCredentialsProvider, - httpCall: HttpCall & { responseType: "json" }, - cancellationToken?: CancellationToken, -): Promise; - export function makeRequest( instance: BrainmapsInstance, credentialsProvider: BrainmapsCredentialsProvider, - httpCall: HttpCall & { responseType: XMLHttpRequestResponseType }, - cancellationToken: CancellationToken = uncancelableToken, -): any { - return fetchWithOAuth2Credentials( + path: string, + init: RequestInitWithProgress = {}, +): Promise { + return fetchOkWithOAuth2Credentials( credentialsProvider, - `${instance.serverUrl}${httpCall.path}`, - { method: httpCall.method, body: httpCall.payload }, - httpCall.responseType === "json" ? responseJson : responseArrayBuffer, - cancellationToken, + `${instance.serverUrl}${path}`, + init, ); } diff --git a/src/datasource/brainmaps/backend.ts b/src/datasource/brainmaps/backend.ts index 15f29e8a13..51e2de5061 100644 --- a/src/datasource/brainmaps/backend.ts +++ b/src/datasource/brainmaps/backend.ts @@ -79,7 +79,6 @@ import { decodeJpegChunk } from "#src/sliceview/backend_chunk_decoders/jpeg.js"; import { decodeRawChunk } from "#src/sliceview/backend_chunk_decoders/raw.js"; import type { VolumeChunk } from "#src/sliceview/volume/backend.js"; import { VolumeChunkSource } from "#src/sliceview/volume/backend.js"; -import type { CancellationToken } from "#src/util/cancellation.js"; import { convertEndian32, Endianness } from "#src/util/endian.js"; import { kInfinityVec, kZeroVec, vec3, vec3Key } from "#src/util/geom.js"; import { @@ -143,8 +142,6 @@ function BrainmapsSource< ); } -const tempUint64 = new Uint64(); - @registerSharedObject() export class BrainmapsVolumeChunkSource extends BrainmapsSource( VolumeChunkSource, @@ -178,7 +175,7 @@ export class BrainmapsVolumeChunkSource extends BrainmapsSource( } } - async download(chunk: VolumeChunk, cancellationToken: CancellationToken) { + async download(chunk: VolumeChunk, signal: AbortSignal) { const { parameters } = this; // chunkPosition must not be captured, since it will be invalidated by the next call to @@ -201,15 +198,14 @@ export class BrainmapsVolumeChunkSource extends BrainmapsSource( const response = await makeRequest( parameters.instance, this.credentialsProvider, + path, { method: "POST", - payload: JSON.stringify(payload), - path, - responseType: "arraybuffer", + body: JSON.stringify(payload), + signal: signal, }, - cancellationToken, ); - await this.chunkDecoder(chunk, cancellationToken, response); + await this.chunkDecoder(chunk, signal, await response.arrayBuffer()); } } @@ -225,7 +221,7 @@ function getFragmentCorner( `Couldn't parse fragmentId ${fragmentId} as hex-encoded Uint64`, ); } - return decodeZIndexCompressed(id, xBits, yBits, zBits); + return decodeZIndexCompressed(id.toBigInt(), xBits, yBits, zBits); } interface BrainmapsMultiscaleManifestChunk extends MultiscaleManifestChunk { @@ -487,7 +483,7 @@ async function makeBatchMeshRequest( meshName: string; }, ids: Map, - cancellationToken: CancellationToken, + signal: AbortSignal, ): Promise { const path = "/v1/objects/meshes:batch"; const batches: BatchMeshFragment[] = []; @@ -512,17 +508,13 @@ async function makeBatchMeshRequest( batches: batches, }; try { - return await makeRequest( - parameters.instance, - credentialsProvider, - { + return await ( + await makeRequest(parameters.instance, credentialsProvider, path, { method: "POST", - path, - payload: JSON.stringify(payload), - responseType: "arraybuffer", - }, - cancellationToken, - ); + body: JSON.stringify(payload), + signal: signal, + }) + ).arrayBuffer(); } finally { for (const [id, idData] of pendingIds) { ids.set(id, idData); @@ -544,32 +536,21 @@ export class BrainmapsMultiscaleMeshSource extends BrainmapsSource( return ""; })(); - download( - chunk: BrainmapsMultiscaleManifestChunk, - cancellationToken: CancellationToken, - ) { + download(chunk: BrainmapsMultiscaleManifestChunk, signal: AbortSignal) { const { parameters } = this; const path = `/v1/objects/${parameters.volumeId}/meshes/` + `${parameters.info.lods[0].info.name}:listfragments?` + `object_id=${chunk.objectId}&return_supervoxel_ids=true` + this.listFragmentsParams; - return makeRequest( - parameters.instance, - this.credentialsProvider, - { - method: "GET", - path, - responseType: "json", - }, - cancellationToken, - ).then((response) => decodeMultiscaleManifestChunk(chunk, response)); + return makeRequest(parameters.instance, this.credentialsProvider, path, { + signal: signal, + }) + .then((response) => response.json()) + .then((response) => decodeMultiscaleManifestChunk(chunk, response)); } - async downloadFragment( - chunk: MultiscaleFragmentChunk, - cancellationToken: CancellationToken, - ) { + async downloadFragment(chunk: MultiscaleFragmentChunk, signal: AbortSignal) { const { parameters } = this; const manifestChunk = @@ -608,7 +589,6 @@ export class BrainmapsMultiscaleMeshSource extends BrainmapsSource( octree[chunkIndex * 5 + 2] / relativeBlockShape[2], ); const fragmentKey = encodeZIndexCompressed3d( - tempUint64, xBits, yBits, zBits, @@ -652,7 +632,7 @@ export class BrainmapsMultiscaleMeshSource extends BrainmapsSource( meshName, }, ids, - cancellationToken, + signal, ) .then((response) => { --requestsInProgress; @@ -783,29 +763,23 @@ export class BrainmapsMeshSource extends BrainmapsSource( return ""; })(); - download(chunk: ManifestChunk, cancellationToken: CancellationToken) { + download(chunk: ManifestChunk, signal: AbortSignal) { const { parameters } = this; const path = `/v1/objects/${parameters.volumeId}/meshes/` + `${parameters.meshName}:listfragments?` + `object_id=${chunk.objectId}&return_supervoxel_ids=true` + this.listFragmentsParams; - return makeRequest( - parameters.instance, - this.credentialsProvider, - { - method: "GET", - path, - responseType: "json", - }, - cancellationToken, - ).then((response) => decodeManifestChunkWithSupervoxelIds(chunk, response)); + return makeRequest(parameters.instance, this.credentialsProvider, path, { + signal, + }) + .then((response) => response.json()) + .then((response) => + decodeManifestChunkWithSupervoxelIds(chunk, response), + ); } - async downloadFragment( - chunk: FragmentChunk, - cancellationToken: CancellationToken, - ) { + async downloadFragment(chunk: FragmentChunk, signal: AbortSignal) { const { parameters } = this; const ids = new Map(); @@ -822,7 +796,7 @@ export class BrainmapsMeshSource extends BrainmapsSource( credentialsProvider, parameters, ids, - cancellationToken, + signal, ); decodeBatchMeshResponse(response, (fragment) => { if (!ids.delete(fragment.fullKey)) { @@ -867,7 +841,7 @@ export class BrainmapsSkeletonSource extends BrainmapsSource( SkeletonSource, SkeletonSourceParameters, ) { - download(chunk: SkeletonChunk, cancellationToken: CancellationToken) { + download(chunk: SkeletonChunk, signal: AbortSignal) { const { parameters } = this; const payload: SkeletonPayload = { object_id: `${chunk.objectId}`, @@ -877,17 +851,13 @@ export class BrainmapsSkeletonSource extends BrainmapsSource( `/meshes/${parameters.meshName}` + "/skeleton:binary"; applyChangeStack(parameters.changeSpec, payload); - return makeRequest( - parameters.instance, - this.credentialsProvider, - { - method: "POST", - path, - payload: JSON.stringify(payload), - responseType: "arraybuffer", - }, - cancellationToken, - ).then((response) => decodeSkeletonChunk(chunk, response)); + return makeRequest(parameters.instance, this.credentialsProvider, path, { + method: "POST", + body: JSON.stringify(payload), + signal, + }) + .then((response) => response.arrayBuffer()) + .then((response) => decodeSkeletonChunk(chunk, response)); } } @@ -1152,27 +1122,23 @@ export class BrainmapsAnnotationGeometryChunkSource extends BrainmapsSource( AnnotationGeometryChunkSourceBackend, AnnotationSpatialIndexSourceParameters, ) { - async download( - chunk: AnnotationGeometryChunk, - cancellationToken: CancellationToken, - ) { + async download(chunk: AnnotationGeometryChunk, signal: AbortSignal) { const { parameters } = this; return Promise.all( spatialAnnotationTypes.map((spatialAnnotationType) => makeRequest( parameters.instance, this.credentialsProvider, + `/v1/changes/${parameters.volumeId}/${parameters.changestack}/spatials:get`, { + signal, method: "POST", - path: `/v1/changes/${parameters.volumeId}/${parameters.changestack}/spatials:get`, - payload: JSON.stringify({ + body: JSON.stringify({ type: spatialAnnotationType, ignore_payload: true, }), - responseType: "json", }, - cancellationToken, - ), + ).then((response) => response.json()), ), ).then((values) => { parseAnnotations(chunk, values); @@ -1188,7 +1154,7 @@ export class BrainmapsAnnotationSource extends BrainmapsSource( downloadSegmentFilteredGeometry( chunk: AnnotationSubsetGeometryChunk, _relationshipIndex: number, - cancellationToken: CancellationToken, + signal: AbortSignal, ) { const { parameters } = this; return Promise.all( @@ -1196,100 +1162,108 @@ export class BrainmapsAnnotationSource extends BrainmapsSource( makeRequest( parameters.instance, this.credentialsProvider, + `/v1/changes/${parameters.volumeId}/${parameters.changestack}/spatials:get`, { + signal, method: "POST", - path: `/v1/changes/${parameters.volumeId}/${parameters.changestack}/spatials:get`, - payload: JSON.stringify({ + body: JSON.stringify({ type: spatialAnnotationType, object_labels: [chunk.objectId.toString()], ignore_payload: true, }), - responseType: "json", }, - cancellationToken, - ), + ).then((response) => response.json()), ), ).then((values) => { parseAnnotations(chunk, values); }); } - downloadMetadata( - chunk: AnnotationMetadataChunk, - cancellationToken: CancellationToken, - ) { + downloadMetadata(chunk: AnnotationMetadataChunk, signal: AbortSignal) { const { parameters } = this; const id = chunk.key!; return makeRequest( parameters.instance, this.credentialsProvider, + `/v1/changes/${parameters.volumeId}/${parameters.changestack}/spatials:get`, { + signal, method: "POST", - path: `/v1/changes/${parameters.volumeId}/${parameters.changestack}/spatials:get`, - payload: JSON.stringify({ + body: JSON.stringify({ type: getSpatialAnnotationTypeFromId(id), id: getFullSpatialAnnotationId(parameters, id), }), - responseType: "json", - }, - cancellationToken, - ).then( - (response) => { - chunk.annotation = parseAnnotationResponse( - response, - getIdPrefix(parameters), - id, - ); - }, - () => { - chunk.annotation = null; }, - ); + ) + .then((response) => response.json()) + .then( + (response) => { + chunk.annotation = parseAnnotationResponse( + response, + getIdPrefix(parameters), + id, + ); + }, + () => { + chunk.annotation = null; + }, + ); } add(annotation: Annotation) { const { parameters } = this; const brainmapsAnnotation = annotationToBrainmaps(annotation); - return makeRequest(parameters.instance, this.credentialsProvider, { - method: "POST", - path: `/v1/changes/${parameters.volumeId}/${parameters.changestack}/spatials:push`, - payload: JSON.stringify({ annotations: [brainmapsAnnotation] }), - responseType: "json", - }).then((response) => { - verifyObject(response); - const ids = verifyObjectProperty(response, "ids", verifyStringArray); - if (ids.length !== 1) { - throw new Error( - `Expected list of 1 id, but received ${JSON.stringify(ids)}.`, - ); - } - const idPrefix = getIdPrefix(this.parameters); - return parseBrainmapsAnnotationId(idPrefix, ids[0]); - }); + return makeRequest( + parameters.instance, + this.credentialsProvider, + `/v1/changes/${parameters.volumeId}/${parameters.changestack}/spatials:push`, + { + method: "POST", + body: JSON.stringify({ annotations: [brainmapsAnnotation] }), + }, + ) + .then((response) => response.json()) + .then((response) => { + verifyObject(response); + const ids = verifyObjectProperty(response, "ids", verifyStringArray); + if (ids.length !== 1) { + throw new Error( + `Expected list of 1 id, but received ${JSON.stringify(ids)}.`, + ); + } + const idPrefix = getIdPrefix(this.parameters); + return parseBrainmapsAnnotationId(idPrefix, ids[0]); + }); } update(id: AnnotationId, annotation: Annotation) { const { parameters } = this; const brainmapsAnnotation = annotationToBrainmaps(annotation); brainmapsAnnotation.id = getFullSpatialAnnotationId(parameters, id); - return makeRequest(parameters.instance, this.credentialsProvider, { - method: "POST", - path: `/v1/changes/${parameters.volumeId}/${parameters.changestack}/spatials:push`, - payload: JSON.stringify({ annotations: [brainmapsAnnotation] }), - responseType: "json", - }); + return makeRequest( + parameters.instance, + this.credentialsProvider, + `/v1/changes/${parameters.volumeId}/${parameters.changestack}/spatials:push`, + { + method: "POST", + body: JSON.stringify({ annotations: [brainmapsAnnotation] }), + }, + ).then((response) => response.json()); } delete(id: AnnotationId) { const { parameters } = this; - return makeRequest(parameters.instance, this.credentialsProvider, { - method: "POST", - path: `/v1/changes/${parameters.volumeId}/${parameters.changestack}/spatials:delete`, - payload: JSON.stringify({ - type: getSpatialAnnotationTypeFromId(id), - ids: [getFullSpatialAnnotationId(parameters, id)], - }), - responseType: "json", - }); + return makeRequest( + parameters.instance, + this.credentialsProvider, + `/v1/changes/${parameters.volumeId}/${parameters.changestack}/spatials:delete`, + { + method: "POST", + body: JSON.stringify({ + type: getSpatialAnnotationTypeFromId(id), + ids: [getFullSpatialAnnotationId(parameters, id)], + }), + }, + ).then((response) => response.json()); } } diff --git a/src/datasource/brainmaps/frontend.ts b/src/datasource/brainmaps/frontend.ts index b713dad7bd..aa5a16ba14 100644 --- a/src/datasource/brainmaps/frontend.ts +++ b/src/datasource/brainmaps/frontend.ts @@ -34,13 +34,16 @@ import { makeIdentityTransformedBoundingBox, } from "#src/coordinate_transform.js"; import { WithCredentialsProvider } from "#src/credentials_provider/chunk_source_frontend.js"; -import type { CredentialsProvider } from "#src/credentials_provider/index.js"; +import type { + CredentialsManager, + CredentialsProvider, +} from "#src/credentials_provider/index.js"; import type { BrainmapsCredentialsProvider, BrainmapsInstance, OAuth2Credentials, } from "#src/datasource/brainmaps/api.js"; -import { makeRequest } from "#src/datasource/brainmaps/api.js"; +import { credentialsKey, makeRequest } from "#src/datasource/brainmaps/api.js"; import type { ChangeSpec, MultiscaleMeshInfo, @@ -58,9 +61,10 @@ import { import type { CompleteUrlOptions, DataSource, + DataSourceRegistry, GetDataSourceOptions, + DataSourceProvider, } from "#src/datasource/index.js"; -import { DataSourceProvider } from "#src/datasource/index.js"; import { VertexPositionFormat } from "#src/mesh/base.js"; import { MeshSource, MultiscaleMeshSource } from "#src/mesh/frontend.js"; import { SkeletonSource } from "#src/skeleton/frontend.js"; @@ -79,7 +83,6 @@ import { MultiscaleVolumeChunkSource as GenericMultiscaleVolumeChunkSource, VolumeChunkSource, } from "#src/sliceview/volume/frontend.js"; -import { StatusMessage } from "#src/status.js"; import { transposeNestedArrays } from "#src/util/array.js"; import type { CompletionWithDescription } from "#src/util/completion.js"; import { @@ -106,7 +109,8 @@ import { verifyPositiveInt, verifyString, } from "#src/util/json.js"; -import { getObjectId } from "#src/util/object_id.js"; +import type { ProgressOptions } from "#src/util/progress_listener.js"; +import { ProgressSpan } from "#src/util/progress_listener.js"; import { defaultStringCompare } from "#src/util/string.js"; class BrainmapsVolumeChunkSource extends WithParameters( @@ -691,8 +695,8 @@ const MultiscaleAnnotationSourceBase = WithParameters( ); export class BrainmapsAnnotationSource extends MultiscaleAnnotationSourceBase { - key: any; - parameters: AnnotationSourceParameters; + declare key: any; + declare parameters: AnnotationSourceParameters; credentialsProvider: Owned>; constructor( chunkManager: ChunkManager, @@ -769,49 +773,67 @@ const supportedQueryParameters = [ }, ]; -export class BrainmapsDataSource extends DataSourceProvider { +function getCredentialsProvider(credentialsManager: CredentialsManager) { + return credentialsManager.getCredentialsProvider( + credentialsKey, + ); +} + +export class BrainmapsDataSource implements DataSourceProvider { constructor( public instance: BrainmapsInstance, - public credentialsProvider: Owned, - ) { - super(); - } + public scheme: string, + ) {} get description() { return this.instance.description; } - private getMultiscaleInfo(chunkManager: ChunkManager, volumeId: string) { - return chunkManager.memoize.getUncounted( + private getMultiscaleInfo( + registry: DataSourceRegistry, + volumeId: string, + options: Partial, + ) { + return registry.chunkManager.memoize.getAsync( { type: "brainmaps:getMultiscaleInfo", volumeId, instance: this.instance, - credentialsProvider: getObjectId(this.credentialsProvider), }, - () => - makeRequest(this.instance, this.credentialsProvider, { - method: "GET", - path: `/v1beta2/volumes/${volumeId}`, - responseType: "json", - }).then((response) => new MultiscaleVolumeInfo(response)), + options, + async (progressOptions) => { + const response = await makeRequest( + this.instance, + getCredentialsProvider(registry.credentialsManager), + `/v1beta2/volumes/${volumeId}`, + progressOptions, + ); + return new MultiscaleVolumeInfo(await response.json()); + }, ); } - private getMeshesInfo(chunkManager: ChunkManager, volumeId: string) { - return chunkManager.memoize.getUncounted( + private getMeshesInfo( + registry: DataSourceRegistry, + volumeId: string, + options: Partial, + ) { + return registry.chunkManager.memoize.getAsync( { type: "brainmaps:getMeshesInfo", volumeId, instance: this.instance, - credentialsProvider: getObjectId(this.credentialsProvider), }, - () => - makeRequest(this.instance, this.credentialsProvider, { - method: "GET", - path: `/v1beta2/objects/${volumeId}/meshes`, - responseType: "json", - }).then((response) => parseMeshesResponse(response)), + options, + (progressOptions) => + makeRequest( + this.instance, + getCredentialsProvider(registry.credentialsManager), + `/v1beta2/objects/${volumeId}/meshes`, + progressOptions, + ) + .then((response) => response.json()) + .then((response) => parseMeshesResponse(response)), ); } @@ -846,7 +868,7 @@ export class BrainmapsDataSource extends DataSourceProvider { chunkLayoutPreference, jpegQuality, }; - return options.chunkManager.memoize.getUncounted( + return options.registry.chunkManager.memoize.getAsync( { type: "brainmaps:get", instance: this.instance, @@ -854,15 +876,19 @@ export class BrainmapsDataSource extends DataSourceProvider { changeSpec, brainmapsOptions, }, - async () => { + options, + async (progressOptions) => { + const credentialsProvider = getCredentialsProvider( + options.registry.credentialsManager, + ); const [multiscaleVolumeInfo, meshesInfo] = await Promise.all([ - this.getMultiscaleInfo(options.chunkManager, volumeId), - this.getMeshesInfo(options.chunkManager, volumeId), + this.getMultiscaleInfo(options.registry, volumeId, progressOptions), + this.getMeshesInfo(options.registry, volumeId, progressOptions), ]); const volume = new MultiscaleVolumeChunkSource( - options.chunkManager, + options.registry.chunkManager, this.instance, - this.credentialsProvider, + credentialsProvider, volumeId, changeSpec, multiscaleVolumeInfo, @@ -916,10 +942,10 @@ export class BrainmapsDataSource extends DataSourceProvider { const { single } = mesh; if (single !== undefined) { if (single.type === "TRIANGLES") { - meshSource = options.chunkManager.getChunkSource( + meshSource = options.registry.chunkManager.getChunkSource( BrainmapsMeshSource, { - credentialsProvider: this.credentialsProvider, + credentialsProvider, parameters: { instance: this.instance, volumeId: volumeId, @@ -929,10 +955,10 @@ export class BrainmapsDataSource extends DataSourceProvider { }, ); } else { - meshSource = options.chunkManager.getChunkSource( + meshSource = options.registry.chunkManager.getChunkSource( BrainmapsSkeletonSource, { - credentialsProvider: this.credentialsProvider, + credentialsProvider, parameters: { instance: this.instance, volumeId: volumeId, @@ -944,10 +970,10 @@ export class BrainmapsDataSource extends DataSourceProvider { } } else { const multi = mesh.multi!; - meshSource = options.chunkManager.getChunkSource( + meshSource = options.registry.chunkManager.getChunkSource( BrainmapsMultiscaleMeshSource, { - credentialsProvider: this.credentialsProvider, + credentialsProvider, format: { fragmentRelativeVertices: false, vertexPositionFormat: VertexPositionFormat.float32, @@ -992,7 +1018,7 @@ export class BrainmapsDataSource extends DataSourceProvider { default: true, modelSubspaceDimensionIndices: [0, 1, 2], subsource: { - annotation: options.chunkManager.getChunkSource( + annotation: options.registry.chunkManager.getChunkSource( BrainmapsAnnotationSource, { parameters: { @@ -1002,7 +1028,7 @@ export class BrainmapsDataSource extends DataSourceProvider { upperVoxelBound: multiscaleVolumeInfo.scales[0].upperVoxelBound, }, - credentialsProvider: this.credentialsProvider, + credentialsProvider, }, ), }, @@ -1013,108 +1039,110 @@ export class BrainmapsDataSource extends DataSourceProvider { ); } - getProjectList(chunkManager: ChunkManager) { - return chunkManager.memoize.getUncounted( + getProjectList( + registry: DataSourceRegistry, + options: Partial, + ) { + return registry.chunkManager.memoize.getAsync( { instance: this.instance, type: "brainmaps:getProjectList" }, - () => { - const promise = makeRequest(this.instance, this.credentialsProvider, { - method: "GET", - path: "/v1beta2/projects", - responseType: "json", - }).then((projectsResponse) => { - return parseProjectList(projectsResponse); + options, + async (progressOptions) => { + using _span = new ProgressSpan(progressOptions.progressListener, { + message: `Retrieving ${this.instance.description} project list`, }); - const description = `${this.instance.description} project list`; - StatusMessage.forPromise(promise, { - delay: true, - initialMessage: `Retrieving ${description}.`, - errorPrefix: `Error retrieving ${description}: `, - }); - return promise; + const response = await makeRequest( + this.instance, + getCredentialsProvider(registry.credentialsManager), + "/v1beta2/projects", + progressOptions, + ); + return parseProjectList(await response.json()); }, ); } - getDatasetList(chunkManager: ChunkManager, project: string) { - return chunkManager.memoize.getUncounted( + getDatasetList( + registry: DataSourceRegistry, + project: string, + options: Partial, + ) { + return registry.chunkManager.memoize.getAsync( { instance: this.instance, type: `brainmaps:${project}:getDatasetList` }, - () => { - const promise = makeRequest(this.instance, this.credentialsProvider, { - method: "GET", - path: `/v1beta2/datasets?project_id=${project}`, - responseType: "json", - }).then((datasetsResponse) => { - return parseAPIResponseList(datasetsResponse, "datasetIds"); - }); - const description = `${this.instance.description} dataset list`; - StatusMessage.forPromise(promise, { - delay: true, - initialMessage: `Retrieving ${description}`, - errorPrefix: `Error retrieving ${description}`, + options, + async (progressOptions) => { + using _span = new ProgressSpan(progressOptions.progressListener, { + message: `Retrieving ${this.instance.description} dataset list for ${project}`, }); - return promise; + const response = await makeRequest( + this.instance, + getCredentialsProvider(registry.credentialsManager), + `/v1beta2/datasets?project_id=${project}`, + ); + return parseAPIResponseList(await response.json(), "datasetIds"); }, ); } - getVolumeList(chunkManager: ChunkManager, project: string, dataset: string) { - return chunkManager.memoize.getUncounted( + getVolumeList( + registry: DataSourceRegistry, + project: string, + dataset: string, + options: Partial, + ) { + return registry.chunkManager.memoize.getAsync( { instance: this.instance, type: `brainmaps:${project}:${dataset}:getVolumeList`, }, - () => { - const promise = makeRequest(this.instance, this.credentialsProvider, { - method: "GET", - path: `/v1beta2/volumes?project_id=${project}&dataset_id=${dataset}`, - responseType: "json", - }).then((volumesResponse) => { - const fullyQualifyiedVolumeList = parseAPIResponseList( - volumesResponse, - "volumeId", - ); - const splitPoint = project.length + dataset.length + 2; - const volumeList = []; - for (const volume of fullyQualifyiedVolumeList) { - volumeList.push(volume.substring(splitPoint)); - } - return volumeList; + options, + async (progressOptions) => { + using _span = new ProgressSpan(progressOptions.progressListener, { + message: `Retrieving ${this.instance.description} volume list for ${project}:${dataset}`, }); - const description = `${this.instance.description} volume list`; - StatusMessage.forPromise(promise, { - delay: true, - initialMessage: `Retrieving ${description}`, - errorPrefix: `Error retrieving ${description}`, - }); - return promise; + + const response = await makeRequest( + this.instance, + getCredentialsProvider(registry.credentialsManager), + `/v1beta2/volumes?project_id=${project}&dataset_id=${dataset}`, + progressOptions, + ); + const fullyQualifyiedVolumeList = parseAPIResponseList( + await response.json(), + "volumeId", + ); + const splitPoint = project.length + dataset.length + 2; + const volumeList = []; + for (const volume of fullyQualifyiedVolumeList) { + volumeList.push(volume.substring(splitPoint)); + } + return volumeList; }, ); } - getChangeStackList(chunkManager: ChunkManager, volumeId: string) { - return chunkManager.memoize.getUncounted( + getChangeStackList( + registry: DataSourceRegistry, + volumeId: string, + options: Partial, + ) { + return registry.chunkManager.memoize.getAsync( { instance: this.instance, type: "brainmaps:getChangeStackList", volumeId, }, - () => { - const promise: Promise = makeRequest( - this.instance, - this.credentialsProvider, - { - method: "GET", - path: `/v1beta2/changes/${volumeId}/change_stacks`, - responseType: "json", - }, - ).then((response) => parseChangeStackList(response)); - const description = `change stacks for ${volumeId}`; - StatusMessage.forPromise(promise, { - delay: true, - initialMessage: `Retrieving ${description}.`, - errorPrefix: `Error retrieving ${description}: `, + options, + async (progressOptions) => { + using _span = new ProgressSpan(progressOptions.progressListener, { + message: `Retrieving ${this.instance.description} change stack list for ${volumeId}`, }); - return promise; + const response = await makeRequest( + this.instance, + getCredentialsProvider(registry.credentialsManager), + `/v1beta2/changes/${volumeId}/change_stacks`, + progressOptions, + ); + return parseChangeStackList(await response.json()); }, ); } @@ -1137,7 +1165,11 @@ export class BrainmapsDataSource extends DataSourceProvider { } if (meshName !== undefined) { const volumeId = `${project}:${dataset}:${volume}`; - const meshes = await this.getMeshesInfo(options.chunkManager, volumeId); + const meshes = await this.getMeshesInfo( + options.registry, + volumeId, + options, + ); const results: CompletionWithDescription[] = []; const seenMultiscale = new Set(); for (const mesh of meshes) { @@ -1174,8 +1206,9 @@ export class BrainmapsDataSource extends DataSourceProvider { if (changestack !== undefined) { const volumeId = `${project}:${dataset}:${volume}`; const changeStacks = await this.getChangeStackList( - options.chunkManager, + options.registry, volumeId, + options, ); if (changeStacks === undefined) { throw null; @@ -1190,12 +1223,16 @@ export class BrainmapsDataSource extends DataSourceProvider { offset: providerUrl.length - volume.length, completions: getPrefixMatches( volume, - await this.getVolumeList(options.chunkManager, project, dataset), + await this.getVolumeList(options.registry, project, dataset, options), ), }; } if (dataset !== undefined) { - const datasets = await this.getDatasetList(options.chunkManager, project); + const datasets = await this.getDatasetList( + options.registry, + project, + options, + ); return { offset: providerUrl.length - dataset.length, completions: getPrefixMatches( @@ -1205,7 +1242,7 @@ export class BrainmapsDataSource extends DataSourceProvider { }; } - const projects = await this.getProjectList(options.chunkManager); + const projects = await this.getProjectList(options.registry, options); return { offset: 0, completions: getPrefixMatchesWithDescriptions( diff --git a/src/datasource/brainmaps/register_credentials_provider.ts b/src/datasource/brainmaps/register_credentials_provider.ts index 4d3035b159..f31189e993 100644 --- a/src/datasource/brainmaps/register_credentials_provider.ts +++ b/src/datasource/brainmaps/register_credentials_provider.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { defaultCredentialsManager } from "#src/credentials_provider/default_manager.js"; +import { registerDefaultCredentialsProvider } from "#src/credentials_provider/default_manager.js"; import { credentialsKey } from "#src/datasource/brainmaps/api.js"; import { BrainmapsCredentialsProvider } from "#src/datasource/brainmaps/credentials_provider.js"; @@ -22,7 +22,7 @@ import { BrainmapsCredentialsProvider } from "#src/datasource/brainmaps/credenti declare const NEUROGLANCER_BRAINMAPS_CLIENT_ID: string | undefined; if (typeof NEUROGLANCER_BRAINMAPS_CLIENT_ID !== "undefined") { - defaultCredentialsManager.register( + registerDefaultCredentialsProvider( credentialsKey, () => new BrainmapsCredentialsProvider(NEUROGLANCER_BRAINMAPS_CLIENT_ID!), ); diff --git a/src/datasource/brainmaps/register_default.ts b/src/datasource/brainmaps/register_default.ts index 03c94c992f..c06935310e 100644 --- a/src/datasource/brainmaps/register_default.ts +++ b/src/datasource/brainmaps/register_default.ts @@ -15,21 +15,13 @@ */ import type { BrainmapsInstance } from "#src/datasource/brainmaps/api.js"; -import { credentialsKey } from "#src/datasource/brainmaps/api.js"; import { BrainmapsDataSource, productionInstance, } from "#src/datasource/brainmaps/frontend.js"; import { registerProvider } from "#src/datasource/default_provider.js"; -registerProvider( - "brainmaps", - (options) => - new BrainmapsDataSource( - productionInstance, - options.credentialsManager.getCredentialsProvider(credentialsKey), - ), -); +registerProvider(new BrainmapsDataSource(productionInstance, "brainmaps")); declare const NEUROGLANCER_BRAINMAPS_SERVERS: | { [key: string]: BrainmapsInstance } @@ -39,13 +31,6 @@ if (typeof NEUROGLANCER_BRAINMAPS_SERVERS !== "undefined") { for (const [key, instance] of Object.entries( NEUROGLANCER_BRAINMAPS_SERVERS, )) { - registerProvider( - `brainmaps-${key}`, - (options) => - new BrainmapsDataSource( - instance, - options.credentialsManager.getCredentialsProvider(credentialsKey), - ), - ); + registerProvider(new BrainmapsDataSource(instance, `brainmaps-${key}`)); } } diff --git a/src/datasource/deepzoom/backend.ts b/src/datasource/deepzoom/backend.ts index 0c7ac55a44..fc5a74d8d6 100644 --- a/src/datasource/deepzoom/backend.ts +++ b/src/datasource/deepzoom/backend.ts @@ -18,21 +18,14 @@ import { decodeJpeg } from "#src/async_computation/decode_jpeg_request.js"; import { decodePng } from "#src/async_computation/decode_png_request.js"; import { requestAsyncComputation } from "#src/async_computation/request.js"; import { WithParameters } from "#src/chunk_manager/backend.js"; -import { WithSharedCredentialsProviderCounterpart } from "#src/credentials_provider/shared_counterpart.js"; import { ImageTileEncoding, ImageTileSourceParameters, } from "#src/datasource/deepzoom/base.js"; +import { WithSharedKvStoreContextCounterpart } from "#src/kvstore/backend.js"; import type { VolumeChunk } from "#src/sliceview/volume/backend.js"; import { VolumeChunkSource } from "#src/sliceview/volume/backend.js"; import { transposeArray2d } from "#src/util/array.js"; -import type { CancellationToken } from "#src/util/cancellation.js"; -import { - isNotFoundError, - responseArrayBuffer, -} from "#src/util/http_request.js"; -import type { SpecialProtocolCredentials } from "#src/util/special_protocol_request.js"; -import { cancellableFetchSpecialOk } from "#src/util/special_protocol_request.js"; import { registerSharedObject } from "#src/worker_rpc.js"; /* This is enough if support for these aren't needed: @@ -43,11 +36,13 @@ import { registerSharedObject } from "#src/worker_rpc.js"; @registerSharedObject() export class DeepzoomImageTileSource extends WithParameters( - WithSharedCredentialsProviderCounterpart()( - VolumeChunkSource, - ), + WithSharedKvStoreContextCounterpart(VolumeChunkSource), ImageTileSourceParameters, ) { + private tileKvStore = this.sharedKvStoreContext.kvStoreContext.getKvStore( + this.parameters.url, + ); + gridShape = (() => { const gridShape = new Uint32Array(2); const { upperVoxelBound, chunkDataSize } = this.spec; @@ -57,10 +52,7 @@ export class DeepzoomImageTileSource extends WithParameters( return gridShape; })(); - async download( - chunk: VolumeChunk, - cancellationToken: CancellationToken, - ): Promise { + async download(chunk: VolumeChunk, signal: AbortSignal): Promise { const { parameters } = this; // /* This block is enough if support for these aren't needed: @@ -70,7 +62,7 @@ export class DeepzoomImageTileSource extends WithParameters( // const {tilesize, overlap} = parameters; // const [x, y] = chunk.chunkGridPosition; // const url = `${parameters.url}/${x}_${y}.${ImageTileEncoding[parameters.encoding].toLowerCase()}`; - // const response: Blob = await cancellableFetchSpecialOk(this.credentialsProvider, url, {}, response => response.blob(), cancellationToken); + // const response: Blob = await (await fetchSpecialOk(this.credentialsProvider, url, {signal: signal})).blob(); // const tile = await createImageBitmap(response); // const canvas = new OffscreenCanvas(tilesize, tilesize); // const ctx = canvas.getContext("2d")!; @@ -89,75 +81,71 @@ export class DeepzoomImageTileSource extends WithParameters( const [x, y] = chunk.chunkGridPosition; const ox = x === 0 ? 0 : overlap; const oy = y === 0 ? 0 : overlap; - const url = `${parameters.url}/${x}_${y}.${parameters.format}`; - try { - const responseBuffer = await cancellableFetchSpecialOk( - this.credentialsProvider, - url, - {}, - responseArrayBuffer, - cancellationToken, - ); - - let tilewidth = 0; - let tileheight = 0; - let tiledata: Uint8Array | undefined; - switch (encoding) { - case ImageTileEncoding.PNG: { - const pngbitmap = await requestAsyncComputation( - decodePng, - cancellationToken, - [responseBuffer], - new Uint8Array(responseBuffer), - undefined, - undefined, - undefined, - 3, - 1, - false, - ); - ({ width: tilewidth, height: tileheight } = pngbitmap); - tiledata = transposeArray2d( - pngbitmap.uint8Array, - tilewidth * tileheight, - 3, - ); - break; - } + const path = `${this.tileKvStore.path}/${x}_${y}.${parameters.format}`; + const response = await this.tileKvStore.store.read(path, { + signal, + }); + if (response === undefined) { + return; + } + const responseArray = new Uint8Array(await response.response.arrayBuffer()); - case ImageTileEncoding.JPG: - case ImageTileEncoding.JPEG: { - const jpegbitmap = await requestAsyncComputation( - decodeJpeg, - cancellationToken, - [responseBuffer], - new Uint8Array(responseBuffer), - undefined, - undefined, - undefined, - 3, - false, - ); - ({ - uint8Array: tiledata, - width: tilewidth, - height: tileheight, - } = jpegbitmap); - break; - } + let tilewidth = 0; + let tileheight = 0; + let tiledata: Uint8Array | undefined; + switch (encoding) { + case ImageTileEncoding.PNG: { + const pngbitmap = await requestAsyncComputation( + decodePng, + signal, + [responseArray.buffer], + responseArray, + undefined, + undefined, + undefined, + 3, + 1, + false, + ); + ({ width: tilewidth, height: tileheight } = pngbitmap); + tiledata = transposeArray2d( + pngbitmap.uint8Array, + tilewidth * tileheight, + 3, + ); + break; } - if (tiledata !== undefined) { - const t2 = tilesize * tilesize; - const twh = tilewidth * tileheight; - const d = (chunk.data = new Uint8Array(t2 * 3)); - for (let k = 0; k < 3; k++) - for (let j = 0; j < tileheight; j++) - for (let i = 0; i < tilewidth; i++) - d[i + j * tilesize + k * t2] = - tiledata[i + ox + (j + oy) * tilewidth + k * twh]; + + case ImageTileEncoding.JPG: + case ImageTileEncoding.JPEG: { + const jpegbitmap = await requestAsyncComputation( + decodeJpeg, + signal, + [responseArray.buffer], + responseArray, + undefined, + undefined, + undefined, + 3, + false, + ); + ({ + uint8Array: tiledata, + width: tilewidth, + height: tileheight, + } = jpegbitmap); + break; } - } catch (e) { - if (!isNotFoundError(e)) throw e; + } + if (tiledata !== undefined) { + const t2 = tilesize * tilesize; + const twh = tilewidth * tileheight; + const d = (chunk.data = new Uint8Array(t2 * 3)); + for (let k = 0; k < 3; k++) + for (let j = 0; j < tileheight; j++) + for (let i = 0; i < tilewidth; i++) + d[i + j * tilesize + k * t2] = + tiledata[i + ox + (j + oy) * tilewidth + k * twh]; } } } diff --git a/src/datasource/deepzoom/frontend.ts b/src/datasource/deepzoom/frontend.ts index d91f269dec..826d43e438 100644 --- a/src/datasource/deepzoom/frontend.ts +++ b/src/datasource/deepzoom/frontend.ts @@ -15,7 +15,6 @@ */ import { makeDataBoundsBoundingBoxAnnotationSet } from "#src/annotation/index.js"; -import type { ChunkManager } from "#src/chunk_manager/frontend.js"; import { WithParameters } from "#src/chunk_manager/frontend.js"; import type { BoundingBox, @@ -26,26 +25,24 @@ import { makeIdentityTransform, makeIdentityTransformedBoundingBox, } from "#src/coordinate_transform.js"; -import { WithCredentialsProvider } from "#src/credentials_provider/chunk_source_frontend.js"; import { ImageTileEncoding, ImageTileSourceParameters, } from "#src/datasource/deepzoom/base.js"; -import { responseText } from "#src/datasource/dvid/api.js"; import type { - CompleteUrlOptions, - ConvertLegacyUrlOptions, DataSource, DataSubsourceEntry, - GetDataSourceOptions, - NormalizeUrlOptions, + GetKvStoreBasedDataSourceOptions, + KvStoreBasedDataSourceProvider, } from "#src/datasource/index.js"; -import { DataSourceProvider } from "#src/datasource/index.js"; -import { - parseProviderUrl, - resolvePath, - unparseProviderUrl, -} from "#src/datasource/precomputed/frontend.js"; +import type { + AutoDetectFileOptions, + AutoDetectMatch, + AutoDetectRegistry, +} from "#src/kvstore/auto_detect.js"; +import { WithSharedKvStoreContext } from "#src/kvstore/chunk_source_frontend.js"; +import type { SharedKvStoreContext } from "#src/kvstore/frontend.js"; +import { ensureEmptyUrlSuffix } from "#src/kvstore/url.js"; import type { SliceViewSingleResolutionSource } from "#src/sliceview/frontend.js"; import type { VolumeSourceOptions } from "#src/sliceview/volume/base.js"; import { @@ -58,7 +55,6 @@ import { } from "#src/sliceview/volume/frontend.js"; import { transposeNestedArrays } from "#src/util/array.js"; import { DataType } from "#src/util/data_type.js"; -import { completeHttpPath } from "#src/util/http_path_completion.js"; import { verifyEnumString, verifyInt, @@ -66,18 +62,11 @@ import { verifyPositiveInt, verifyString, } from "#src/util/json.js"; -import { getObjectId } from "#src/util/object_id.js"; -import type { - SpecialProtocolCredentials, - SpecialProtocolCredentialsProvider, -} from "#src/util/special_protocol_request.js"; -import { - cancellableFetchSpecialOk, - parseSpecialUrl, -} from "#src/util/special_protocol_request.js"; +import type { ProgressOptions } from "#src/util/progress_listener.js"; +import { ProgressSpan } from "#src/util/progress_listener.js"; /*export*/ class DeepzoomImageTileSource extends WithParameters( - WithCredentialsProvider()(VolumeChunkSource), + WithSharedKvStoreContext(VolumeChunkSource), ImageTileSourceParameters, ) {} @@ -151,12 +140,11 @@ interface LevelInfo { url: string; constructor( - chunkManager: ChunkManager, - public credentialsProvider: SpecialProtocolCredentialsProvider, - /*public*/ url: string, + public sharedKvStoreContext: SharedKvStoreContext, + url: string, public info: PyramidalImageInfo, ) { - super(chunkManager); + super(sharedKvStoreContext.chunkManager); this.url = url.substring(0, url.lastIndexOf(".")) + "_files"; } @@ -197,13 +185,10 @@ interface LevelInfo { chunkSource: this.chunkManager.getChunkSource( DeepzoomImageTileSource, { - credentialsProvider: this.credentialsProvider, + sharedKvStoreContext: this.sharedKvStoreContext, spec, parameters: { - url: resolvePath( - this.url, - (array.length - 1 - index).toString(), - ), + url: `${this.url}/${array.length - 1 - index}/`, encoding: this.info.encoding, format: this.info.format, overlap: this.info.overlap, @@ -229,9 +214,9 @@ interface DZIMetaData { } function getDZIMetadata( - chunkManager: ChunkManager, - credentialsProvider: SpecialProtocolCredentialsProvider, + sharedKvStoreContext: SharedKvStoreContext, url: string, + options: Partial, ): Promise { if (url.endsWith(".json") || url.includes(".json?")) { /* http://openseadragon.github.io/examples/tilesource-dzi/ @@ -241,19 +226,21 @@ function getDZIMetadata( */ throw new Error("DZI-JSON: OpenSeadragon hack not supported yet."); } - return chunkManager.memoize.getUncounted( + return sharedKvStoreContext.chunkManager.memoize.getAsync( { type: "deepzoom:metadata", url, - credentialsProvider: getObjectId(credentialsProvider), }, - async () => { - const text = await cancellableFetchSpecialOk( - credentialsProvider, - url, - {}, - responseText, - ); + options, + async (progressOptions) => { + using _span = new ProgressSpan(progressOptions.progressListener, { + message: `Reading Deep Zoom metadata from ${url}`, + }); + const { response } = await sharedKvStoreContext.kvStoreContext.read(url, { + ...progressOptions, + throwIfMissing: true, + }); + const text = await response.text(); const xml = new DOMParser().parseFromString(text, "text/xml"); const image = xml.documentElement; const size = verifyObject(image.getElementsByTagName("Size").item(0)); @@ -270,16 +257,14 @@ function getDZIMetadata( ); } -async function getImageDataSource( - options: GetDataSourceOptions, - credentialsProvider: SpecialProtocolCredentialsProvider, +function getImageDataSource( + sharedKvStoreContext: SharedKvStoreContext, url: string, metadata: DZIMetaData, -): Promise { +): DataSource { const info = buildPyramidalImageInfo(metadata); const volume = new DeepzoomPyramidalImageTileSource( - options.chunkManager, - credentialsProvider, + sharedKvStoreContext, url, info, ); @@ -300,53 +285,61 @@ async function getImageDataSource( }, }, ]; - return { modelTransform: makeIdentityTransform(modelSpace), subsources }; + return { + modelTransform: makeIdentityTransform(modelSpace), + subsources, + canonicalUrl: `${url}|deepzoom:`, + }; } -export class DeepzoomDataSource extends DataSourceProvider { - get description() { - return "Deep Zoom file-backed data source"; - } - - normalizeUrl(options: NormalizeUrlOptions): string { - const { url, parameters } = parseProviderUrl(options.providerUrl); - return ( - options.providerProtocol + "://" + unparseProviderUrl(url, parameters) - ); +export class DeepzoomDataSource implements KvStoreBasedDataSourceProvider { + get scheme() { + return "deepzoom"; } - - convertLegacyUrl(options: ConvertLegacyUrlOptions): string { - const { url, parameters } = parseProviderUrl(options.providerUrl); - return ( - options.providerProtocol + "://" + unparseProviderUrl(url, parameters) - ); + get description() { + return "Deep Zoom data source"; } - get(options: GetDataSourceOptions): Promise { - const { url: providerUrl, parameters } = parseProviderUrl( - options.providerUrl, - ); - return options.chunkManager.memoize.getUncounted( - { type: "deepzoom:get", providerUrl, parameters }, - async (): Promise => { - const { url, credentialsProvider } = parseSpecialUrl( - providerUrl, - options.credentialsManager, - ); + get(options: GetKvStoreBasedDataSourceOptions): Promise { + ensureEmptyUrlSuffix(options.url); + return options.registry.chunkManager.memoize.getAsync( + { type: "deepzoom:get", url: options.kvStoreUrl }, + options, + async (progressOptions): Promise => { const metadata = await getDZIMetadata( - options.chunkManager, - credentialsProvider, - url, + options.registry.sharedKvStoreContext, + options.kvStoreUrl, + progressOptions, + ); + return getImageDataSource( + options.registry.sharedKvStoreContext, + options.kvStoreUrl, + metadata, ); - return getImageDataSource(options, credentialsProvider, url, metadata); }, ); } - completeUrl(options: CompleteUrlOptions) { - return completeHttpPath( - options.credentialsManager, - options.providerUrl, - options.cancellationToken, - ); +} + +async function detectFormat( + options: AutoDetectFileOptions, +): Promise { + const text = new TextDecoder().decode(options.prefix); + const xml = new DOMParser().parseFromString(text, "text/xml"); + if ( + xml.documentElement.tagName === "Image" && + xml.documentElement.namespaceURI === + "http://schemas.microsoft.com/deepzoom/2009" + ) { + return [{ suffix: "deepzoom:", description: "Deep Zoom" }]; } + return []; +} + +export function registerAutoDetect(registry: AutoDetectRegistry) { + registry.registerFileFormat({ + prefixLength: 500, + suffixLength: 0, + match: detectFormat, + }); } diff --git a/src/datasource/deepzoom/register_default.ts b/src/datasource/deepzoom/register_default.ts index eb9c8a387d..cf97508b87 100644 --- a/src/datasource/deepzoom/register_default.ts +++ b/src/datasource/deepzoom/register_default.ts @@ -14,7 +14,18 @@ * limitations under the License. */ -import { DeepzoomDataSource } from "#src/datasource/deepzoom/frontend.js"; -import { registerProvider } from "#src/datasource/default_provider.js"; +import { + DeepzoomDataSource, + registerAutoDetect, +} from "#src/datasource/deepzoom/frontend.js"; +import { + dataSourceAutoDetectRegistry, + registerKvStoreBasedDataProvider, + registerProvider, +} from "#src/datasource/default_provider.js"; +import { KvStoreBasedDataSourceLegacyUrlAdapter } from "#src/datasource/index.js"; -registerProvider("deepzoom", () => new DeepzoomDataSource()); +const provider = new DeepzoomDataSource(); +registerKvStoreBasedDataProvider(provider); +registerProvider(new KvStoreBasedDataSourceLegacyUrlAdapter(provider)); +registerAutoDetect(dataSourceAutoDetectRegistry); diff --git a/src/datasource/default_provider.ts b/src/datasource/default_provider.ts index bc72938543..85bf8b0aa7 100644 --- a/src/datasource/default_provider.ts +++ b/src/datasource/default_provider.ts @@ -18,32 +18,47 @@ * @file Facility for registering default data sources. */ -import type { CredentialsManager } from "#src/credentials_provider/index.js"; -import type { DataSourceProvider } from "#src/datasource/index.js"; -import { DataSourceProviderRegistry } from "#src/datasource/index.js"; -import type { Owned } from "#src/util/disposable.js"; +import type { SharedCredentialsManager } from "#src/credentials_provider/shared.js"; +import type { + DataSourceProvider, + KvStoreBasedDataSourceProvider, +} from "#src/datasource/index.js"; +import { DataSourceRegistry } from "#src/datasource/index.js"; +import { LocalDataSourceProvider } from "#src/datasource/local.js"; +import { AutoDetectRegistry } from "#src/kvstore/auto_detect.js"; +import type { SharedKvStoreContext } from "#src/kvstore/frontend.js"; export interface ProviderOptions { - credentialsManager: CredentialsManager; + credentialsManager: SharedCredentialsManager; + kvStoreContext: SharedKvStoreContext; } -export type ProviderFactory = ( - options: ProviderOptions, -) => Owned; -const providerFactories = new Map(); +const providers: DataSourceProvider[] = []; +const kvStoreBasedProviders: KvStoreBasedDataSourceProvider[] = []; +export const dataSourceAutoDetectRegistry = new AutoDetectRegistry(); -export function registerProvider(name: string, factory: ProviderFactory) { - providerFactories.set(name, factory); +export function registerProvider(provider: DataSourceProvider) { + providers.push(provider); +} + +export function registerKvStoreBasedDataProvider( + provider: KvStoreBasedDataSourceProvider, +) { + kvStoreBasedProviders.push(provider); } export function getDefaultDataSourceProvider(options: ProviderOptions) { - const provider = new DataSourceProviderRegistry(options.credentialsManager); - for (const [name, factory] of providerFactories) { - try { - provider.register(name, factory(options)); - } catch (e) { - console.warn(`Skipping ${name} data source: ${e}`); - } + const registry = new DataSourceRegistry(options.kvStoreContext); + registry.register(new LocalDataSourceProvider()); + for (const provider of providers) { + registry.register(provider); + } + for (const provider of kvStoreBasedProviders) { + registry.registerKvStoreBasedProvider(provider); } - return provider; + options.kvStoreContext.kvStoreContext.autoDetectRegistry.copyTo( + registry.autoDetectRegistry, + ); + dataSourceAutoDetectRegistry.copyTo(registry.autoDetectRegistry); + return registry; } diff --git a/src/datasource/dvid/api.ts b/src/datasource/dvid/api.ts index 731c2c2846..c9f0ed1ed2 100644 --- a/src/datasource/dvid/api.ts +++ b/src/datasource/dvid/api.ts @@ -18,16 +18,8 @@ * limitations under the License. */ -import { fetchWithCredentials } from "#src/credentials_provider/http_request.js"; +import { fetchOkWithCredentials } from "#src/credentials_provider/http_request.js"; import type { CredentialsProvider } from "#src/credentials_provider/index.js"; -import type { CancellationToken } from "#src/util/cancellation.js"; -import { uncancelableToken } from "#src/util/cancellation.js"; -import type { ResponseTransform } from "#src/util/http_request.js"; -import { - cancellableFetchOk, - responseArrayBuffer, - responseJson, -} from "#src/util/http_request.js"; export interface DVIDToken { // If token is undefined, it indicates anonymous credentials that may be retried. @@ -36,12 +28,6 @@ export interface DVIDToken { export const credentialsKey = "DVID"; -interface HttpCall { - method: "GET" | "POST" | "DELETE" | "HEAD"; - url: string; - payload?: string; -} - export class DVIDInstance { constructor( public baseUrl: string, @@ -85,91 +71,15 @@ export function appendQueryStringForDvid( return url; } -export function responseText(response: Response): Promise { - return response.text(); -} - -export function makeRequest( - httpCall: HttpCall & { responseType: "arraybuffer" }, - cancellationToken?: CancellationToken, -): Promise; - -export function makeRequest( - httpCall: HttpCall & { responseType: "json" }, - cancellationToken?: CancellationToken, -): Promise; - -export function makeRequest( - httpCall: HttpCall & { responseType: "" }, - cancellationToken?: CancellationToken, -): Promise; - -export function makeRequest( - httpCall: HttpCall & { responseType: XMLHttpRequestResponseType }, - cancellationToken: CancellationToken = uncancelableToken, -): any { - const requestInfo = `${httpCall.url}`; - const init = { method: httpCall.method, body: httpCall.payload }; - - if (httpCall.responseType === "") { - return cancellableFetchOk( - requestInfo, - init, - responseText, - cancellationToken, - ); - } - return cancellableFetchOk(requestInfo, init, responseJson, cancellationToken); -} - -export function makeRequestWithCredentials( - credentialsProvider: CredentialsProvider, - httpCall: HttpCall & { responseType: "arraybuffer" }, - cancellationToken?: CancellationToken, -): Promise; - -export function makeRequestWithCredentials( - credentialsProvider: CredentialsProvider, - httpCall: HttpCall & { responseType: "json" }, - cancellationToken?: CancellationToken, -): Promise; - -export function makeRequestWithCredentials( - credentialsProvider: CredentialsProvider, - httpCall: HttpCall & { responseType: "" }, - cancellationToken?: CancellationToken, -): Promise; - -export function makeRequestWithCredentials( - credentialsProvider: CredentialsProvider, - httpCall: HttpCall & { responseType: XMLHttpRequestResponseType }, - cancellationToken: CancellationToken = uncancelableToken, -): Promise { - return fetchWithDVIDCredentials( - credentialsProvider, - httpCall.url, - { method: httpCall.method, body: httpCall.payload }, - httpCall.responseType === "" - ? responseText - : httpCall.responseType === "json" - ? responseJson - : responseArrayBuffer, - cancellationToken, - ); -} - -export function fetchWithDVIDCredentials( +export function fetchWithDVIDCredentials( credentialsProvider: CredentialsProvider, input: string, init: RequestInit, - transformResponse: ResponseTransform, - cancellationToken: CancellationToken = uncancelableToken, -): Promise { - return fetchWithCredentials( +): Promise { + return fetchOkWithCredentials( credentialsProvider, input, init, - transformResponse, (credentials: DVIDToken, init: RequestInit) => { const newInit: RequestInit = { ...init }; if (credentials.token) { @@ -188,6 +98,5 @@ export function fetchWithDVIDCredentials( } throw error; }, - cancellationToken, ); } diff --git a/src/datasource/dvid/backend.ts b/src/datasource/dvid/backend.ts index 94d8ca0311..c136a10dad 100644 --- a/src/datasource/dvid/backend.ts +++ b/src/datasource/dvid/backend.ts @@ -20,7 +20,7 @@ import { WithSharedCredentialsProviderCounterpart } from "#src/credentials_provi import type { DVIDToken } from "#src/datasource/dvid/api.js"; import { DVIDInstance, - makeRequestWithCredentials, + fetchWithDVIDCredentials, appendQueryStringForDvid, } from "#src/datasource/dvid/api.js"; import { @@ -42,7 +42,6 @@ import { decodeCompressedSegmentationChunk } from "#src/sliceview/backend_chunk_ import { decodeJpegChunk } from "#src/sliceview/backend_chunk_decoders/jpeg.js"; import type { VolumeChunk } from "#src/sliceview/volume/backend.js"; import { VolumeChunkSource } from "#src/sliceview/volume/backend.js"; -import type { CancellationToken } from "#src/util/cancellation.js"; import { Endianness } from "#src/util/endian.js"; import type { SharedObject } from "#src/worker_rpc.js"; import { registerSharedObject } from "#src/worker_rpc.js"; @@ -65,7 +64,7 @@ export class DVIDSkeletonSource extends DVIDSource( SkeletonSource, SkeletonSourceParameters, ) { - download(chunk: SkeletonChunk, cancellationToken: CancellationToken) { + download(chunk: SkeletonChunk, signal: AbortSignal) { const { parameters } = this; const bodyid = `${chunk.objectId}`; const url = @@ -73,18 +72,18 @@ export class DVIDSkeletonSource extends DVIDSource( `/${parameters.dataInstanceKey}/key/` + bodyid + "_swc"; - return makeRequestWithCredentials( + return fetchWithDVIDCredentials( this.credentialsProvider, + appendQueryStringForDvid(url, parameters.user), { - method: "GET", - url: appendQueryStringForDvid(url, parameters.user), - responseType: "arraybuffer", + signal: signal, }, - cancellationToken, - ).then((response) => { - const enc = new TextDecoder("utf-8"); - decodeSwcSkeletonChunk(chunk, enc.decode(response)); - }); + ) + .then((response) => response.arrayBuffer()) + .then((response) => { + const enc = new TextDecoder("utf-8"); + decodeSwcSkeletonChunk(chunk, enc.decode(response)); + }); } } @@ -118,7 +117,7 @@ export class DVIDMeshSource extends DVIDSource( return Promise.resolve(undefined); } - downloadFragment(chunk: FragmentChunk, cancellationToken: CancellationToken) { + downloadFragment(chunk: FragmentChunk, signal: AbortSignal) { const { parameters } = this; const dvidInstance = new DVIDInstance( parameters.baseUrl, @@ -129,15 +128,15 @@ export class DVIDMeshSource extends DVIDSource( `${chunk.fragmentId}.ngmesh`, ); - return makeRequestWithCredentials( + return fetchWithDVIDCredentials( this.credentialsProvider, + appendQueryStringForDvid(meshUrl, parameters.user), { - method: "GET", - url: appendQueryStringForDvid(meshUrl, parameters.user), - responseType: "arraybuffer", + signal: signal, }, - cancellationToken, - ).then((response) => decodeFragmentChunk(chunk, response)); + ) + .then((response) => response.arrayBuffer()) + .then((response) => decodeFragmentChunk(chunk, response)); } } @@ -146,7 +145,7 @@ export class DVIDVolumeChunkSource extends DVIDSource( VolumeChunkSource, VolumeChunkSourceParameters, ) { - async download(chunk: VolumeChunk, cancellationToken: CancellationToken) { + async download(chunk: VolumeChunk, signal: AbortSignal) { const params = this.parameters; let path: string; { @@ -159,18 +158,14 @@ export class DVIDVolumeChunkSource extends DVIDSource( path = this.getPath(chunkPosition, chunkDataSize); } const decoder = this.getDecoder(params); - const response = await makeRequestWithCredentials( + const response = await fetchWithDVIDCredentials( this.credentialsProvider, - { - method: "GET", - url: appendQueryStringForDvid(`${params.baseUrl}${path}`, params.user), - responseType: "arraybuffer", - }, - cancellationToken, - ); + appendQueryStringForDvid(`${params.baseUrl}${path}`, params.user), + { signal: signal }, + ).then((response) => response.arrayBuffer()); await decoder( chunk, - cancellationToken, + signal, params.encoding === VolumeChunkEncoding.JPEG ? response.slice(16) : response, diff --git a/src/datasource/dvid/credentials_provider.ts b/src/datasource/dvid/credentials_provider.ts index 24362dfa2b..74dd40f515 100644 --- a/src/datasource/dvid/credentials_provider.ts +++ b/src/datasource/dvid/credentials_provider.ts @@ -23,26 +23,21 @@ import { CredentialsProvider, makeCredentialsGetter, } from "#src/credentials_provider/index.js"; +import { getCredentialsWithStatus } from "#src/credentials_provider/interactive_credentials_provider.js"; import type { DVIDToken } from "#src/datasource/dvid/api.js"; -import { responseText } from "#src/datasource/dvid/api.js"; -import { StatusMessage } from "#src/status.js"; -import { - CANCELED, - CancellationTokenSource, - uncancelableToken, -} from "#src/util/cancellation.js"; -import { cancellableFetchOk } from "#src/util/http_request.js"; +import { fetchOk } from "#src/util/http_request.js"; +import { ProgressSpan } from "#src/util/progress_listener.js"; async function getAuthToken( authServer: string, - cancellationToken = uncancelableToken, + signal: AbortSignal, ): Promise { - const token = await cancellableFetchOk( - authServer, - { method: "GET", credentials: "include" }, - responseText, - cancellationToken, - ); + const response = await fetchOk(authServer, { + method: "GET", + credentials: "include", + signal: signal, + }); + const token = await response.text(); return { token }; } @@ -51,80 +46,36 @@ class BaseDVIDCredentialsProvider extends CredentialsProvider { super(); } - get = makeCredentialsGetter((cancellationToken) => { - if (!this.authServer) return Promise.resolve({ token: "" }); - const status = new StatusMessage(/*delay=*/ true); - let cancellationSource: CancellationTokenSource | undefined; - return new Promise((resolve, reject) => { - const dispose = () => { - cancellationSource = undefined; - status.dispose(); - }; - cancellationToken.add(() => { - if (cancellationSource !== undefined) { - cancellationSource.cancel(); - cancellationSource = undefined; - status.dispose(); - reject(CANCELED); - } - }); - function writeAuthStatus( - authServer: string, - msg = "DVID authorization required.", - linkMessage = "Request authorization.", - ) { - status.setText(msg + " "); - const button = document.createElement("button"); - button.textContent = linkMessage; - status.element.appendChild(button); - button.addEventListener("click", () => { + get = makeCredentialsGetter(async (options) => { + const { authServer } = this; + if (!authServer) return { token: "" }; + using _span = new ProgressSpan(options.progressListener, { + message: `Requesting DVID access token from ${authServer}`, + }); + return await getCredentialsWithStatus( + { + description: `DVID server ${this.authServer}`, + supportsImmediate: true, + get: async (signal, immediate) => { + if (immediate) { + return await getAuthToken(authServer, signal); + } // In the current DVID setup, https://flyemlogin. is expected for the login server const match = authServer.match(/^[^/]+\/\/[^/.]+\.([^/]+)/); if (match) { const loginServer = `https://flyemlogin.${match[1]}/login`; - window.alert( + throw new Error( `Please log into ${loginServer} and then refresh the neurogalncer page to try again.\nIf you are unable to log into ${loginServer}, please check your authorization server ${authServer} to make sure it is correct.`, ); } else { - window.alert( + throw new Error( `Please check your authorization server ${authServer} to make sure it is correct.`, ); } - }); - status.setVisible(true); - } - - function requestAuth(authServer: string) { - if (cancellationSource !== undefined) { - cancellationSource.cancel(); - } - cancellationSource = new CancellationTokenSource(); - writeAuthStatus( - authServer, - "Waiting for DVID authorization...", - "Retry", - ); - getAuthToken(authServer, cancellationSource).then( - (token) => { - if (cancellationSource !== undefined) { - dispose(); - resolve(token); - } - }, - (reason) => { - if (cancellationSource !== undefined) { - cancellationSource = undefined; - writeAuthStatus( - authServer, - `DVID authorization failed: ${reason}.`, - "Retry", - ); - } - }, - ); - } - requestAuth(this.authServer!); - }); + }, + }, + options.signal, + ); }); } diff --git a/src/datasource/dvid/frontend.ts b/src/datasource/dvid/frontend.ts index 9121f80821..d4db7ffa4e 100644 --- a/src/datasource/dvid/frontend.ts +++ b/src/datasource/dvid/frontend.ts @@ -29,14 +29,11 @@ import { makeIdentityTransformedBoundingBox, } from "#src/coordinate_transform.js"; import { WithCredentialsProvider } from "#src/credentials_provider/chunk_source_frontend.js"; -import type { - CredentialsManager, - CredentialsProvider, -} from "#src/credentials_provider/index.js"; +import type { CredentialsProvider } from "#src/credentials_provider/index.js"; import type { DVIDToken } from "#src/datasource/dvid/api.js"; import { credentialsKey, - makeRequestWithCredentials, + fetchWithDVIDCredentials, } from "#src/datasource/dvid/api.js"; import type { DVIDSourceParameters } from "#src/datasource/dvid/base.js"; import { @@ -50,8 +47,8 @@ import type { CompletionResult, DataSource, GetDataSourceOptions, + DataSourceProvider, } from "#src/datasource/index.js"; -import { DataSourceProvider } from "#src/datasource/index.js"; import { MeshSource } from "#src/mesh/frontend.js"; import { SkeletonSource } from "#src/skeleton/frontend.js"; import type { SliceViewSingleResolutionSource } from "#src/sliceview/frontend.js"; @@ -65,7 +62,6 @@ import { MultiscaleVolumeChunkSource, VolumeChunkSource, } from "#src/sliceview/volume/frontend.js"; -import { StatusMessage } from "#src/status.js"; import { transposeNestedArrays } from "#src/util/array.js"; import { applyCompletionOffset, @@ -85,6 +81,8 @@ import { verifyPositiveInt, verifyString, } from "#src/util/json.js"; +import type { ProgressOptions } from "#src/util/progress_listener.js"; +import { ProgressSpan } from "#src/util/progress_listener.js"; const serverDataTypes = new Map(); serverDataTypes.set("uint8", DataType.UINT8); @@ -453,22 +451,21 @@ export function getServerInfo( chunkManager: ChunkManager, baseUrl: string, credentialsProvider: CredentialsProvider, + options: Partial, ) { - return chunkManager.memoize.getUncounted( + return chunkManager.memoize.getAsync( { type: "dvid:getServerInfo", baseUrl }, - () => { - const result = makeRequestWithCredentials(credentialsProvider, { - url: `${baseUrl}/api/repos/info`, - method: "GET", - responseType: "json", - }).then((response) => new ServerInfo(response)); - const description = `repository info for DVID server ${baseUrl}`; - StatusMessage.forPromise(result, { - initialMessage: `Retrieving ${description}.`, - delay: true, - errorPrefix: `Error retrieving ${description}: `, + options, + async (progressOptions) => { + using _span = new ProgressSpan(progressOptions.progressListener, { + message: `Retrieving repository info for DVID server ${baseUrl}`, }); - return result; + const response = await fetchWithDVIDCredentials( + credentialsProvider, + `${baseUrl}/api/repos/info`, + progressOptions, + ); + return new ServerInfo(await response.json()); }, ); } @@ -568,7 +565,7 @@ function getVolumeSource( }); const volume = new DvidMultiscaleVolumeChunkSource( - options.chunkManager, + options.registry.chunkManager, baseUrl, nodeKey, dataInstanceKey, @@ -595,7 +592,7 @@ function getVolumeSource( id: "meshes", default: true, subsource: { - mesh: options.chunkManager.getChunkSource(DVIDMeshSource, { + mesh: options.registry.chunkManager.getChunkSource(DVIDMeshSource, { parameters: { ...sourceParameters, dataInstanceKey: info.meshSrc, @@ -611,7 +608,7 @@ function getVolumeSource( id: "skeletons", default: true, subsource: { - mesh: options.chunkManager.getChunkSource(DVIDSkeletonSource, { + mesh: options.registry.chunkManager.getChunkSource(DVIDSkeletonSource, { parameters: { ...sourceParameters, dataInstanceKey: info.skeletonSrc, @@ -638,16 +635,17 @@ export function getDataSource( const sourceParameters = parseSourceUrl(options.providerUrl); const { baseUrl, nodeKey, dataInstanceKey } = sourceParameters; - return options.chunkManager.memoize.getUncounted( + return options.registry.chunkManager.memoize.getAsync( { type: "dvid:MultiscaleVolumeChunkSource", baseUrl, nodeKey: nodeKey, dataInstanceKey, }, - async () => { + options, + async (progressOptions) => { const credentailsProvider = - options.credentialsManager.getCredentialsProvider( + options.registry.credentialsManager.getCredentialsProvider( credentialsKey, { dvidServer: sourceParameters.baseUrl, @@ -655,9 +653,10 @@ export function getDataSource( }, ); const serverInfo = await getServerInfo( - options.chunkManager, + options.registry.chunkManager, baseUrl, credentailsProvider, + progressOptions, ); const repositoryInfo = serverInfo.getNode(nodeKey); if (repositoryInfo === undefined) { @@ -740,12 +739,13 @@ export async function completeUrl( const authServer = getDefaultAuthServer(baseUrl); const serverInfo = await getServerInfo( - options.chunkManager, + options.registry.chunkManager, baseUrl, - options.credentialsManager.getCredentialsProvider( + options.registry.credentialsManager.getCredentialsProvider( credentialsKey, { dvidServer: baseUrl, authServer }, ), + options, ); return applyCompletionOffset( baseUrl.length + 1, @@ -753,11 +753,10 @@ export async function completeUrl( ); } -export class DVIDDataSource extends DataSourceProvider { - constructor(public credentialsManager: CredentialsManager) { - super(); +export class DVIDDataSource implements DataSourceProvider { + get scheme() { + return "dvid"; } - get description() { return "DVID"; } diff --git a/src/datasource/dvid/register_credentials_provider.ts b/src/datasource/dvid/register_credentials_provider.ts index d14e3bb2e9..42891dc49a 100644 --- a/src/datasource/dvid/register_credentials_provider.ts +++ b/src/datasource/dvid/register_credentials_provider.ts @@ -18,11 +18,11 @@ * limitations under the License. */ -import { defaultCredentialsManager } from "#src/credentials_provider/default_manager.js"; +import { registerDefaultCredentialsProvider } from "#src/credentials_provider/default_manager.js"; import { credentialsKey } from "#src/datasource/dvid/api.js"; import { DVIDCredentialsProvider } from "#src/datasource/dvid/credentials_provider.js"; -defaultCredentialsManager.register( +registerDefaultCredentialsProvider( credentialsKey, (params: { dvidServer: string; authServer: string | undefined }) => new DVIDCredentialsProvider(params.dvidServer, params.authServer), diff --git a/src/datasource/dvid/register_default.ts b/src/datasource/dvid/register_default.ts index ac96fb56f7..810a8dbb79 100644 --- a/src/datasource/dvid/register_default.ts +++ b/src/datasource/dvid/register_default.ts @@ -17,7 +17,4 @@ import { registerProvider } from "#src/datasource/default_provider.js"; import { DVIDDataSource } from "#src/datasource/dvid/frontend.js"; -registerProvider( - "dvid", - (options) => new DVIDDataSource(options.credentialsManager), -); +registerProvider(new DVIDDataSource()); diff --git a/src/datasource/enabled_async_computation_modules.ts b/src/datasource/enabled_async_computation_modules.ts index 94f0d6043b..2607da3fce 100644 --- a/src/datasource/enabled_async_computation_modules.ts +++ b/src/datasource/enabled_async_computation_modules.ts @@ -5,7 +5,6 @@ import "#datasource/deepzoom/async_computation"; import "#datasource/dvid/async_computation"; import "#datasource/graphene/async_computation"; import "#datasource/n5/async_computation"; -import "#datasource/nifti/async_computation"; import "#datasource/obj/async_computation"; import "#datasource/precomputed/async_computation"; import "#datasource/render/async_computation"; diff --git a/src/datasource/enabled_backend_modules.ts b/src/datasource/enabled_backend_modules.ts index 926dea0f29..62f3d8564e 100644 --- a/src/datasource/enabled_backend_modules.ts +++ b/src/datasource/enabled_backend_modules.ts @@ -5,7 +5,6 @@ import "#datasource/deepzoom/backend"; import "#datasource/dvid/backend"; import "#datasource/graphene/backend"; import "#datasource/n5/backend"; -import "#datasource/nggraph/backend"; import "#datasource/nifti/backend"; import "#datasource/obj/backend"; import "#datasource/precomputed/backend"; diff --git a/src/datasource/enabled_frontend_modules.ts b/src/datasource/enabled_frontend_modules.ts index 96b934b7b7..264c63800b 100644 --- a/src/datasource/enabled_frontend_modules.ts +++ b/src/datasource/enabled_frontend_modules.ts @@ -7,13 +7,12 @@ import "#datasource/deepzoom/register_default"; import "#datasource/dvid/register_default"; import "#datasource/dvid/register_credentials_provider"; import "#datasource/graphene/register_default"; -import "#datasource/middleauth/register_credentials_provider"; import "#datasource/n5/register_default"; -import "#datasource/ngauth/register_credentials_provider"; import "#datasource/nggraph/register_default"; import "#datasource/nifti/register_default"; import "#datasource/obj/register_default"; import "#datasource/precomputed/register_default"; +import "#datasource/python/register_default"; import "#datasource/render/register_default"; import "#datasource/vtk/register_default"; import "#datasource/zarr/register_default"; diff --git a/src/datasource/graphene/async_computation.ts b/src/datasource/graphene/async_computation.ts index 69e1442c3a..6ffe0e5ecb 100644 --- a/src/datasource/graphene/async_computation.ts +++ b/src/datasource/graphene/async_computation.ts @@ -1,2 +1 @@ import "#src/async_computation/decode_jpeg.js"; -import "#src/async_computation/decode_gzip.js"; diff --git a/src/datasource/graphene/backend.ts b/src/datasource/graphene/backend.ts index b49783b22d..987c48d831 100644 --- a/src/datasource/graphene/backend.ts +++ b/src/datasource/graphene/backend.ts @@ -22,20 +22,22 @@ import { ChunkSource, } from "#src/chunk_manager/backend.js"; import { ChunkPriorityTier, ChunkState } from "#src/chunk_manager/base.js"; -import { WithSharedCredentialsProviderCounterpart } from "#src/credentials_provider/shared_counterpart.js"; import type { ChunkedGraphChunkSpecification } from "#src/datasource/graphene/base.js"; import { getGrapheneFragmentKey, GRAPHENE_MESH_NEW_SEGMENT_RPC_ID, - responseIdentity, ChunkedGraphSourceParameters, MeshSourceParameters, CHUNKED_GRAPH_LAYER_RPC_ID, CHUNKED_GRAPH_RENDER_LAYER_UPDATE_SOURCES_RPC_ID, RENDER_RATIO_LIMIT, isBaseSegmentId, + parseGrapheneError, } from "#src/datasource/graphene/base.js"; import { decodeManifestChunk } from "#src/datasource/precomputed/backend.js"; +import { WithSharedKvStoreContextCounterpart } from "#src/kvstore/backend.js"; +import type { KvStoreWithPath, ReadResponse } from "#src/kvstore/index.js"; +import { readKvStore } from "#src/kvstore/index.js"; import type { FragmentChunk, ManifestChunk } from "#src/mesh/backend.js"; import { assignMeshFragmentData, MeshSource } from "#src/mesh/backend.js"; import { decodeDraco } from "#src/mesh/draco/index.js"; @@ -60,15 +62,8 @@ import { } from "#src/sliceview/base.js"; import { computeChunkBounds } from "#src/sliceview/volume/backend.js"; import { Uint64Set } from "#src/uint64_set.js"; -import { fetchSpecialHttpByteRange } from "#src/util/byte_range_http_requests.js"; -import type { CancellationToken } from "#src/util/cancellation.js"; import { vec3, vec3Key } from "#src/util/geom.js"; -import { responseArrayBuffer, responseJson } from "#src/util/http_request.js"; -import type { - SpecialProtocolCredentials, - SpecialProtocolCredentialsProvider, -} from "#src/util/special_protocol_request.js"; -import { cancellableFetchSpecialOk } from "#src/util/special_protocol_request.js"; +import { HttpError } from "#src/util/http_request.js"; import { Uint64 } from "#src/util/uint64.js"; import { getBasePriority, @@ -78,77 +73,67 @@ import { import type { RPC } from "#src/worker_rpc.js"; import { registerSharedObject, registerRPC } from "#src/worker_rpc.js"; -function getVerifiedFragmentPromise( - credentialsProvider: SpecialProtocolCredentialsProvider, - chunk: FragmentChunk, - parameters: MeshSourceParameters, - cancellationToken: CancellationToken, -) { - if (chunk.fragmentId && chunk.fragmentId.charAt(0) === "~") { - const parts = chunk.fragmentId.substr(1).split(":"); - const startOffset = Number(parts[1]); - const endOffset = startOffset + Number(parts[2]); - return fetchSpecialHttpByteRange( - credentialsProvider, - `${parameters.fragmentUrl}/initial/${parts[0]}`, - startOffset, - endOffset, - cancellationToken, +function downloadFragmentWithSharding( + fragmentKvStore: KvStoreWithPath, + fragmentId: string, + signal: AbortSignal, +): Promise { + if (fragmentId && fragmentId.charAt(0) === "~") { + const parts = fragmentId.substring(1).split(":"); + const byteRange = { offset: Number(parts[1]), length: Number(parts[2]) }; + return readKvStore( + fragmentKvStore.store, + `${fragmentKvStore.path}initial/${parts[0]}`, + { signal, byteRange, throwIfMissing: true }, ); } - return cancellableFetchSpecialOk( - credentialsProvider, - `${parameters.fragmentUrl}/dynamic/${chunk.fragmentId}`, - {}, - responseArrayBuffer, - cancellationToken, + return readKvStore( + fragmentKvStore.store, + `${fragmentKvStore.path}dynamic/${fragmentId}`, + { signal, throwIfMissing: true }, ); } -function getFragmentDownloadPromise( - credentialsProvider: SpecialProtocolCredentialsProvider, - chunk: FragmentChunk, +function downloadFragment( + fragmentKvStore: KvStoreWithPath, + fragmentId: string, parameters: MeshSourceParameters, - cancellationToken: CancellationToken, -) { - let fragmentDownloadPromise; + signal: AbortSignal, +): Promise { if (parameters.sharding) { - fragmentDownloadPromise = getVerifiedFragmentPromise( - credentialsProvider, - chunk, - parameters, - cancellationToken, - ); + return downloadFragmentWithSharding(fragmentKvStore, fragmentId, signal); } else { - fragmentDownloadPromise = cancellableFetchSpecialOk( - credentialsProvider, - `${parameters.fragmentUrl}/${chunk.fragmentId}`, - {}, - responseArrayBuffer, - cancellationToken, + return readKvStore( + fragmentKvStore.store, + `${fragmentKvStore.path}/${fragmentId}`, + { signal, throwIfMissing: true }, ); } - return fragmentDownloadPromise; } async function decodeDracoFragmentChunk( chunk: FragmentChunk, - response: ArrayBuffer, + response: Uint8Array, ) { - const rawMesh = await decodeDraco(new Uint8Array(response)); + const rawMesh = await decodeDraco(response); assignMeshFragmentData(chunk, rawMesh); } @registerSharedObject() export class GrapheneMeshSource extends WithParameters( - WithSharedCredentialsProviderCounterpart()( - MeshSource, - ), + WithSharedKvStoreContextCounterpart(MeshSource), MeshSourceParameters, ) { manifestRequestCount = new Map(); newSegments = new Uint64Set(); + manifestKvStore = this.sharedKvStoreContext.kvStoreContext.getKvStore( + this.parameters.manifestUrl, + ); + fragmentKvStore = this.sharedKvStoreContext.kvStoreContext.getKvStore( + this.parameters.fragmentUrl, + ); + addNewSegment(segment: Uint64) { const { newSegments } = this; newSegments.add(segment); @@ -158,53 +143,49 @@ export class GrapheneMeshSource extends WithParameters( }, TEN_MINUTES); } - async download(chunk: ManifestChunk, cancellationToken: CancellationToken) { + async download(chunk: ManifestChunk, signal: AbortSignal) { const { parameters, newSegments, manifestRequestCount } = this; if (isBaseSegmentId(chunk.objectId, parameters.nBitsForLayerId)) { return decodeManifestChunk(chunk, { fragments: [] }); } - const url = `${parameters.manifestUrl}/manifest`; - const manifestUrl = `${url}/${chunk.objectId}:${parameters.lod}?verify=1&prepend_seg_ids=1`; - await cancellableFetchSpecialOk( - this.credentialsProvider, - manifestUrl, - {}, - responseJson, - cancellationToken, - ).then((response) => { - const chunkIdentifier = manifestUrl; - if (newSegments.has(chunk.objectId)) { - const requestCount = - (manifestRequestCount.get(chunkIdentifier) || 0) + 1; - manifestRequestCount.set(chunkIdentifier, requestCount); - setTimeout( - () => { - this.chunkManager.queueManager.updateChunkState( - chunk, - ChunkState.QUEUED, - ); - }, - 2 ** requestCount * 1000, - ); - } else { - manifestRequestCount.delete(chunkIdentifier); - } - return decodeManifestChunk(chunk, response); - }); + const { manifestKvStore } = this; + const manifestPath = `${manifestKvStore.path}/manifest/${chunk.objectId}:${parameters.lod}?verify=1&prepend_seg_ids=1`; + const response = await ( + await readKvStore(manifestKvStore.store, manifestPath, { + throwIfMissing: true, + signal, + }) + ).response.json(); + const chunkIdentifier = manifestPath; + if (newSegments.has(chunk.objectId)) { + const requestCount = (manifestRequestCount.get(chunkIdentifier) ?? 0) + 1; + manifestRequestCount.set(chunkIdentifier, requestCount); + setTimeout( + () => { + this.chunkManager.queueManager.updateChunkState( + chunk, + ChunkState.QUEUED, + ); + }, + 2 ** requestCount * 1000, + ); + } else { + manifestRequestCount.delete(chunkIdentifier); + } + return decodeManifestChunk(chunk, response); } - async downloadFragment( - chunk: FragmentChunk, - cancellationToken: CancellationToken, - ) { - const { parameters } = this; - const response = await getFragmentDownloadPromise( - undefined, + async downloadFragment(chunk: FragmentChunk, signal: AbortSignal) { + const { response } = await downloadFragment( + this.fragmentKvStore, + chunk.fragmentId!, + this.parameters, + signal, + ); + await decodeDracoFragmentChunk( chunk, - parameters, - cancellationToken, + new Uint8Array(await response.arrayBuffer()), ); - await decodeDracoFragmentChunk(chunk, response); } getFragmentKey(objectKey: string | null, fragmentId: string) { @@ -262,16 +243,18 @@ function decodeChunkedGraphChunk(leaves: string[]) { @registerSharedObject() export class GrapheneChunkedGraphChunkSource extends WithParameters( - WithSharedCredentialsProviderCounterpart()( - ChunkSource, - ), + WithSharedKvStoreContextCounterpart(ChunkSource), ChunkedGraphSourceParameters, ) { spec: ChunkedGraphChunkSpecification; - chunks: Map; + declare chunks: Map; tempChunkDataSize: Uint32Array; tempChunkPosition: Float32Array; + kvStore = this.sharedKvStoreContext.kvStoreContext.getKvStore( + this.parameters.url, + ); + constructor(rpc: RPC, options: any) { super(rpc, options); this.spec = options.spec; @@ -280,11 +263,7 @@ export class GrapheneChunkedGraphChunkSource extends WithParameters( this.tempChunkPosition = new Float32Array(rank); } - async download( - chunk: ChunkedGraphChunk, - cancellationToken: CancellationToken, - ): Promise { - const { parameters } = this; + async download(chunk: ChunkedGraphChunk, signal: AbortSignal): Promise { const chunkPosition = this.computeChunkBounds(chunk); const chunkDataSize = chunk.chunkDataSize!; const bounds = @@ -292,22 +271,25 @@ export class GrapheneChunkedGraphChunkSource extends WithParameters( `${chunkPosition[1]}-${chunkPosition[1] + chunkDataSize[1]}_` + `${chunkPosition[2]}-${chunkPosition[2] + chunkDataSize[2]}`; - const request = cancellableFetchSpecialOk( - this.credentialsProvider, - `${parameters.url}/${chunk.segment}/leaves?int64_as_str=1&bounds=${bounds}`, - {}, - responseIdentity, - cancellationToken, + const { kvStore } = this; + + const request = readKvStore( + kvStore.store, + `${kvStore.path}/${chunk.segment}/leaves?int64_as_str=1&bounds=${bounds}`, + { signal, throwIfMissing: true }, ); await this.withErrorMessage( request, `Fetching leaves of segment ${chunk.segment} in region ${bounds}: `, ) - .then((res) => res.json()) + .then((res) => res.response.json()) .then((res) => { chunk.leaves = decodeChunkedGraphChunk(res.leaf_ids); }) - .catch((err) => console.error(err)); + .catch((err) => { + if (err instanceof Error && err.name === "AbortError") return; + console.error(err); + }); } getChunk(chunkGridPosition: Float32Array, segment: Uint64) { @@ -326,21 +308,17 @@ export class GrapheneChunkedGraphChunkSource extends WithParameters( return computeChunkBounds(this, chunk); } - async withErrorMessage( - promise: Promise, + async withErrorMessage( + promise: Promise, errorPrefix: string, - ): Promise { - const response = await promise; - if (response.ok) { - return response; - } - let msg: string; - try { - msg = (await response.json()).message; - } catch { - msg = await response.text(); - } - throw new Error(`[${response.status}] ${errorPrefix}${msg}`); + ): Promise { + return promise.catch(async (e) => { + if (e instanceof HttpError && e.response) { + const msg = await parseGrapheneError(e); + throw new Error(`[${e.response.status}] ${errorPrefix}${msg ?? ""}`); + } + throw e; + }); } } diff --git a/src/datasource/graphene/base.ts b/src/datasource/graphene/base.ts index 52048f98db..aedf2a291b 100644 --- a/src/datasource/graphene/base.ts +++ b/src/datasource/graphene/base.ts @@ -25,6 +25,7 @@ import type { } from "#src/sliceview/base.js"; import { makeSliceViewChunkSpecification } from "#src/sliceview/base.js"; import type { mat4 } from "#src/util/geom.js"; +import type { HttpError } from "#src/util/http_request.js"; import { Uint64 } from "#src/util/uint64.js"; @@ -68,8 +69,6 @@ export class MultiscaleMeshMetadata { sharding: Array | undefined; } -export const responseIdentity = async (x: any) => x; - export function isBaseSegmentId(segmentId: Uint64, nBitsForLayerId: number) { const layerId = Uint64.rshift(new Uint64(), segmentId, 64 - nBitsForLayerId); return Uint64.equal(layerId, Uint64.ONE); @@ -139,3 +138,16 @@ export function makeChunkedGraphChunkSpecification( export interface ChunkedGraphChunkSource extends SliceViewChunkSource { spec: ChunkedGraphChunkSpecification; } + +export async function parseGrapheneError(e: HttpError) { + if (e.response) { + let msg: string; + if (e.response.headers.get("content-type") === "application/json") { + msg = (await e.response.json()).message; + } else { + msg = await e.response.text(); + } + return msg; + } + return undefined; +} diff --git a/src/datasource/graphene/frontend.ts b/src/datasource/graphene/frontend.ts index 04a1281b69..b0966e59ae 100644 --- a/src/datasource/graphene/frontend.ts +++ b/src/datasource/graphene/frontend.ts @@ -34,14 +34,13 @@ import { LayerChunkProgressInfo } from "#src/chunk_manager/base.js"; import type { ChunkManager } from "#src/chunk_manager/frontend.js"; import { WithParameters } from "#src/chunk_manager/frontend.js"; import { makeIdentityTransform } from "#src/coordinate_transform.js"; -import { WithCredentialsProvider } from "#src/credentials_provider/chunk_source_frontend.js"; -import type { CredentialsManager } from "#src/credentials_provider/index.js"; import type { ChunkedGraphChunkSource as ChunkedGraphChunkSourceInterface, ChunkedGraphChunkSpecification, MultiscaleMeshMetadata, } from "#src/datasource/graphene/base.js"; import { + parseGrapheneError, CHUNKED_GRAPH_LAYER_RPC_ID, CHUNKED_GRAPH_RENDER_LAYER_UPDATE_SOURCES_RPC_ID, ChunkedGraphSourceParameters, @@ -51,14 +50,14 @@ import { makeChunkedGraphChunkSpecification, MeshSourceParameters, PYCG_APP_VERSION, - responseIdentity, } from "#src/datasource/graphene/base.js"; import type { DataSource, + DataSourceLookupResult, DataSubsourceEntry, - GetDataSourceOptions, + GetKvStoreBasedDataSourceOptions, + KvStoreBasedDataSourceProvider, } from "#src/datasource/index.js"; -import { RedirectError } from "#src/datasource/index.js"; import type { ShardingParameters } from "#src/datasource/precomputed/base.js"; import { DataEncoding, @@ -68,11 +67,16 @@ import type { MultiscaleVolumeInfo } from "#src/datasource/precomputed/frontend. import { getSegmentPropertyMap, parseMultiscaleVolumeInfo, - parseProviderUrl, - PrecomputedDataSource, PrecomputedMultiscaleVolumeChunkSource, - resolvePath, } from "#src/datasource/precomputed/frontend.js"; +import { WithSharedKvStoreContext } from "#src/kvstore/chunk_source_frontend.js"; +import type { SharedKvStoreContext } from "#src/kvstore/frontend.js"; +import { HttpKvStore } from "#src/kvstore/http/index.js"; +import { + ensureEmptyUrlSuffix, + kvstoreEnsureDirectoryPipelineUrl, + pipelineUrlJoin, +} from "#src/kvstore/url.js"; import type { LayerView, MouseSelectionState, @@ -161,11 +165,8 @@ import type { ValueOrError } from "#src/util/error.js"; import { makeValueOrError, valueOrThrow } from "#src/util/error.js"; import { EventActionMap } from "#src/util/event_action_map.js"; import { mat4, vec3, vec4 } from "#src/util/geom.js"; -import { - HttpError, - isNotFoundError, - responseJson, -} from "#src/util/http_request.js"; +import type { FetchOk } from "#src/util/http_request.js"; +import { HttpError, isNotFoundError } from "#src/util/http_request.js"; import { parseArray, parseFixedLengthArray, @@ -183,16 +184,9 @@ import { verifyPositiveInt, verifyString, } from "#src/util/json.js"; -import { getObjectId } from "#src/util/object_id.js"; +import type { ProgressOptions } from "#src/util/progress_listener.js"; +import { ProgressSpan } from "#src/util/progress_listener.js"; import { NullarySignal } from "#src/util/signal.js"; -import type { - SpecialProtocolCredentials, - SpecialProtocolCredentialsProvider, -} from "#src/util/special_protocol_request.js"; -import { - cancellableFetchSpecialOk, - parseSpecialUrl, -} from "#src/util/special_protocol_request.js"; import type { Trackable } from "#src/util/trackable.js"; import { Uint64 } from "#src/util/uint64.js"; import { makeDeleteButton } from "#src/widget/delete_button.js"; @@ -218,7 +212,7 @@ const TRANSPARENT_COLOR_PACKED = new Uint64(packColor(TRANSPARENT_COLOR)); const MULTICUT_OFF_COLOR = vec4.fromValues(0, 0, 0, 0.5); class GrapheneMeshSource extends WithParameters( - WithCredentialsProvider()(MeshSource), + WithSharedKvStoreContext(MeshSource), MeshSourceParameters, ) { getFragmentKey(objectKey: string | null, fragmentId: string) { @@ -235,7 +229,7 @@ class AppInfo { // .../1.0/... is the legacy link style // .../table/... is the current, version agnostic link style (for retrieving the info file) const linkStyle = - /^(https?:\/\/[.\w:\-/]+)\/segmentation\/(?:1\.0|table)\/([^/]+)\/?$/; + /^((?:middleauth\+)?https?:\/\/[.\w:\-/]+)\/segmentation\/(?:1\.0|table)\/([^/]+)\/?$/; const match = infoUrl.match(linkStyle); if (match === null) { throw Error(`Graph URL invalid: ${infoUrl}`); @@ -250,11 +244,11 @@ class AppInfo { "supported_api_versions", (x) => parseArray(x, verifyNonnegativeInt), ); - } catch (error) { + } catch { // Dealing with a prehistoric graph server with no version information this.supported_api_versions = [0]; } - if (PYCG_APP_VERSION in this.supported_api_versions === false) { + if (this.supported_api_versions.includes(PYCG_APP_VERSION) === false) { const redirectMsg = `This Neuroglancer branch requires Graph Server version ${PYCG_APP_VERSION}, but the server only supports version(s) ${this.supported_api_versions}.`; throw new Error(redirectMsg); } @@ -289,12 +283,9 @@ interface GrapheneMultiscaleVolumeInfo extends MultiscaleVolumeInfo { function parseGrapheneMultiscaleVolumeInfo( obj: unknown, url: string, - credentialsManager: CredentialsManager, ): GrapheneMultiscaleVolumeInfo { const volumeInfo = parseMultiscaleVolumeInfo(obj); - const dataUrl = verifyObjectProperty(obj, "data_dir", (x) => - parseSpecialUrl(x, credentialsManager), - ).url; + const dataUrl = verifyObjectProperty(obj, "data_dir", verifyString); const app = verifyObjectProperty(obj, "app", (x) => new AppInfo(url, x)); const graph = verifyObjectProperty(obj, "graph", (x) => new GraphInfo(x)); return { @@ -307,11 +298,10 @@ function parseGrapheneMultiscaleVolumeInfo( class GrapheneMultiscaleVolumeChunkSource extends PrecomputedMultiscaleVolumeChunkSource { constructor( - chunkManager: ChunkManager, - public chunkedGraphCredentialsProvider: SpecialProtocolCredentialsProvider, + sharedKvStoreContext: SharedKvStoreContext, public info: GrapheneMultiscaleVolumeInfo, ) { - super(chunkManager, undefined, info.dataUrl, info); + super(sharedKvStoreContext, info.dataUrl, info); } getChunkedGraphSource() { @@ -346,7 +336,7 @@ class GrapheneMultiscaleVolumeChunkSource extends PrecomputedMultiscaleVolumeChu GrapheneChunkedGraphChunkSource, { spec, - credentialsProvider: this.chunkedGraphCredentialsProvider, + sharedKvStoreContext: this.sharedKvStoreContext, parameters: { url: `${this.info.app!.segmentationUrl}/node` }, }, ), @@ -435,13 +425,18 @@ function parseMeshMetadata(data: any): ParsedMeshMetadata { } async function getMeshMetadata( - chunkManager: ChunkManager, - credentialsProvider: SpecialProtocolCredentialsProvider, + sharedKvStoreContext: SharedKvStoreContext, url: string, + options: Partial, ): Promise { let metadata: any; try { - metadata = await getJsonMetadata(chunkManager, credentialsProvider, url); + metadata = await getJsonMetadata( + sharedKvStoreContext, + url, + /*required=*/ false, + options, + ); } catch (e) { if (isNotFoundError(e)) { // If we fail to fetch the info file, assume it is the legacy @@ -517,27 +512,26 @@ function parseGrapheneShardingParameters( } function getShardedMeshSource( - chunkManager: ChunkManager, + sharedKvStoreContext: SharedKvStoreContext, parameters: MeshSourceParameters, - credentialsProvider: SpecialProtocolCredentialsProvider, ) { - return chunkManager.getChunkSource(GrapheneMeshSource, { + return sharedKvStoreContext.chunkManager.getChunkSource(GrapheneMeshSource, { + sharedKvStoreContext, parameters, - credentialsProvider, }); } async function getMeshSource( - chunkManager: ChunkManager, - credentialsProvider: SpecialProtocolCredentialsProvider, + sharedKvStoreContext: SharedKvStoreContext, url: string, fragmentUrl: string, nBitsForLayerId: number, + options: ProgressOptions, ) { const { metadata, segmentPropertyMap } = await getMeshMetadata( - chunkManager, - undefined, + sharedKvStoreContext, fragmentUrl, + options, ); const parameters: MeshSourceParameters = { manifestUrl: url, @@ -548,30 +542,35 @@ async function getMeshSource( }; const transform = metadata?.transform || mat4.create(); return { - source: getShardedMeshSource(chunkManager, parameters, credentialsProvider), + source: getShardedMeshSource(sharedKvStoreContext, parameters), transform, segmentPropertyMap, }; } -function getJsonMetadata( - chunkManager: ChunkManager, - credentialsProvider: SpecialProtocolCredentialsProvider, +export function getJsonMetadata( + sharedKvStoreContext: SharedKvStoreContext, url: string, + required: boolean, + options: Partial, ): Promise { - return chunkManager.memoize.getUncounted( + return sharedKvStoreContext.chunkManager.memoize.getAsync( { - type: "graphene:metadata", + type: "precomputed:metadata", url, - credentialsProvider: getObjectId(credentialsProvider), }, - async () => { - return await cancellableFetchSpecialOk( - credentialsProvider, - `${url}/info`, - {}, - responseJson, - ); + options, + async (options) => { + const infoUrl = pipelineUrlJoin(url, "info"); + using _span = new ProgressSpan(options.progressListener, { + message: `Reading graphene metadata from ${infoUrl}`, + }); + const response = await sharedKvStoreContext.kvStoreContext.read(infoUrl, { + ...options, + throwIfMissing: required, + }); + if (response === undefined) return undefined; + return await response.response.json(); }, ); } @@ -586,31 +585,22 @@ function getSubsourceToModelSubspaceTransform(info: MultiscaleVolumeInfo) { } async function getVolumeDataSource( - options: GetDataSourceOptions, - credentialsProvider: SpecialProtocolCredentialsProvider, + sharedKvStoreContext: SharedKvStoreContext, url: string, metadata: any, + options: ProgressOptions, + stateJson: any, ): Promise { - const info = parseGrapheneMultiscaleVolumeInfo( - metadata, - url, - options.credentialsManager, - ); + const info = parseGrapheneMultiscaleVolumeInfo(metadata, url); const volume = new GrapheneMultiscaleVolumeChunkSource( - options.chunkManager, - credentialsProvider, + sharedKvStoreContext, info, ); const state = new GrapheneState(); - if (options.state) { - state.restoreState(options.state); + if (stateJson) { + state.restoreState(stateJson); } - const segmentationGraph = new GrapheneGraphSource( - info, - credentialsProvider, - volume, - state, - ); + const segmentationGraph = new GrapheneGraphSource(info, volume, state); const { modelSpace } = info; const subsources: DataSubsourceEntry[] = [ { @@ -634,18 +624,19 @@ async function getVolumeDataSource( }, ]; if (info.segmentPropertyMap !== undefined) { - const mapUrl = resolvePath(url, info.segmentPropertyMap); - const metadata = await getJsonMetadata( - options.chunkManager, - credentialsProvider, - mapUrl, + const mapUrl = kvstoreEnsureDirectoryPipelineUrl( + sharedKvStoreContext.kvStoreContext.resolveRelativePath( + url, + info.segmentPropertyMap, + ), ); - const segmentPropertyMap = getSegmentPropertyMap( - options.chunkManager, - credentialsProvider, - metadata, + const metadata = await getJsonMetadata( + sharedKvStoreContext, mapUrl, + /*required=*/ true, + options, ); + const segmentPropertyMap = getSegmentPropertyMap(metadata); subsources.push({ id: "properties", default: true, @@ -654,11 +645,16 @@ async function getVolumeDataSource( } if (info.mesh !== undefined) { const { source: meshSource, transform } = await getMeshSource( - options.chunkManager, - credentialsProvider, + sharedKvStoreContext, info.app!.meshingUrl, - resolvePath(info.dataUrl, info.mesh), + kvstoreEnsureDirectoryPipelineUrl( + sharedKvStoreContext.kvStoreContext.resolveRelativePath( + info.dataUrl, + info.mesh, + ), + ), info.graph.nBitsForLayerId, + options, ); const subsourceToModelSubspaceTransform = getSubsourceToModelSubspaceTransform(info); @@ -681,56 +677,56 @@ async function getVolumeDataSource( }; } -export class GrapheneDataSource extends PrecomputedDataSource { - get description() { - return "Graphene file-backed data source"; +// Note: Graphene is not really a kvstore-based data source, since it relies on +// making arbitrary HTTP requests rather than just kvstore. It fails if the +// provided kvstore does not inherit from HttpKvStore. +export class GrapheneDataSource implements KvStoreBasedDataSourceProvider { + get scheme() { + return "graphene"; } - - get(options: GetDataSourceOptions): Promise { - const { url: providerUrl, parameters } = parseProviderUrl( - options.providerUrl, - ); - return options.chunkManager.memoize.getUncounted( - { type: "graphene:get", providerUrl, parameters }, - async (): Promise => { - const { url, credentialsProvider } = parseSpecialUrl( - providerUrl, - options.credentialsManager, + get description() { + return "Graphene data source"; + } + + get( + options: GetKvStoreBasedDataSourceOptions, + ): Promise { + ensureEmptyUrlSuffix(options.url); + const url = kvstoreEnsureDirectoryPipelineUrl(options.kvStoreUrl); + return options.registry.chunkManager.memoize.getAsync( + { type: "graphene:get", url }, + options, + async (progressOptions) => { + const metadata = await getJsonMetadata( + options.registry.sharedKvStoreContext, + url, + /*required=*/ true, + progressOptions, ); - let metadata: any; - try { - metadata = await getJsonMetadata( - options.chunkManager, - credentialsProvider, - url, - ); - } catch (e) { - if (isNotFoundError(e)) { - if (parameters.type === "mesh") { - console.log("does this happen?"); - } - } - throw e; - } verifyObject(metadata); const redirect = verifyOptionalObjectProperty( metadata, "redirect", verifyString, ); + const canonicalUrl = `${options.url.scheme}://${url}`; if (redirect !== undefined) { - throw new RedirectError(redirect); + return { canonicalUrl, targetUrl: redirect }; } const t = verifyOptionalObjectProperty(metadata, "@type", verifyString); switch (t) { case "neuroglancer_multiscale_volume": - case undefined: - return await getVolumeDataSource( - options, - credentialsProvider, + case undefined: { + const dataSource = await getVolumeDataSource( + options.registry.sharedKvStoreContext, url, metadata, + progressOptions, + options.state, ); + dataSource.canonicalUrl = canonicalUrl; + return dataSource; + } default: throw new Error(`Invalid type: ${JSON.stringify(t)}`); } @@ -1544,26 +1540,13 @@ class GraphConnection extends SegmentationGraphSourceConnection { } } -async function parseGrapheneError(e: HttpError) { - if (e.response) { - let msg: string; - if (e.response.headers.get("content-type") === "application/json") { - msg = (await e.response.json()).message; - } else { - msg = await e.response.text(); - } - return msg; - } - return undefined; -} - -async function withErrorMessageHTTP( - promise: Promise, +async function withErrorMessageHTTP( + promise: Promise, options: { initialMessage?: string; errorPrefix: string; }, -): Promise { +): Promise { let status: StatusMessage | undefined = undefined; let dispose = () => {}; if (options.initialMessage) { @@ -1595,10 +1578,17 @@ async function withErrorMessageHTTP( export const GRAPH_SERVER_NOT_SPECIFIED = Symbol("Graph Server Not Specified."); class GrapheneGraphServerInterface { - constructor( - private url: string, - private credentialsProvider: SpecialProtocolCredentialsProvider, - ) {} + private fetchOkImpl: FetchOk; + private url: string; + constructor(sharedKvStoreContext: SharedKvStoreContext, url: string) { + const { store, path } = sharedKvStoreContext.kvStoreContext.getKvStore(url); + if (store instanceof HttpKvStore) { + this.fetchOkImpl = store.fetchOkImpl; + this.url = store.baseUrl + path; + } else { + throw new Error(`Non-HTTP protocol not supported: ${url}`); + } + } async getRoot(segment: Uint64, timestamp = "") { const timestampEpoch = new Date(timestamp).valueOf() / 1000; @@ -1607,18 +1597,13 @@ class GrapheneGraphServerInterface { Number.isNaN(timestampEpoch) ? "" : `×tamp=${timestampEpoch}` }`; - const promise = cancellableFetchSpecialOk( - this.credentialsProvider, - url, - {}, - responseIdentity, + const jsonResp = await withErrorMessageHTTP( + this.fetchOkImpl(url).then((response) => response.json()), + { + initialMessage: `Retrieving root for segment ${segment}`, + errorPrefix: "Could not fetch root: ", + }, ); - - const response = await withErrorMessageHTTP(promise, { - initialMessage: `Retrieving root for segment ${segment}`, - errorPrefix: "Could not fetch root: ", - }); - const jsonResp = await response.json(); return Uint64.parseString(jsonResp.root_id); } @@ -1632,24 +1617,19 @@ class GrapheneGraphServerInterface { return Promise.reject(GRAPH_SERVER_NOT_SPECIFIED); } - const promise = cancellableFetchSpecialOk( - this.credentialsProvider, - `${url}/merge?int64_as_str=1`, - { - method: "POST", - body: JSON.stringify([ - [ - String(first.segmentId), - ...first.position.map((val, i) => val * annotationToNanometers[i]), - ], - [ - String(second.segmentId), - ...second.position.map((val, i) => val * annotationToNanometers[i]), - ], - ]), - }, - responseIdentity, - ); + const promise = this.fetchOkImpl(`${url}/merge?int64_as_str=1`, { + method: "POST", + body: JSON.stringify([ + [ + String(first.segmentId), + ...first.position.map((val, i) => val * annotationToNanometers[i]), + ], + [ + String(second.segmentId), + ...second.position.map((val, i) => val * annotationToNanometers[i]), + ], + ]), + }); try { const response = await promise; @@ -1674,24 +1654,19 @@ class GrapheneGraphServerInterface { return Promise.reject(GRAPH_SERVER_NOT_SPECIFIED); } - const promise = cancellableFetchSpecialOk( - this.credentialsProvider, - `${url}/split?int64_as_str=1`, - { - method: "POST", - body: JSON.stringify({ - sources: first.map((x) => [ - String(x.segmentId), - ...x.position.map((val, i) => val * annotationToNanometers[i]), - ]), - sinks: second.map((x) => [ - String(x.segmentId), - ...x.position.map((val, i) => val * annotationToNanometers[i]), - ]), - }), - }, - responseIdentity, - ); + const promise = this.fetchOkImpl(`${url}/split?int64_as_str=1`, { + method: "POST", + body: JSON.stringify({ + sources: first.map((x) => [ + String(x.segmentId), + ...x.position.map((val, i) => val * annotationToNanometers[i]), + ]), + sinks: second.map((x) => [ + String(x.segmentId), + ...x.position.map((val, i) => val * annotationToNanometers[i]), + ]), + }), + }); const response = await withErrorMessageHTTP(promise, { initialMessage: `Splitting ${first.length} sources from ${second.length} sinks`, @@ -1708,23 +1683,20 @@ class GrapheneGraphServerInterface { async filterLatestRoots(segments: Uint64[]): Promise { const url = `${this.url}/is_latest_roots`; - const promise = cancellableFetchSpecialOk( - this.credentialsProvider, - url, + const promise = this.fetchOkImpl(url, { + method: "POST", + body: JSON.stringify({ + node_ids: segments.map((x) => x.toJSON()), + }), + }); + + const jsonResp = await withErrorMessageHTTP( + promise.then((response) => response.json()), { - method: "POST", - body: JSON.stringify({ - node_ids: segments.map((x) => x.toJSON()), - }), + errorPrefix: "Could not check latest: ", }, - responseIdentity, ); - const response = await withErrorMessageHTTP(promise, { - errorPrefix: "Could not check latest: ", - }); - const jsonResp = await response.json(); - const res: Uint64[] = []; for (const [i, isLatest] of jsonResp.is_latest.entries()) { if (isLatest) { @@ -1741,14 +1713,13 @@ class GrapheneGraphSource extends SegmentationGraphSource { constructor( public info: GrapheneMultiscaleVolumeInfo, - credentialsProvider: SpecialProtocolCredentialsProvider, private chunkSource: GrapheneMultiscaleVolumeChunkSource, public state: GrapheneState, ) { super(); this.graphServer = new GrapheneGraphServerInterface( + chunkSource.sharedKvStoreContext, info.app!.segmentationUrl, - credentialsProvider, ); } @@ -1842,14 +1813,12 @@ class ChunkedGraphChunkSource extends SliceViewChunkSource implements ChunkedGraphChunkSourceInterface { - spec: ChunkedGraphChunkSpecification; - OPTIONS: { spec: ChunkedGraphChunkSpecification }; + declare spec: ChunkedGraphChunkSpecification; + declare OPTIONS: { spec: ChunkedGraphChunkSpecification }; } class GrapheneChunkedGraphChunkSource extends WithParameters( - WithCredentialsProvider()( - ChunkedGraphChunkSource, - ), + WithSharedKvStoreContext(ChunkedGraphChunkSource), ChunkedGraphSourceParameters, ) {} diff --git a/src/datasource/graphene/register_default.ts b/src/datasource/graphene/register_default.ts index e256a146fb..a0532a80b6 100644 --- a/src/datasource/graphene/register_default.ts +++ b/src/datasource/graphene/register_default.ts @@ -16,5 +16,8 @@ import { registerProvider } from "#src/datasource/default_provider.js"; import { GrapheneDataSource } from "#src/datasource/graphene/frontend.js"; +import { KvStoreBasedDataSourceLegacyUrlAdapter } from "#src/datasource/index.js"; -registerProvider("graphene", () => new GrapheneDataSource()); +registerProvider( + new KvStoreBasedDataSourceLegacyUrlAdapter(new GrapheneDataSource()), +); diff --git a/src/datasource/index.ts b/src/datasource/index.ts index e1cc361c05..98c048c728 100644 --- a/src/datasource/index.ts +++ b/src/datasource/index.ts @@ -22,12 +22,21 @@ import type { CoordinateSpaceTransform, CoordinateTransformSpecification, } from "#src/coordinate_transform.js"; +import type { SharedCredentialsManager } from "#src/credentials_provider/shared.js"; +import { getKvStoreCompletions } from "#src/datasource/kvstore_completions.js"; +import type { LocalDataSource } from "#src/datasource/local.js"; import { - emptyValidCoordinateSpace, - makeCoordinateSpace, - makeIdentityTransform, -} from "#src/coordinate_transform.js"; -import type { CredentialsManager } from "#src/credentials_provider/index.js"; + AutoDetectRegistry, + autoDetectFormat, +} from "#src/kvstore/auto_detect.js"; +import type { SharedKvStoreContext } from "#src/kvstore/frontend.js"; +import type { UrlWithParsedScheme } from "#src/kvstore/url.js"; +import { + extractQueryAndFragment, + finalPipelineUrlComponent, + parsePipelineUrlComponent, + splitPipelineUrl, +} from "#src/kvstore/url.js"; import type { MeshSource, MultiscaleMeshSource } from "#src/mesh/frontend.js"; import type { SegmentPropertyMap } from "#src/segmentation_display_state/property_map.js"; import type { SegmentationGraphSource } from "#src/segmentation_graph/source.js"; @@ -35,8 +44,6 @@ import type { SingleMeshSource } from "#src/single_mesh/frontend.js"; import type { SkeletonSource } from "#src/skeleton/frontend.js"; import type { MultiscaleVolumeChunkSource } from "#src/sliceview/volume/frontend.js"; import type { WatchableValueInterface } from "#src/trackable_value.js"; -import type { CancellationToken } from "#src/util/cancellation.js"; -import { uncancelableToken } from "#src/util/cancellation.js"; import type { BasicCompletionResult, CompletionWithDescription, @@ -45,19 +52,12 @@ import { applyCompletionOffset, getPrefixMatchesWithDescriptions, } from "#src/util/completion.js"; -import type { Owned } from "#src/util/disposable.js"; import { RefCounted } from "#src/util/disposable.js"; -import { createIdentity } from "#src/util/matrix.js"; +import { type ProgressOptions } from "#src/util/progress_listener.js"; import type { Trackable } from "#src/util/trackable.js"; export type CompletionResult = BasicCompletionResult; -export class RedirectError extends Error { - constructor(public redirectTarget: string) { - super(`Redirected to: ${redirectTarget}`); - } -} - /** * Returns the length of the prefix of path that corresponds to the "group", according to the * specified separator. @@ -95,9 +95,7 @@ export function suggestLayerNameBasedOnSeparator( return path.substring(groupIndex); } -export interface GetDataSourceOptionsBase { - chunkManager: ChunkManager; - cancellationToken?: CancellationToken; +export interface GetDataSourceOptionsBase extends Partial { url: string; transform: CoordinateTransformSpecification | undefined; globalCoordinateSpace: WatchableValueInterface; @@ -105,11 +103,10 @@ export interface GetDataSourceOptionsBase { } export interface GetDataSourceOptions extends GetDataSourceOptionsBase { - registry: DataSourceProviderRegistry; + registry: DataSourceRegistry; providerUrl: string; - cancellationToken: CancellationToken; - providerProtocol: string; - credentialsManager: CredentialsManager; + signal: AbortSignal; + providerScheme: string; } export interface ConvertLegacyUrlOptionsBase { @@ -118,24 +115,9 @@ export interface ConvertLegacyUrlOptionsBase { } export interface ConvertLegacyUrlOptions extends ConvertLegacyUrlOptionsBase { - registry: DataSourceProviderRegistry; - providerUrl: string; - providerProtocol: string; -} - -export interface NormalizeUrlOptionsBase { - url: string; -} - -export interface NormalizeUrlOptions extends NormalizeUrlOptionsBase { - registry: DataSourceProviderRegistry; + registry: DataSourceRegistry; providerUrl: string; - providerProtocol: string; -} - -export enum LocalDataSource { - annotations = 0, - equivalences = 1, + providerScheme: string; } export interface DataSubsource { @@ -149,17 +131,14 @@ export interface DataSubsource { segmentationGraph?: SegmentationGraphSource; } -export interface CompleteUrlOptionsBase { +export interface CompleteUrlOptionsBase extends Partial { url: string; - cancellationToken?: CancellationToken; - chunkManager: ChunkManager; } export interface CompleteUrlOptions extends CompleteUrlOptionsBase { - registry: DataSourceProviderRegistry; + registry: DataSourceRegistry; providerUrl: string; - cancellationToken: CancellationToken; - credentialsManager: CredentialsManager; + signal: AbortSignal; } export interface DataSubsourceEntry { @@ -198,20 +177,23 @@ export interface DataSource { modelTransform: CoordinateSpaceTransform; canChangeModelSpaceRank?: boolean; state?: Trackable; + canonicalUrl?: string; } -// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging -export interface DataSourceProvider { - /** - * Returns a suggested layer name for the given volume source. - */ - suggestLayerName?(path: string): string; +export interface DataSourceRedirect { + // Canonical URL of the source. + canonicalUrl?: string; - /** - * Returns the length of the prefix of path that is its 'group'. This is used for suggesting a - * default URL for adding a new layer. - */ - findSourceGroup?(path: string): number; + // Target URL. + targetUrl: string; +} + +export type DataSourceLookupResult = DataSource | DataSourceRedirect; + +export interface DataSourceWithRedirectInfo extends DataSource { + // Canonical URL prior to any redirects. + originalCanonicalUrl?: string; + redirectLog: Set; } export interface DataSubsourceSpecification { @@ -224,6 +206,9 @@ export interface DataSourceSpecification { enableDefaultSubsources: boolean; subsources: Map; state?: any; + + // Indicates that the spec was set manually in the UI. + setManually?: boolean; } export function makeEmptyDataSourceSpecification(): DataSourceSpecification { @@ -235,220 +220,234 @@ export function makeEmptyDataSourceSpecification(): DataSourceSpecification { }; } -// eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging -export abstract class DataSourceProvider extends RefCounted { - abstract description?: string; +export interface DataSourceProvider { + scheme: string; + description?: string; + // Exclude from completion list. + hidden?: boolean; - abstract get(options: GetDataSourceOptions): Promise; + get(options: GetDataSourceOptions): Promise; - normalizeUrl(options: NormalizeUrlOptions): string { - return options.url; - } + convertLegacyUrl?: (options: ConvertLegacyUrlOptions) => string; - convertLegacyUrl(options: ConvertLegacyUrlOptions): string { - return options.url; - } + completeUrl?: (options: CompleteUrlOptions) => Promise; +} - async completeUrl(options: CompleteUrlOptions): Promise { - options; - throw null; - } +export interface KvStoreBasedDataSourceProvider { + scheme: string; + description?: string; + singleFile?: boolean; + expectsDirectory?: boolean; + get( + options: GetKvStoreBasedDataSourceOptions, + ): Promise; + completeUrl?: ( + options: GetKvStoreBasedDataSourceOptions, + ) => Promise; } -export const localAnnotationsUrl = "local://annotations"; -export const localEquivalencesUrl = "local://equivalences"; +export interface GetKvStoreBasedDataSourceOptions + extends Partial { + registry: DataSourceRegistry; + kvStoreUrl: string; + url: UrlWithParsedScheme; + state?: any; +} -class LocalDataSourceProvider extends DataSourceProvider { - get description() { - return "Local in-memory"; - } +const schemePattern = /^(?:([a-zA-Z][a-zA-Z0-9-+_]*):\/\/)?(.*)$/; - async get(options: GetDataSourceOptions): Promise { - switch (options.url) { - case localAnnotationsUrl: { - const { transform } = options; - let modelTransform: CoordinateSpaceTransform; - if (transform === undefined) { - const baseSpace = options.globalCoordinateSpace.value; - const { rank, names, scales, units } = baseSpace; - const inputSpace = makeCoordinateSpace({ - rank, - scales, - units, - names: names.map((_, i) => `${i}`), - }); - const outputSpace = makeCoordinateSpace({ - rank, - scales, - units, - names, - }); - modelTransform = { - rank, - sourceRank: rank, - inputSpace, - outputSpace, - transform: createIdentity(Float64Array, rank + 1), - }; - } else { - modelTransform = makeIdentityTransform(emptyValidCoordinateSpace); - } - return { - modelTransform, - canChangeModelSpaceRank: true, - subsources: [ - { - id: "default", - default: true, - subsource: { - local: LocalDataSource.annotations, - }, - }, - ], - }; - } - case localEquivalencesUrl: { - return { - modelTransform: makeIdentityTransform(emptyValidCoordinateSpace), - canChangeModelSpaceRank: false, - subsources: [ - { - id: "default", - default: true, - subsource: { - local: LocalDataSource.equivalences, - }, - }, - ], - }; - } - } - throw new Error("Invalid local data source URL"); +export class DataSourceRegistry extends RefCounted { + get credentialsManager(): SharedCredentialsManager { + return this.sharedKvStoreContext.credentialsManager; } - async completeUrl(options: CompleteUrlOptions) { - return { - offset: 0, - completions: getPrefixMatchesWithDescriptions( - options.providerUrl, - [ - { - value: "annotations", - description: "Annotations stored in the JSON state", - }, - { - value: "equivalences", - description: - "Segmentation equivalence graph stored in the JSON state", - }, - ], - (x) => x.value, - (x) => x.description, - ), - }; + get chunkManager(): ChunkManager { + return this.sharedKvStoreContext.chunkManager; } -} - -const protocolPattern = /^(?:([a-zA-Z][a-zA-Z0-9-+_]*):\/\/)?(.*)$/; -export class DataSourceProviderRegistry extends RefCounted { - constructor(public credentialsManager: CredentialsManager) { + constructor(public sharedKvStoreContext: SharedKvStoreContext) { super(); } - dataSources = new Map>([ - ["local", new LocalDataSourceProvider()], - ]); + dataSources = new Map(); + kvStoreBasedDataSources = new Map(); + autoDetectRegistry = new AutoDetectRegistry(); - register(name: string, dataSource: Owned) { - this.dataSources.set(name, this.registerDisposer(dataSource)); + register(provider: DataSourceProvider) { + this.dataSources.set(provider.scheme, provider); + } + registerKvStoreBasedProvider(provider: KvStoreBasedDataSourceProvider) { + this.kvStoreBasedDataSources.set(provider.scheme, provider); } getProvider(url: string): [DataSourceProvider, string, string] { - const m = url.match(protocolPattern); + const m = url.match(schemePattern); if (m === null || m[1] === undefined) { throw new Error( - `Data source URL must have the form "://".`, + `Data source URL must have the form "://".`, ); } - const [, providerProtocol, providerUrl] = m; - const factory = this.dataSources.get(providerProtocol); + const [, providerScheme, providerUrl] = m; + const factory = this.dataSources.get(providerScheme); if (factory === undefined) { throw new Error( - `Unsupported data source: ${JSON.stringify(providerProtocol)}.`, + `Unsupported data source: ${JSON.stringify(providerScheme)}.`, ); } - return [factory, providerUrl, providerProtocol]; + return [factory, providerUrl, providerScheme]; } - async get(options: GetDataSourceOptionsBase): Promise { - const redirectLog = new Set(); - const { cancellationToken = uncancelableToken } = options; - let url: string = options.url; + private async autoDetectFormat(options: GetDataSourceOptionsBase) { + const { matches, url } = await autoDetectFormat({ + url: options.url, + kvStoreContext: this.sharedKvStoreContext.kvStoreContext, + signal: options.signal, + progressListener: options.progressListener, + autoDetectDirectory: () => this.autoDetectRegistry.directorySpec, + autoDetectFile: () => this.autoDetectRegistry.fileSpec, + }); + if (matches.length !== 1) { + let message: string; + if (matches.length === 0) { + message = "no format detected"; + } else { + message = `multiple formats detected: ${JSON.stringify(matches)}`; + } + throw new Error( + `Failed to auto-detect data source for ${JSON.stringify(options.url)}: ${message}`, + ); + } + return `${url}|${matches[0].suffix}`; + } + + private async resolveKvStoreBasedDataSource( + options: GetDataSourceOptionsBase, + ): Promise { while (true) { - const [provider, providerUrl, providerProtocol] = this.getProvider( - options.url, + const finalPart = parsePipelineUrlComponent( + finalPipelineUrlComponent(options.url), ); - redirectLog.add(options.url); - try { - return provider.get({ + const dataSourceProvider = this.kvStoreBasedDataSources.get( + finalPart.scheme, + ); + if (dataSourceProvider === undefined) { + // Attempt to auto-detect format. + const newUrl = await this.autoDetectFormat(options); + options = { ...options, url: newUrl }; + continue; + } + return await dataSourceProvider.get({ + registry: this, + url: finalPart, + kvStoreUrl: options.url.substring( + 0, + options.url.length - finalPart.url.length - 1, + ), + signal: options.signal, + progressListener: options.progressListener, + state: options.state, + }); + } + } + + private async resolvePipeline( + options: GetDataSourceOptionsBase, + ): Promise { + const pipelineParts = splitPipelineUrl(options.url); + + const basePart = pipelineParts[0]; + const baseScheme = basePart.scheme; + + // Check kvstore providers + { + const provider = + this.sharedKvStoreContext.kvStoreContext.baseKvStoreProviders.get( + baseScheme, + ); + if (provider !== undefined) { + return await this.resolveKvStoreBasedDataSource(options); + } + } + + if (pipelineParts.length !== 1) { + throw new Error(`${baseScheme}: scheme does not support | URL pipelines`); + } + + const suffix = basePart.suffix ?? ""; + if (!suffix.startsWith("//")) { + throw new Error(`${baseScheme}: URLs must start with "${baseScheme}://"`); + } + + const providerUrl = suffix.substring(2); + + // Check non-kvstore-based providers + { + const provider = this.dataSources.get(baseScheme); + if (provider !== undefined) { + return await provider.get({ ...options, - url, - providerProtocol, + url: pipelineParts[0].url, + providerScheme: baseScheme, providerUrl, registry: this, - cancellationToken, - credentialsManager: this.credentialsManager, + signal: options.signal ?? new AbortController().signal, }); - } catch (e) { - if (e instanceof RedirectError) { - const redirect = e.redirectTarget; - if (redirectLog.has(redirect)) { - throw Error( - `Layer source redirection contains loop: ${JSON.stringify( - Array.from(redirectLog), - )}`, - ); - } - if (redirectLog.size >= 10) { - throw Error( - `Too many layer source redirections: ${JSON.stringify( - Array.from(redirectLog), - )}`, - ); - } - url = redirect; - continue; - } - throw e; } } + + throw new Error(`Unsupported scheme: ${baseScheme}:`); } - convertLegacyUrl(options: ConvertLegacyUrlOptionsBase): string { - try { - const [provider, providerUrl, providerProtocol] = this.getProvider( - options.url, - ); - return provider.convertLegacyUrl({ - ...options, - providerUrl, - providerProtocol, - registry: this, - }); - } catch { - return options.url; + async get( + options: GetDataSourceOptionsBase, + ): Promise { + const redirectLog = new Set(); + let url: string = options.url; + url = url.trim(); + // Trim any trailing "|" characters. + url = url.replace(/\|+$/, ""); + let originalCanonicalUrl: string | undefined; + while (true) { + redirectLog.add(url); + const dataSource = await this.resolvePipeline({ ...options, url }); + if (originalCanonicalUrl === undefined) { + originalCanonicalUrl = dataSource.canonicalUrl; + } + if ("targetUrl" in dataSource) { + const { targetUrl } = dataSource; + if (redirectLog.has(targetUrl)) { + throw Error( + `Layer source redirection contains loop: ${JSON.stringify([ + ...redirectLog, + targetUrl, + ])}`, + ); + } + if (redirectLog.size >= 10) { + throw Error( + `Too many layer source redirections: ${JSON.stringify([ + ...redirectLog, + targetUrl, + ])}`, + ); + } + url = targetUrl; + continue; + } + return { ...dataSource, redirectLog, originalCanonicalUrl }; } } - normalizeUrl(options: NormalizeUrlOptionsBase): string { + // Converts legacy precomputed mesh and skeleton datasource URLs. + convertLegacyUrl(options: ConvertLegacyUrlOptionsBase): string { try { - const [provider, providerUrl, providerProtocol] = this.getProvider( + const [provider, providerUrl, providerScheme] = this.getProvider( options.url, ); - return provider.normalizeUrl({ + if (provider.convertLegacyUrl === undefined) return options.url; + return provider.convertLegacyUrl({ ...options, providerUrl, - providerProtocol, + providerScheme: providerScheme, registry: this, }); } catch { @@ -459,52 +458,209 @@ export class DataSourceProviderRegistry extends RefCounted { async completeUrl( options: CompleteUrlOptionsBase, ): Promise { - // Check if url matches a protocol. Note that protocolPattern always matches. - const { url, cancellationToken = uncancelableToken } = options; - const protocolMatch = url.match(protocolPattern)!; - const protocol = protocolMatch[1]; - if (protocol === undefined) { - return Promise.resolve({ - offset: 0, + // Check if url matches a scheme. Note that schemePattern always matches. + const { signal } = options; + + const { url } = options; + + const finalComponent = finalPipelineUrlComponent(url); + const parsedFinalComponent = parsePipelineUrlComponent(finalComponent); + const { scheme } = parsedFinalComponent; + + // Check if we need to complete a scheme. + if ( + finalComponent === url && + !(parsedFinalComponent.suffix ?? "").startsWith("//") + ) { + const providers: { + scheme: string; + description?: string; + }[] = []; + const add = ( + iterable: Iterable, + predicate?: (provider: Provider) => boolean, + ) => { + for (const provider of iterable) { + if (predicate?.(provider) === false) continue; + providers.push(provider); + } + }; + + if (finalComponent === url) { + add( + this.sharedKvStoreContext.kvStoreContext.baseKvStoreProviders.values(), + ); + add(this.dataSources.values(), (provider) => provider.hidden !== true); + } else { + add(this.kvStoreBasedDataSources.values()); + add( + this.sharedKvStoreContext.kvStoreContext.kvStoreAdapterProviders.values(), + ); + } + + const schemeSuffix = finalComponent === url ? "//" : ""; + return { + offset: url.length - finalComponent.length, completions: getPrefixMatchesWithDescriptions( - url, - this.dataSources, - ([name]) => `${name}://`, - ([, factory]) => factory.description, + scheme, + providers, + ({ scheme }) => `${scheme}:${schemeSuffix}`, + ({ description }) => description, ), - }); + }; } - const factory = this.dataSources.get(protocol); - if (factory !== undefined) { - const completions = await factory.completeUrl({ - registry: this, - url, - providerUrl: protocolMatch[2], - chunkManager: options.chunkManager, - cancellationToken, - credentialsManager: this.credentialsManager, + + if (parsedFinalComponent.suffix === undefined) { + const prevPipelineUrl = options.url.substring( + 0, + options.url.length - finalComponent.length - 1, + ); + const { matches } = await autoDetectFormat({ + url: prevPipelineUrl, + kvStoreContext: this.sharedKvStoreContext.kvStoreContext, + signal: options.signal, + progressListener: options.progressListener, + autoDetectDirectory: () => this.autoDetectRegistry.directorySpec, + autoDetectFile: () => this.autoDetectRegistry.fileSpec, }); - return applyCompletionOffset(protocol.length + 3, completions); + if (matches.length === 0) { + throw new Error( + `Failed to auto-detect data source for ${JSON.stringify(prevPipelineUrl)}`, + ); + } + return { + offset: url.length - finalComponent.length, + completions: getPrefixMatchesWithDescriptions( + parsedFinalComponent.scheme, + matches, + ({ suffix }) => suffix, + ({ description }) => description, + ), + }; + } + + if (finalComponent === url) { + // Single component pipeline. + const provider = this.dataSources.get(scheme); + if (provider !== undefined) { + // Non-kvstore-based protocol. + if (provider.completeUrl === undefined) throw null; + const completions = await provider.completeUrl({ + registry: this, + url: options.url, + providerUrl: parsedFinalComponent.suffix!.substring(2), + signal: signal ?? new AbortController().signal, + progressListener: options.progressListener, + }); + return applyCompletionOffset(scheme.length + 3, completions); + } + } + + { + const provider = this.kvStoreBasedDataSources.get(scheme); + if (provider !== undefined) { + if (provider.completeUrl === undefined) throw null; + const completions = await provider.completeUrl({ + registry: this, + signal: signal ?? new AbortController().signal, + progressListener: options.progressListener, + kvStoreUrl: url.substring(0, url.length - finalComponent.length - 1), + url: parsedFinalComponent, + }); + return applyCompletionOffset( + url.length - + finalComponent.length + + parsedFinalComponent.scheme.length + + 1, + completions, + ); + } } - throw null; + + return await getKvStoreCompletions(this.sharedKvStoreContext, { + url, + signal, + progressListener: options.progressListener, + autoDetectDirectory: () => this.autoDetectRegistry.directorySpec, + }); } - suggestLayerName(url: string) { - let [dataSource, path] = this.getProvider(url); - if (path.endsWith("/")) { - path = path.substring(0, path.length - 1); + suggestLayerName(url: string): string | undefined { + const parts = splitPipelineUrl(url); + for (let i = parts.length - 1; i >= 0; --i) { + let { suffix } = parts[i]; + if (!suffix) continue; + suffix = suffix.replace(/^\/+/, "").replace(/\/+$/, ""); + if (!suffix) continue; + return suggestLayerNameBasedOnSeparator(suffix); } - const suggestor = dataSource.suggestLayerName; - if (suggestor !== undefined) { - return suggestor(path); + return undefined; + } +} + +export class KvStoreBasedDataSourceLegacyUrlAdapter + implements DataSourceProvider +{ + constructor( + public base: KvStoreBasedDataSourceProvider, + public scheme = base.scheme, + ) {} + + get hidden() { + return true; + } + + get description() { + return this.base.description; + } + + private parseProviderUrl(url: string) { + if (url.includes("|")) { + throw new Error("Only a single pipeline component supported"); } - return suggestLayerNameBasedOnSeparator(path); + const { base, queryAndFragment } = extractQueryAndFragment(url); + return { + kvStoreUrl: base, + queryAndFragment, + url: parsePipelineUrlComponent(`${this.base.scheme}:${queryAndFragment}`), + }; + } + + get(options: GetDataSourceOptions): Promise { + const { kvStoreUrl, url } = this.parseProviderUrl(options.providerUrl); + return this.base.get({ + registry: options.registry, + url, + kvStoreUrl, + state: options.state, + signal: options.signal, + progressListener: options.progressListener, + }); } - findSourceGroup(url: string) { - const [dataSource, path, dataSourceName] = this.getProvider(url); - const helper = - dataSource.findSourceGroup || findSourceGroupBasedOnSeparator; - return helper(path) + dataSourceName.length + 3; + async completeUrl(options: CompleteUrlOptions): Promise { + const { kvStoreUrl, url, queryAndFragment } = this.parseProviderUrl( + options.providerUrl, + ); + if (queryAndFragment === "") { + return await getKvStoreCompletions( + options.registry.sharedKvStoreContext, + { + url: options.providerUrl, + signal: options.signal, + progressListener: options.progressListener, + singlePipelineComponent: true, + directoryOnly: this.base.expectsDirectory, + }, + ); + } + if (!this.base.completeUrl) throw null; + return this.base.completeUrl({ + registry: options.registry, + signal: options.signal, + progressListener: options.progressListener, + kvStoreUrl, + url, + }); } } diff --git a/src/datasource/kvstore_completions.ts b/src/datasource/kvstore_completions.ts new file mode 100644 index 0000000000..05a8f80ab2 --- /dev/null +++ b/src/datasource/kvstore_completions.ts @@ -0,0 +1,141 @@ +/** + * @license + * Copyright 2024 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { CompletionResult } from "#src/datasource/index.js"; +import type { AutoDetectDirectorySpec } from "#src/kvstore/auto_detect.js"; +import type { SharedKvStoreContext } from "#src/kvstore/frontend.js"; +import { listKvStore } from "#src/kvstore/index.js"; +import { + encodePathForUrl, + finalPipelineUrlComponent, +} from "#src/kvstore/url.js"; +import type { CompletionWithDescription } from "#src/util/completion.js"; +import type { ProgressListener } from "#src/util/progress_listener.js"; + +export async function getKvStoreCompletions( + sharedKvStoreContext: SharedKvStoreContext, + options: { + url: string; + signal?: AbortSignal; + progressListener?: ProgressListener; + directoryOnly?: boolean; + autoDetectDirectory?: () => AutoDetectDirectorySpec; + singlePipelineComponent?: boolean; + }, +): Promise { + const { url, autoDetectDirectory } = options; + const kvStore = sharedKvStoreContext.kvStoreContext.getKvStore(url); + if (kvStore.store.getUrl(kvStore.path) !== url) { + // URL is valid but lacks final "/" terminator, skip completion. + // + // This avoids attempting to access e.g. `gs://bucke` as the user is typing + // `gs://bucket/`. + throw null; + } + const results = await listKvStore(kvStore.store, kvStore.path, { + signal: options.signal, + progressListener: options.progressListener, + responseKeys: "url", + }); + + const finalComponent = finalPipelineUrlComponent(url); + + // Infallible pattern + const [, directoryPath, namePrefix] = finalComponent.match( + /^((?:[a-zA-Z][a-zA-Z0-9-+.]*:)(?:.*\/)?)([^/]*)$/, + )!; + const offset = url.length - namePrefix.length; + const matches: CompletionWithDescription[] = []; + const directoryOffset = + url.length - finalComponent.length + directoryPath.length; + for (const entry of results.directories) { + matches.push({ value: entry.substring(directoryOffset) + "/" }); + } + if (!options.directoryOnly) { + const matchSuffix = options.singlePipelineComponent === true ? "" : "|"; + for (const entry of results.entries) { + matches.push({ + value: entry.key.substring(directoryOffset) + matchSuffix, + }); + } + } + + let defaultCompletion: string | undefined; + + if (autoDetectDirectory !== undefined && namePrefix === "") { + const names = new Set(); + for (const entry of results.entries) { + names.add(entry.key.substring(directoryOffset)); + } + const pipelineMatches = await autoDetectDirectory().match({ + url, + fileNames: names, + signal: options.signal, + }); + for (const match of pipelineMatches) { + matches.push({ + value: `|${match.suffix}`, + description: match.description, + }); + } + if (pipelineMatches.length === 1) { + defaultCompletion = `|${pipelineMatches[0].suffix}`; + } + } + return { offset, completions: matches, defaultCompletion }; +} + +export async function getKvStorePathCompletions( + sharedKvStoreContext: SharedKvStoreContext, + options: { + baseUrl: string; + path: string; + signal?: AbortSignal; + progressListener?: ProgressListener; + directoryOnly?: boolean; + }, +): Promise { + const { baseUrl, path } = options; + const { store, path: basePath } = + sharedKvStoreContext.kvStoreContext.getKvStore(baseUrl); + if (!store.list) { + throw new Error("Listing not supported"); + } + + const fullPath = basePath + path; + + const fullOffset = Math.max(basePath.length, fullPath.lastIndexOf("/") + 1); + + const results = await store.list(fullPath, { + signal: options.signal, + progressListener: options.progressListener, + }); + + const matches: CompletionWithDescription[] = []; + for (const entry of results.directories) { + matches.push({ + value: encodePathForUrl(entry.substring(fullOffset) + "/"), + }); + } + if (!options.directoryOnly) { + for (const entry of results.entries) { + matches.push({ + value: encodePathForUrl(entry.key.substring(fullOffset)), + }); + } + } + return { offset: fullOffset - basePath.length, completions: matches }; +} diff --git a/src/datasource/local.ts b/src/datasource/local.ts new file mode 100644 index 0000000000..4df6dc0443 --- /dev/null +++ b/src/datasource/local.ts @@ -0,0 +1,132 @@ +/** + * @license + * Copyright 2016 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + emptyValidCoordinateSpace, + makeCoordinateSpace, + makeIdentityTransform, + type CoordinateSpaceTransform, +} from "#src/coordinate_transform.js"; +import type { + CompleteUrlOptions, + DataSource, + GetDataSourceOptions, + DataSourceProvider, +} from "#src/datasource/index.js"; +import { getPrefixMatchesWithDescriptions } from "#src/util/completion.js"; +import { createIdentity } from "#src/util/matrix.js"; + +export const localAnnotationsUrl = "local://annotations"; +export const localEquivalencesUrl = "local://equivalences"; + +export enum LocalDataSource { + annotations = 0, + equivalences = 1, +} + +export class LocalDataSourceProvider implements DataSourceProvider { + get scheme() { + return "local"; + } + get description() { + return "Local in-memory"; + } + + async get(options: GetDataSourceOptions): Promise { + switch (options.url) { + case localAnnotationsUrl: { + const { transform } = options; + let modelTransform: CoordinateSpaceTransform; + if (transform === undefined) { + const baseSpace = options.globalCoordinateSpace.value; + const { rank, names, scales, units } = baseSpace; + const inputSpace = makeCoordinateSpace({ + rank, + scales, + units, + names: names.map((_, i) => `${i}`), + }); + const outputSpace = makeCoordinateSpace({ + rank, + scales, + units, + names, + }); + modelTransform = { + rank, + sourceRank: rank, + inputSpace, + outputSpace, + transform: createIdentity(Float64Array, rank + 1), + }; + } else { + modelTransform = makeIdentityTransform(emptyValidCoordinateSpace); + } + return { + modelTransform, + canChangeModelSpaceRank: true, + subsources: [ + { + id: "default", + default: true, + subsource: { + local: LocalDataSource.annotations, + }, + }, + ], + }; + } + case localEquivalencesUrl: { + return { + modelTransform: makeIdentityTransform(emptyValidCoordinateSpace), + canChangeModelSpaceRank: false, + subsources: [ + { + id: "default", + default: true, + subsource: { + local: LocalDataSource.equivalences, + }, + }, + ], + }; + } + } + throw new Error("Invalid local data source URL"); + } + + async completeUrl(options: CompleteUrlOptions) { + return { + offset: 0, + completions: getPrefixMatchesWithDescriptions( + options.providerUrl, + [ + { + value: "annotations", + description: "Annotations stored in the JSON state", + }, + { + value: "equivalences", + description: + "Segmentation equivalence graph stored in the JSON state", + }, + ], + (x) => x.value, + (x) => x.description, + ), + }; + } +} diff --git a/src/datasource/n5/async_computation.ts b/src/datasource/n5/async_computation.ts index df029623c4..db56b860ff 100644 --- a/src/datasource/n5/async_computation.ts +++ b/src/datasource/n5/async_computation.ts @@ -1,3 +1,2 @@ -import "#src/async_computation/decode_gzip.js"; import "#src/async_computation/decode_blosc.js"; import "#src/async_computation/decode_zstd.js"; diff --git a/src/datasource/n5/backend.ts b/src/datasource/n5/backend.ts index 4f51ce2c69..6e1a7fcb9d 100644 --- a/src/datasource/n5/backend.ts +++ b/src/datasource/n5/backend.ts @@ -15,31 +15,24 @@ */ import { decodeBlosc } from "#src/async_computation/decode_blosc_request.js"; -import { decodeGzip } from "#src/async_computation/decode_gzip_request.js"; import { decodeZstd } from "#src/async_computation/decode_zstd_request.js"; import { requestAsyncComputation } from "#src/async_computation/request.js"; import { WithParameters } from "#src/chunk_manager/backend.js"; -import { WithSharedCredentialsProviderCounterpart } from "#src/credentials_provider/shared_counterpart.js"; import { VolumeChunkEncoding, VolumeChunkSourceParameters, } from "#src/datasource/n5/base.js"; +import { WithSharedKvStoreContextCounterpart } from "#src/kvstore/backend.js"; import { decodeRawChunk } from "#src/sliceview/backend_chunk_decoders/raw.js"; import type { VolumeChunk } from "#src/sliceview/volume/backend.js"; import { VolumeChunkSource } from "#src/sliceview/volume/backend.js"; -import type { CancellationToken } from "#src/util/cancellation.js"; import { Endianness } from "#src/util/endian.js"; -import { - isNotFoundError, - responseArrayBuffer, -} from "#src/util/http_request.js"; -import type { SpecialProtocolCredentials } from "#src/util/special_protocol_request.js"; -import { cancellableFetchSpecialOk } from "#src/util/special_protocol_request.js"; +import { decodeGzip } from "#src/util/gzip.js"; import { registerSharedObject } from "#src/worker_rpc.js"; async function decodeChunk( chunk: VolumeChunk, - cancellationToken: CancellationToken, + signal: AbortSignal, response: ArrayBuffer, encoding: VolumeChunkEncoding, ) { @@ -61,18 +54,16 @@ async function decodeChunk( chunk.chunkDataSize = shape; let buffer = new Uint8Array(response, offset); switch (encoding) { + case VolumeChunkEncoding.ZLIB: + buffer = new Uint8Array(await decodeGzip(buffer, "deflate")); + break; case VolumeChunkEncoding.GZIP: - buffer = await requestAsyncComputation( - decodeGzip, - cancellationToken, - [buffer.buffer], - buffer, - ); + buffer = new Uint8Array(await decodeGzip(buffer, "gzip")); break; case VolumeChunkEncoding.BLOSC: buffer = await requestAsyncComputation( decodeBlosc, - cancellationToken, + signal, [buffer.buffer], buffer, ); @@ -80,7 +71,7 @@ async function decodeChunk( case VolumeChunkEncoding.ZSTD: buffer = await requestAsyncComputation( decodeZstd, - cancellationToken, + signal, [buffer.buffer], buffer, ); @@ -88,7 +79,7 @@ async function decodeChunk( } await decodeRawChunk( chunk, - cancellationToken, + signal, buffer.buffer, Endianness.BIG, buffer.byteOffset, @@ -98,35 +89,32 @@ async function decodeChunk( @registerSharedObject() export class PrecomputedVolumeChunkSource extends WithParameters( - WithSharedCredentialsProviderCounterpart()( - VolumeChunkSource, - ), + WithSharedKvStoreContextCounterpart(VolumeChunkSource), VolumeChunkSourceParameters, ) { - async download(chunk: VolumeChunk, cancellationToken: CancellationToken) { - const { parameters } = this; + private chunkKvStore = this.sharedKvStoreContext.kvStoreContext.getKvStore( + this.parameters.url, + ); + async download(chunk: VolumeChunk, signal: AbortSignal) { + const { parameters, chunkKvStore } = this; const { chunkGridPosition } = chunk; - let url = parameters.url; + let path = chunkKvStore.path; const rank = this.spec.rank; for (let i = 0; i < rank; ++i) { - url += `/${chunkGridPosition[i]}`; - } - try { - const response = await cancellableFetchSpecialOk( - this.credentialsProvider, - url, - {}, - responseArrayBuffer, - cancellationToken, - ); - await decodeChunk( - chunk, - cancellationToken, - response, - parameters.encoding, - ); - } catch (e) { - if (!isNotFoundError(e)) throw e; + if (i !== 0) { + path += "/"; + } + path += `${chunkGridPosition[i]}`; } + const response = await chunkKvStore.store.read(path, { + signal, + }); + if (response === undefined) return; + await decodeChunk( + chunk, + signal, + await response.response.arrayBuffer(), + parameters.encoding, + ); } } diff --git a/src/datasource/n5/base.ts b/src/datasource/n5/base.ts index ef471c8c16..5dc6a2f444 100644 --- a/src/datasource/n5/base.ts +++ b/src/datasource/n5/base.ts @@ -15,10 +15,11 @@ */ export enum VolumeChunkEncoding { - RAW = 0, - GZIP = 1, - BLOSC = 2, - ZSTD = 3, + RAW, + ZLIB, + GZIP, + BLOSC, + ZSTD, } export class VolumeChunkSourceParameters { diff --git a/src/datasource/n5/frontend.ts b/src/datasource/n5/frontend.ts index ed4299a528..3c9f5856c4 100644 --- a/src/datasource/n5/frontend.ts +++ b/src/datasource/n5/frontend.ts @@ -21,10 +21,11 @@ * * https://github.com/saalfeldlab/n5-viewer * https://github.com/bigdataviewer/bigdataviewer-core/blob/master/BDV%20N5%20format.md + * + * https://github.com/janelia-cellmap/schemas/blob/master/multiscale.md */ import { makeDataBoundsBoundingBoxAnnotationSet } from "#src/annotation/index.js"; -import type { ChunkManager } from "#src/chunk_manager/frontend.js"; import { WithParameters } from "#src/chunk_manager/frontend.js"; import type { CoordinateArray, @@ -34,17 +35,28 @@ import { makeCoordinateSpace, makeIdentityTransform, } from "#src/coordinate_transform.js"; -import { WithCredentialsProvider } from "#src/credentials_provider/chunk_source_frontend.js"; import type { - CompleteUrlOptions, DataSource, - GetDataSourceOptions, + GetKvStoreBasedDataSourceOptions, + KvStoreBasedDataSourceProvider, } from "#src/datasource/index.js"; -import { DataSourceProvider } from "#src/datasource/index.js"; +import { getKvStorePathCompletions } from "#src/datasource/kvstore_completions.js"; import { VolumeChunkEncoding, VolumeChunkSourceParameters, } from "#src/datasource/n5/base.js"; +import type { AutoDetectRegistry } from "#src/kvstore/auto_detect.js"; +import { simpleFilePresenceAutoDetectDirectorySpec } from "#src/kvstore/auto_detect.js"; +import { WithSharedKvStoreContext } from "#src/kvstore/chunk_source_frontend.js"; +import type { CompletionResult, KvStoreContext } from "#src/kvstore/context.js"; +import type { SharedKvStoreContext } from "#src/kvstore/frontend.js"; +import { + ensureNoQueryOrFragmentParameters, + ensurePathIsDirectory, + joinPath, + kvstoreEnsureDirectoryPipelineUrl, + pipelineUrlJoin, +} from "#src/kvstore/url.js"; import type { SliceViewSingleResolutionSource } from "#src/sliceview/frontend.js"; import type { VolumeSourceOptions } from "#src/sliceview/volume/base.js"; import { @@ -57,17 +69,11 @@ import { VolumeChunkSource, } from "#src/sliceview/volume/frontend.js"; import { transposeNestedArrays } from "#src/util/array.js"; -import type { Borrowed } from "#src/util/disposable.js"; -import { completeHttpPath } from "#src/util/http_path_completion.js"; -import { - isNotFoundError, - parseUrl, - responseJson, -} from "#src/util/http_request.js"; import { expectArray, parseArray, parseFixedLengthArray, + verifyBoolean, verifyEnumString, verifyFinitePositiveFloat, verifyObject, @@ -78,19 +84,12 @@ import { verifyStringArray, } from "#src/util/json.js"; import { createHomogeneousScaleMatrix } from "#src/util/matrix.js"; -import { getObjectId } from "#src/util/object_id.js"; +import type { ProgressOptions } from "#src/util/progress_listener.js"; +import { ProgressSpan } from "#src/util/progress_listener.js"; import { scaleByExp10, unitFromJson } from "#src/util/si_units.js"; -import type { - SpecialProtocolCredentials, - SpecialProtocolCredentialsProvider, -} from "#src/util/special_protocol_request.js"; -import { - cancellableFetchSpecialOk, - parseSpecialUrl, -} from "#src/util/special_protocol_request.js"; class N5VolumeChunkSource extends WithParameters( - WithCredentialsProvider()(VolumeChunkSource), + WithSharedKvStoreContext(VolumeChunkSource), VolumeChunkSourceParameters, ) {} @@ -106,12 +105,11 @@ export class MultiscaleVolumeChunkSource extends GenericMultiscaleVolumeChunkSou } constructor( - chunkManager: Borrowed, - public credentialsProvider: SpecialProtocolCredentialsProvider, + public sharedKvStoreContext: SharedKvStoreContext, public multiscaleMetadata: MultiscaleMetadata, public scales: (ScaleMetadata | undefined)[], ) { - super(chunkManager); + super(sharedKvStoreContext.chunkManager); let dataType: DataType | undefined; let baseScaleIndex: number | undefined; scales.forEach((scale, i) => { @@ -131,7 +129,7 @@ export class MultiscaleVolumeChunkSource extends GenericMultiscaleVolumeChunkSou if (dataType === undefined) { throw new Error("At least one scale must be specified."); } - const baseDownsamplingInfo = multiscaleMetadata.scales[baseScaleIndex!]!; + const baseDownsamplingInfo = scales[baseScaleIndex!]!; const baseScale = scales[baseScaleIndex!]!; this.dataType = dataType; this.volumeType = VolumeType.IMAGE; @@ -146,7 +144,7 @@ export class MultiscaleVolumeChunkSource extends GenericMultiscaleVolumeChunkSou { transform: createHomogeneousScaleMatrix( Float64Array, - baseDownsamplingInfo.downsamplingFactor, + baseDownsamplingInfo.downsamplingFactors, /*square=*/ false, ), box: { @@ -161,14 +159,12 @@ export class MultiscaleVolumeChunkSource extends GenericMultiscaleVolumeChunkSou getSources(volumeSourceOptions: VolumeSourceOptions) { const { scales, rank } = this; - const scalesDownsamplingInfo = this.multiscaleMetadata.scales; return transposeNestedArrays( (scales.filter((scale) => scale !== undefined) as ScaleMetadata[]).map( - (scale, i) => { - const scaleDownsamplingInfo = scalesDownsamplingInfo[i]; + (scale) => { const transform = createHomogeneousScaleMatrix( Float32Array, - scaleDownsamplingInfo.downsamplingFactor, + scale.downsamplingFactors, ); return makeDefaultVolumeChunkSpecifications({ rank, @@ -183,10 +179,10 @@ export class MultiscaleVolumeChunkSource extends GenericMultiscaleVolumeChunkSou chunkSource: this.chunkManager.getChunkSource( N5VolumeChunkSource, { - credentialsProvider: this.credentialsProvider, + sharedKvStoreContext: this.sharedKvStoreContext, spec, parameters: { - url: scaleDownsamplingInfo.url, + url: scale.url, encoding: scale.encoding, }, }, @@ -204,134 +200,209 @@ interface MultiscaleMetadata { url: string; attributes: any; modelSpace: CoordinateSpace; - scales: { readonly url: string; readonly downsamplingFactor: Float64Array }[]; + scales: ( + | { + readonly url: string; + readonly downsamplingFactors?: Float64Array; + } + | undefined + )[]; } -class ScaleMetadata { +interface ScaleMetadata { + url: string; dataType: DataType; encoding: VolumeChunkEncoding; - size: Float32Array; - chunkSize: Uint32Array; + size: Float32Array; + chunkSize: Uint32Array; + downsamplingFactors: Float64Array; +} - constructor(obj: any) { - verifyObject(obj); - this.dataType = verifyObjectProperty(obj, "dataType", (x) => - verifyEnumString(x, DataType), - ); - this.size = Float32Array.from( - verifyObjectProperty(obj, "dimensions", (x) => - parseArray(x, verifyPositiveInt), - ), +function parseScaleMetadata( + url: string, + obj: any, + scaleIndex: number, + downsamplingFactors?: Float64Array, +): ScaleMetadata { + verifyObject(obj); + const dataType = verifyObjectProperty(obj, "dataType", (x) => + verifyEnumString(x, DataType), + ); + const size = Float32Array.from( + verifyObjectProperty(obj, "dimensions", (x) => + parseArray(x, verifyPositiveInt), + ), + ); + const chunkSize = verifyObjectProperty(obj, "blockSize", (x) => + parseFixedLengthArray(new Uint32Array(size.length), x, verifyPositiveInt), + ); + + let encoding: VolumeChunkEncoding | undefined; + verifyOptionalObjectProperty(obj, "compression", (compression) => { + encoding = verifyObjectProperty(compression, "type", (x) => + verifyEnumString(x, VolumeChunkEncoding), ); - this.chunkSize = verifyObjectProperty(obj, "blockSize", (x) => - parseFixedLengthArray( - new Uint32Array(this.size.length), - x, - verifyPositiveInt, - ), + if ( + encoding === VolumeChunkEncoding.GZIP && + verifyOptionalObjectProperty( + compression, + "useZlib", + verifyBoolean, + false, + ) === true + ) { + encoding = VolumeChunkEncoding.ZLIB; + } + }); + if (encoding === undefined) { + encoding = verifyObjectProperty(obj, "compressionType", (x) => + verifyEnumString(x, VolumeChunkEncoding), ); + } - let encoding: VolumeChunkEncoding | undefined; - verifyOptionalObjectProperty(obj, "compression", (compression) => { - encoding = verifyObjectProperty(compression, "type", (x) => - verifyEnumString(x, VolumeChunkEncoding), - ); - }); - if (encoding === undefined) { - encoding = verifyObjectProperty(obj, "compressionType", (x) => - verifyEnumString(x, VolumeChunkEncoding), - ); + if (downsamplingFactors === undefined) { + downsamplingFactors = verifyOptionalObjectProperty( + obj, + "downsamplingFactors", + (x) => + parseFixedLengthArray( + new Float64Array(size.length), + x, + verifyFinitePositiveFloat, + ), + ); + if (downsamplingFactors === undefined) { + if (scaleIndex === 0) { + downsamplingFactors = new Float64Array(size.length); + downsamplingFactors.fill(1); + } else { + throw new Error("Expected downsamplingFactors attribute"); + } } - this.encoding = encoding; } + + return { url, dataType, encoding, size, chunkSize, downsamplingFactors }; } function getAllScales( - chunkManager: ChunkManager, - credentialsProvider: SpecialProtocolCredentialsProvider, + sharedKvStoreContext: SharedKvStoreContext, multiscaleMetadata: MultiscaleMetadata, + options: Partial, ): Promise<(ScaleMetadata | undefined)[]> { return Promise.all( - multiscaleMetadata.scales.map(async (scale) => { - const attributes = await getAttributes( - chunkManager, - credentialsProvider, + multiscaleMetadata.scales.map(async (scale, scaleIndex) => { + if (scale === undefined) return undefined; + const { attributes } = (await getAttributes( + sharedKvStoreContext, scale.url, true, - ); + options, + ))!; if (attributes === undefined) return undefined; - return new ScaleMetadata(attributes); + try { + return parseScaleMetadata( + scale.url, + attributes, + scaleIndex, + scale.downsamplingFactors, + ); + } catch (e) { + throw new Error(`Error parsing array metadata at ${scale.url}`, { + cause: e, + }); + } }), ); } -function getAttributesJsonUrls(url: string): string[] { - let { protocol, host, path } = parseUrl(url); - if (path.endsWith("/")) { - path = path.substring(0, path.length - 1); - } - const urls: string[] = []; +function getAttributesJsonUrls( + kvStoreContext: KvStoreContext, + url: string, +): { attributesJsonUrl: string; directoryUrl: string; relativePath: string }[] { + const kvStore = kvStoreContext.getKvStore(url); + const urls: { + attributesJsonUrl: string; + directoryUrl: string; + relativePath: string; + }[] = []; + let path = kvStore.path.substring(0, kvStore.path.length - 1); while (true) { - urls.push(`${protocol}://${host}${path}/attributes.json`); + const directoryPath = ensurePathIsDirectory(path); + urls.push({ + attributesJsonUrl: kvStore.store.getUrl( + joinPath(path, "attributes.json"), + ), + directoryUrl: kvStore.store.getUrl(directoryPath), + relativePath: kvStore.path.substring(directoryPath.length), + }); + if (path === "") break; const index = path.lastIndexOf("/"); - if (index === -1) break; path = path.substring(0, index); } return urls; } function getIndividualAttributesJson( - chunkManager: ChunkManager, - credentialsProvider: SpecialProtocolCredentialsProvider, + sharedKvStoreContext: SharedKvStoreContext, url: string, required: boolean, + options: Partial, ): Promise { - return chunkManager.memoize.getUncounted( + return sharedKvStoreContext.chunkManager.memoize.getAsync( { type: "n5:attributes.json", url, - credentialsProvider: getObjectId(credentialsProvider), }, - () => - cancellableFetchSpecialOk(credentialsProvider, url, {}, responseJson) - .then((j) => { - try { - return verifyObject(j); - } catch (e) { - throw new Error( - `Error reading attributes from ${url}: ${e.message}`, - ); - } - }) - .catch((e) => { - if (isNotFoundError(e)) { - if (required) return undefined; - return {}; - } - throw e; - }), + options, + async (progressOptions) => { + using _span = new ProgressSpan(progressOptions.progressListener, { + message: `Reading n5 metadata from ${url}`, + }); + const response = await sharedKvStoreContext.kvStoreContext.read(url, { + ...progressOptions, + throwIfMissing: required, + }); + if (response === undefined) return undefined; + const json = await response.response.json(); + try { + return verifyObject(json); + } catch (e) { + throw new Error(`Error reading attributes from ${url}`, { cause: e }); + } + }, ); } async function getAttributes( - chunkManager: ChunkManager, - credentialsProvider: SpecialProtocolCredentialsProvider, + sharedKvStoreContext: SharedKvStoreContext, url: string, required: boolean, -): Promise { - const attributesJsonUrls = getAttributesJsonUrls(url); + options: Partial, +): Promise< + { attributes: unknown; rootUrl: string; pathFromRoot: string } | undefined +> { + const attributesJsonUrls = getAttributesJsonUrls( + sharedKvStoreContext.kvStoreContext, + url, + ); const metadata = await Promise.all( attributesJsonUrls.map((u, i) => getIndividualAttributesJson( - chunkManager, - credentialsProvider, - u, + sharedKvStoreContext, + u.attributesJsonUrl, required && i === attributesJsonUrls.length - 1, + options, ), ), ); - if (metadata.indexOf(undefined) !== -1) return undefined; + const rootIndex = metadata.findLastIndex((x) => x !== undefined); + if (rootIndex === -1) return undefined; metadata.reverse(); - return Object.assign({}, ...metadata); + const rootInfo = attributesJsonUrls[rootIndex]; + return { + attributes: Object.assign({}, ...metadata.filter((x) => x !== undefined)), + rootUrl: rootInfo.directoryUrl, + pathFromRoot: rootInfo.relativePath, + }; } function verifyRank(existing: number, n: number) { @@ -377,10 +448,12 @@ function getDefaultAxes(rank: number) { return axes; } -function getMultiscaleMetadata( +async function getMultiscaleMetadata( + sharedKvStoreContext: SharedKvStoreContext, url: string, attributes: any, -): MultiscaleMetadata { + progressOptions: ProgressOptions, +): Promise { verifyObject(attributes); let rank = -1; @@ -400,8 +473,8 @@ function getMultiscaleMetadata( return units; }); let defaultUnit = { unit: "m", exponent: -9 }; - let singleDownsamplingFactors: Float64Array | undefined; - let allDownsamplingFactors: Float64Array[] | undefined; + let singleDownsamplingFactors: Float64Array | undefined; + let allDownsamplingFactors: Float64Array[] | undefined; verifyOptionalObjectProperty(attributes, "downsamplingFactors", (dObj) => { const { single, all, rank: curRank } = parseDownsamplingFactors(dObj); rank = verifyRank(rank, curRank); @@ -490,17 +563,33 @@ function getMultiscaleMetadata( }); if (dimensions === undefined) { if (allDownsamplingFactors === undefined) { - throw new Error( - "Not valid single-resolution or multi-resolution dataset", + const scaleDirectories = await findScaleDirectories( + sharedKvStoreContext, + url, + progressOptions, ); + if (scaleDirectories.length === 0) { + throw new Error( + "Not valid single-resolution or multi-resolution dataset", + ); + } + return { + modelSpace, + url, + attributes, + scales: scaleDirectories.map((name) => ({ + url: `${url}${name}/`, + downsamplingFactors: undefined, + })), + }; } return { modelSpace, url, attributes, scales: allDownsamplingFactors.map((f, i) => ({ - url: `${url}/s${i}`, - downsamplingFactor: f, + url: `${url}s${i}/`, + downsamplingFactors: f, })), }; } @@ -512,45 +601,80 @@ function getMultiscaleMetadata( modelSpace, url, attributes, - scales: [{ url, downsamplingFactor: singleDownsamplingFactors }], + scales: [{ url, downsamplingFactors: singleDownsamplingFactors }], }; } -export class N5DataSource extends DataSourceProvider { +async function findScaleDirectories( + sharedKvStoreContext: SharedKvStoreContext, + url: string, + progressOptions: ProgressOptions, +): Promise { + const result = await sharedKvStoreContext.kvStoreContext.list(url, { + responseKeys: "suffix", + ...progressOptions, + }); + const scaleDirectories: string[] = []; + for (const directory of result.directories) { + if (directory.match(/^s(?:0|[1-9][0-9]*)$/)) { + const scale = Number(directory.substring(1)); + scaleDirectories[scale] = directory; + } + } + return scaleDirectories; +} + +export class N5DataSource implements KvStoreBasedDataSourceProvider { + get scheme() { + return "n5"; + } + get expectsDirectory() { + return true; + } get description() { return "N5 data source"; } - get(options: GetDataSourceOptions): Promise { - let { providerUrl } = options; - if (providerUrl.endsWith("/")) { - providerUrl = providerUrl.substring(0, providerUrl.length - 1); - } - return options.chunkManager.memoize.getUncounted( - { type: "n5:MultiscaleVolumeChunkSource", providerUrl }, - async () => { - const { url, credentialsProvider } = parseSpecialUrl( - providerUrl, - options.credentialsManager, - ); - const attributes = await getAttributes( - options.chunkManager, - credentialsProvider, + get(options: GetKvStoreBasedDataSourceOptions): Promise { + ensureNoQueryOrFragmentParameters(options.url); + const url = kvstoreEnsureDirectoryPipelineUrl( + pipelineUrlJoin( + kvstoreEnsureDirectoryPipelineUrl(options.kvStoreUrl), + options.url.suffix ?? "", + ), + ); + const { sharedKvStoreContext } = options.registry; + return options.registry.chunkManager.memoize.getAsync( + { type: "n5:MultiscaleVolumeChunkSource", url }, + options, + async (progressOptions) => { + const attributeResult = await getAttributes( + sharedKvStoreContext, url, false, + progressOptions, + ); + if (attributeResult === undefined) { + throw new Error("N5 metadata not found"); + } + const { attributes, rootUrl, pathFromRoot } = attributeResult; + const multiscaleMetadata = await getMultiscaleMetadata( + sharedKvStoreContext, + url, + attributes, + progressOptions, ); - const multiscaleMetadata = getMultiscaleMetadata(url, attributes); const scales = await getAllScales( - options.chunkManager, - credentialsProvider, + sharedKvStoreContext, multiscaleMetadata, + progressOptions, ); const volume = new MultiscaleVolumeChunkSource( - options.chunkManager, - credentialsProvider, + sharedKvStoreContext, multiscaleMetadata, scales, ); return { + canonicalUrl: `${rootUrl}|${options.url.scheme}:${pathFromRoot}`, modelTransform: makeIdentityTransform(volume.modelSpace), subsources: [ { @@ -575,11 +699,25 @@ export class N5DataSource extends DataSourceProvider { ); } - completeUrl(options: CompleteUrlOptions) { - return completeHttpPath( - options.credentialsManager, - options.providerUrl, - options.cancellationToken, - ); + async completeUrl( + options: GetKvStoreBasedDataSourceOptions, + ): Promise { + ensureNoQueryOrFragmentParameters(options.url); + return getKvStorePathCompletions(options.registry.sharedKvStoreContext, { + baseUrl: kvstoreEnsureDirectoryPipelineUrl(options.kvStoreUrl), + path: options.url.suffix ?? "", + directoryOnly: true, + signal: options.signal, + progressListener: options.progressListener, + }); } } + +export function registerAutoDetect(registry: AutoDetectRegistry) { + registry.registerDirectoryFormat( + simpleFilePresenceAutoDetectDirectorySpec(new Set(["attributes.json"]), { + suffix: "n5:", + description: "N5", + }), + ); +} diff --git a/src/datasource/n5/register_default.ts b/src/datasource/n5/register_default.ts index dddddbb211..7732860e74 100644 --- a/src/datasource/n5/register_default.ts +++ b/src/datasource/n5/register_default.ts @@ -14,7 +14,18 @@ * limitations under the License. */ -import { registerProvider } from "#src/datasource/default_provider.js"; -import { N5DataSource } from "#src/datasource/n5/frontend.js"; +import { + registerKvStoreBasedDataProvider, + dataSourceAutoDetectRegistry, + registerProvider, +} from "#src/datasource/default_provider.js"; +import { KvStoreBasedDataSourceLegacyUrlAdapter } from "#src/datasource/index.js"; +import { + N5DataSource, + registerAutoDetect, +} from "#src/datasource/n5/frontend.js"; -registerProvider("n5", () => new N5DataSource()); +const provider = new N5DataSource(); +registerKvStoreBasedDataProvider(provider); +registerProvider(new KvStoreBasedDataSourceLegacyUrlAdapter(provider)); +registerAutoDetect(dataSourceAutoDetectRegistry); diff --git a/src/datasource/ngauth/credentials_provider.ts b/src/datasource/ngauth/credentials_provider.ts deleted file mode 100644 index 2d3affd68c..0000000000 --- a/src/datasource/ngauth/credentials_provider.ts +++ /dev/null @@ -1,151 +0,0 @@ -/** - * @license - * Copyright 2020 Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { fetchWithCredentials } from "#src/credentials_provider/http_request.js"; -import { - CredentialsProvider, - makeCredentialsGetter, -} from "#src/credentials_provider/index.js"; -import type { OAuth2Credentials } from "#src/credentials_provider/oauth2.js"; -import { StatusMessage } from "#src/status.js"; -import { HttpError, responseJson } from "#src/util/http_request.js"; -import { - verifyObject, - verifyObjectProperty, - verifyString, -} from "#src/util/json.js"; - -function makeOriginError(serverUrl: string): Error { - return new Error( - `ngauth server ${serverUrl} ` + - `does not allow requests from Neuroglancer instance ${self.origin}`, - ); -} - -export interface Credentials { - token: string; -} - -async function waitForLogin(serverUrl: string): Promise { - const status = new StatusMessage(/*delay=*/ false); - function writeLoginStatus(message: string, buttonMessage: string) { - status.element.textContent = message + " "; - const button = document.createElement("button"); - button.textContent = buttonMessage; - status.element.appendChild(button); - button.addEventListener("click", () => { - window.open( - `${serverUrl}/login?origin=${encodeURIComponent(self.origin)}`, - ); - writeLoginStatus( - `Waiting for login to ngauth server ${serverUrl}...`, - "Retry", - ); - }); - } - const messagePromise = new Promise((resolve, reject) => { - function messageHandler(event: MessageEvent) { - const eventOrigin = - event.origin || ((event).originalEvent).origin; - if (eventOrigin !== serverUrl) { - return; - } - const removeListener = () => { - window.removeEventListener("message", messageHandler, false); - }; - const { data } = event; - if (event.data === "badorigin") { - removeListener(); - reject(makeOriginError(serverUrl)); - } - try { - verifyObject(data); - const token = verifyObjectProperty(data, "token", verifyString); - removeListener(); - resolve(token); - } catch (e) { - console.log( - "ngauth: Received unexpected message from ${serverUrl}", - event, - ); - } - } - window.addEventListener("message", messageHandler, false); - }); - writeLoginStatus(`ngauth server ${serverUrl} login required.`, "Login"); - try { - return { token: await messagePromise }; - } finally { - status.dispose(); - } -} - -export class NgauthCredentialsProvider extends CredentialsProvider { - constructor(public serverUrl: string) { - super(); - } - get = makeCredentialsGetter(async () => { - const response = await fetch(`${this.serverUrl}/token`, { - method: "POST", - credentials: "include", - }); - switch (response.status) { - case 200: - return { token: await response.text() }; - case 401: - return await waitForLogin(this.serverUrl); - case 403: - throw makeOriginError(this.serverUrl); - default: - throw HttpError.fromResponse(response); - } - }); -} - -export class NgauthGcsCredentialsProvider extends CredentialsProvider { - constructor( - public ngauthCredentialsProvider: CredentialsProvider, - public serverUrl: string, - public bucket: string, - ) { - super(); - } - get = makeCredentialsGetter(async () => { - const response = await fetchWithCredentials( - this.ngauthCredentialsProvider, - `${this.serverUrl}/gcs_token`, - { method: "POST" }, - responseJson, - (credentials, init) => { - return { - ...init, - body: JSON.stringify({ - token: credentials.token, - bucket: this.bucket, - }), - }; - }, - (error) => { - const { status } = error; - if (status === 401) { - return "refresh"; - } - throw error; - }, - ); - return { tokenType: "Bearer", accessToken: response.token }; - }); -} diff --git a/src/datasource/nggraph/frontend.ts b/src/datasource/nggraph/frontend.ts index 056baf4bc4..8578c9cf6d 100644 --- a/src/datasource/nggraph/frontend.ts +++ b/src/datasource/nggraph/frontend.ts @@ -16,7 +16,7 @@ import { debounce } from "lodash-es"; import type { ChunkManager } from "#src/chunk_manager/frontend.js"; -import { fetchWithCredentials } from "#src/credentials_provider/http_request.js"; +import { fetchOkWithCredentials } from "#src/credentials_provider/http_request.js"; import { CredentialsProvider, makeCredentialsGetter, @@ -27,8 +27,8 @@ import type { DataSource, DataSubsourceEntry, GetDataSourceOptions, + DataSourceProvider, } from "#src/datasource/index.js"; -import { DataSourceProvider } from "#src/datasource/index.js"; import type { Credentials } from "#src/datasource/nggraph/credentials_provider.js"; import { NggraphCredentialsProvider } from "#src/datasource/nggraph/credentials_provider.js"; import type { SegmentationUserLayer } from "#src/layer/segmentation/index.js"; @@ -45,11 +45,9 @@ import { } from "#src/segmentation_graph/source.js"; import { StatusMessage } from "#src/status.js"; import type { Uint64Set } from "#src/uint64_set.js"; -import type { CancellationToken } from "#src/util/cancellation.js"; -import { uncancelableToken } from "#src/util/cancellation.js"; import { getPrefixMatchesWithDescriptions } from "#src/util/completion.js"; import { DisjointUint64Sets } from "#src/util/disjoint_sets.js"; -import { responseJson } from "#src/util/http_request.js"; +import type { RequestInitWithProgress } from "#src/util/http_request.js"; import { parseArray, verifyFiniteFloat, @@ -117,7 +115,7 @@ type GraphSegmentUpdate = GraphSegmentInfo | "invalid" | "error"; let updateGeneration = 0; class GraphConnection extends SegmentationGraphSourceConnection { - graph: NggraphSegmentationGraphSource; + declare graph: NggraphSegmentationGraphSource; constructor( graph: NggraphSegmentationGraphSource, segmentsState: VisibleSegmentsState, @@ -611,13 +609,11 @@ function fetchWithNggraphCredentials( serverUrl: string, path: string, init: RequestInit, - cancellationToken: CancellationToken = uncancelableToken, ): Promise { - return fetchWithCredentials( + return fetchOkWithCredentials( credentialsProvider, `${serverUrl}${path}`, init, - responseJson, (credentials, init) => { const headers = new Headers(init.headers); headers.set("Authorization", credentials.token); @@ -628,8 +624,7 @@ function fetchWithNggraphCredentials( if (status === 401) return "refresh"; throw error; }, - cancellationToken, - ); + ).then((response) => response.json()); } interface EntityCredentials extends Credentials { @@ -642,14 +637,12 @@ function nggraphServerFetch( serverUrl: string, path: string, init: RequestInit, - cancellationToken: CancellationToken = uncancelableToken, ): Promise { return fetchWithNggraphCredentials( getCredentialsProvider(chunkManager, serverUrl), serverUrl, path, init, - cancellationToken, ); } @@ -709,15 +702,13 @@ function nggraphGraphFetch( serverUrl: string, entityName: string, path: string, - init: RequestInit, - cancellationToken: CancellationToken = uncancelableToken, + init: RequestInitWithProgress, ): Promise { return fetchWithNggraphCredentials( getEntityCredentialsProvider(chunkManager, serverUrl, entityName), serverUrl, path, init, - cancellationToken, ); } @@ -742,41 +733,46 @@ function parseListResponse(response: any) { ); } -export class NggraphDataSource extends DataSourceProvider { +export class NggraphDataSource implements DataSourceProvider { + get scheme() { + return "nggraph"; + } get description() { return "nggraph data source"; } get(options: GetDataSourceOptions): Promise { const { serverUrl, id } = parseNggraphUrl(options.providerUrl); - return options.chunkManager.memoize.getUncounted( + return options.registry.chunkManager.memoize.getAsync( { type: "nggraph:get", serverUrl, id }, - async (): Promise => { + options, + async (progressOptions): Promise => { const entityCredentialsProvider = getEntityCredentialsProvider( - options.chunkManager, + options.registry.chunkManager, serverUrl, id, ); - const { entityType } = (await entityCredentialsProvider.get()) - .credentials; + const { entityType } = ( + await entityCredentialsProvider.get(undefined, progressOptions) + ).credentials; if (entityType !== "graph") { throw new Error( `Unsupported entity type: ${JSON.stringify(entityType)}`, ); } const { datasource_url: baseSegmentation } = await nggraphGraphFetch( - options.chunkManager, + options.registry.chunkManager, serverUrl, id, "/graph/config", - { method: "POST" }, + { method: "POST", ...progressOptions }, ); const baseSegmentationDataSource = await options.registry.get({ ...options, url: baseSegmentation, }); const segmentationGraph = new NggraphSegmentationGraphSource( - options.chunkManager, + options.registry.chunkManager, serverUrl, id, ); @@ -799,13 +795,20 @@ export class NggraphDataSource extends DataSourceProvider { async completeUrl(options: CompleteUrlOptions): Promise { const { serverUrl, id } = parseNggraphUrl(options.providerUrl); - const list = await options.chunkManager.memoize.getUncounted( + const list = await options.registry.chunkManager.memoize.getAsync( { type: "nggraph:list", serverUrl }, - async () => { + options, + async (progressOptions) => { return parseListResponse( - await nggraphServerFetch(options.chunkManager, serverUrl, "/list", { - method: "POST", - }), + await nggraphServerFetch( + options.registry.chunkManager, + serverUrl, + "/list", + { + method: "POST", + ...progressOptions, + }, + ), ); }, ); diff --git a/src/datasource/nggraph/register_default.ts b/src/datasource/nggraph/register_default.ts index 82c0754698..99e3c0dede 100644 --- a/src/datasource/nggraph/register_default.ts +++ b/src/datasource/nggraph/register_default.ts @@ -17,4 +17,4 @@ import { registerProvider } from "#src/datasource/default_provider.js"; import { NggraphDataSource } from "#src/datasource/nggraph/frontend.js"; -registerProvider("nggraph", () => new NggraphDataSource()); +registerProvider(new NggraphDataSource()); diff --git a/src/datasource/nifti/async_computation.ts b/src/datasource/nifti/async_computation.ts deleted file mode 100644 index 9f856a9efa..0000000000 --- a/src/datasource/nifti/async_computation.ts +++ /dev/null @@ -1 +0,0 @@ -import "#src/async_computation/decode_gzip.js"; diff --git a/src/datasource/nifti/backend.ts b/src/datasource/nifti/backend.ts index e3670324e8..34c62465e7 100644 --- a/src/datasource/nifti/backend.ts +++ b/src/datasource/nifti/backend.ts @@ -16,26 +16,20 @@ import type { NIFTI2 } from "nifti-reader-js"; import { isCompressed, NIFTI1, readHeader, readImage } from "nifti-reader-js"; -import { decodeGzip } from "#src/async_computation/decode_gzip_request.js"; -import { requestAsyncComputation } from "#src/async_computation/request.js"; -import type { ChunkManager } from "#src/chunk_manager/backend.js"; import { WithParameters } from "#src/chunk_manager/backend.js"; -import { ChunkPriorityTier } from "#src/chunk_manager/base.js"; -import type { PriorityGetter } from "#src/chunk_manager/generic_file_source.js"; -import { GenericSharedDataSource } from "#src/chunk_manager/generic_file_source.js"; -import type { SharedCredentialsProviderCounterpart } from "#src/credentials_provider/shared_counterpart.js"; -import { WithSharedCredentialsProviderCounterpart } from "#src/credentials_provider/shared_counterpart.js"; +import { getCachedDecodedUrl } from "#src/chunk_manager/generic_file_source.js"; import type { NiftiVolumeInfo } from "#src/datasource/nifti/base.js"; import { GET_NIFTI_VOLUME_INFO_RPC_ID, VolumeSourceParameters, } from "#src/datasource/nifti/base.js"; +import type { SharedKvStoreContextCounterpart } from "#src/kvstore/backend.js"; +import { WithSharedKvStoreContextCounterpart } from "#src/kvstore/backend.js"; +import type { ReadResponse } from "#src/kvstore/index.js"; import { decodeRawChunk } from "#src/sliceview/backend_chunk_decoders/raw.js"; import type { VolumeChunk } from "#src/sliceview/volume/backend.js"; import { VolumeChunkSource } from "#src/sliceview/volume/backend.js"; import { DataType } from "#src/sliceview/volume/base.js"; -import type { CancellationToken } from "#src/util/cancellation.js"; -import type { Borrowed } from "#src/util/disposable.js"; import { Endianness } from "#src/util/endian.js"; import { kOneVec, @@ -44,11 +38,9 @@ import { translationRotationScaleZReflectionToMat4, vec3, } from "#src/util/geom.js"; +import { decodeGzip } from "#src/util/gzip.js"; import * as matrix from "#src/util/matrix.js"; -import type { - SpecialProtocolCredentials, - SpecialProtocolCredentialsProvider, -} from "#src/util/special_protocol_request.js"; +import type { ProgressOptions } from "#src/util/progress_listener.js"; import type { RPCPromise } from "#src/worker_rpc.js"; import { registerPromiseRPC, registerSharedObject } from "#src/worker_rpc.js"; @@ -58,18 +50,15 @@ export class NiftiFileData { } async function decodeNiftiFile( - buffer: ArrayBuffer, - cancellationToken: CancellationToken, + readResponse: ReadResponse | undefined, + options: ProgressOptions, ) { + if (readResponse === undefined) { + throw new Error("Not found"); + } + let buffer = await readResponse.response.arrayBuffer(); if (isCompressed(buffer)) { - buffer = ( - await requestAsyncComputation( - decodeGzip, - cancellationToken, - [buffer], - new Uint8Array(buffer), - ) - ).buffer; + buffer = await decodeGzip(buffer, "gzip", options.signal); } const data = new NiftiFileData(); data.uncompressedData = buffer; @@ -82,40 +71,24 @@ async function decodeNiftiFile( } function getNiftiFileData( - chunkManager: Borrowed, - credentialsProvider: SpecialProtocolCredentialsProvider, + sharedKvStoreContextCounterpart: SharedKvStoreContextCounterpart, url: string, - getPriority: PriorityGetter, - cancellationToken: CancellationToken, + options: Partial, ) { - return GenericSharedDataSource.getUrl( - chunkManager, - credentialsProvider, - decodeNiftiFile, + return getCachedDecodedUrl( + sharedKvStoreContextCounterpart, url, - getPriority, - cancellationToken, + decodeNiftiFile, + options, ); } -const NIFTI_HEADER_INFO_PRIORITY = 1000; - async function getNiftiHeaderInfo( - chunkManager: Borrowed, - credentialsProvider: SpecialProtocolCredentialsProvider, + sharedKvStoreContext: SharedKvStoreContextCounterpart, url: string, - cancellationToken: CancellationToken, + options: Partial, ) { - const data = await getNiftiFileData( - chunkManager, - credentialsProvider, - url, - () => ({ - priorityTier: ChunkPriorityTier.VISIBLE, - priority: NIFTI_HEADER_INFO_PRIORITY, - }), - cancellationToken, - ); + const data = await getNiftiFileData(sharedKvStoreContext, url, options); return data.header; } @@ -174,174 +147,161 @@ const DATA_TYPE_CONVERSIONS = new Map([ registerPromiseRPC( GET_NIFTI_VOLUME_INFO_RPC_ID, - async function (x, cancellationToken): RPCPromise { - const chunkManager = this.getRef(x.chunkManager); - const credentialsProvider = this.getOptionalRef< - SharedCredentialsProviderCounterpart< - Exclude - > - >(x.credentialsProvider); - try { - const header = await getNiftiHeaderInfo( - chunkManager, - credentialsProvider, - x.url, - cancellationToken, + async function (x, progressOptions): RPCPromise { + const sharedKvStoreContext = this.get( + x.sharedKvStoreContext, + ) as SharedKvStoreContextCounterpart; + const header = await getNiftiHeaderInfo( + sharedKvStoreContext, + x.url, + progressOptions, + ); + const dataTypeInfo = DATA_TYPE_CONVERSIONS.get(header.datatypeCode); + if (dataTypeInfo === undefined) { + throw new Error( + "Unsupported data type: " + + `${NiftiDataType[header.datatypeCode] || header.datatypeCode}.`, ); - const dataTypeInfo = DATA_TYPE_CONVERSIONS.get(header.datatypeCode); - if (dataTypeInfo === undefined) { - throw new Error( - "Unsupported data type: " + - `${NiftiDataType[header.datatypeCode] || header.datatypeCode}.`, - ); - } - let spatialInvScale = 1; - let spatialUnit = ""; - switch (header.xyzt_units & NIFTI1.SPATIAL_UNITS_MASK) { - case NIFTI1.UNITS_METER: - spatialInvScale = 1; - spatialUnit = "m"; - break; - case NIFTI1.UNITS_MM: - spatialInvScale = 1e3; - spatialUnit = "m"; - break; - case NIFTI1.UNITS_MICRON: - spatialInvScale = 1e6; - spatialUnit = "m"; - break; - } + } + let spatialInvScale = 1; + let spatialUnit = ""; + switch (header.xyzt_units & NIFTI1.SPATIAL_UNITS_MASK) { + case NIFTI1.UNITS_METER: + spatialInvScale = 1; + spatialUnit = "m"; + break; + case NIFTI1.UNITS_MM: + spatialInvScale = 1e3; + spatialUnit = "m"; + break; + case NIFTI1.UNITS_MICRON: + spatialInvScale = 1e6; + spatialUnit = "m"; + break; + } - let timeUnit = ""; - let timeInvScale = 1; - switch (header.xyzt_units & NIFTI1.TEMPORAL_UNITS_MASK) { - case NIFTI1.UNITS_SEC: - timeUnit = "s"; - timeInvScale = 1; - break; - case NIFTI1.UNITS_MSEC: - timeUnit = "s"; - timeInvScale = 1e3; - break; - case NIFTI1.UNITS_USEC: - timeUnit = "s"; - timeInvScale = 1e6; - break; - case NIFTI1.UNITS_HZ: - timeUnit = "Hz"; - timeInvScale = 1; - break; - case NIFTI1.UNITS_RADS: - timeUnit = "rad/s"; - timeInvScale = 1; - break; - } - let units: string[] = [ - spatialUnit, - spatialUnit, - spatialUnit, - timeUnit, - "", - "", - "", - ]; - let sourceScales = Float64Array.of( - header.pixDims[1] / spatialInvScale, - header.pixDims[2] / spatialInvScale, - header.pixDims[3] / spatialInvScale, - header.pixDims[4] / timeInvScale, - header.pixDims[5], - header.pixDims[6], - header.pixDims[7], - ); - let viewScales = Float64Array.of( - 1 / spatialInvScale, - 1 / spatialInvScale, - 1 / spatialInvScale, - 1 / timeInvScale, - 1, - 1, - 1, - ); - let sourceNames = ["i", "j", "k", "m", "c^", "c1^", "c2^"]; - let viewNames = ["x", "y", "z", "t", "c^", "c1^", "c2^"]; - const rank = header.dims[0]; - sourceNames = sourceNames.slice(0, rank); - viewNames = viewNames.slice(0, rank); - units = units.slice(0, rank); - sourceScales = sourceScales.slice(0, rank); - viewScales = viewScales.slice(0, rank); - const { quatern_b, quatern_c, quatern_d } = header; - const quatern_a = Math.sqrt( - 1.0 - - quatern_b * quatern_b - - quatern_c * quatern_c - - quatern_d * quatern_d, - ); - const qfac = header.pixDims[0] === -1 ? -1 : 1; - const qoffset = vec3.fromValues( - header.qoffset_x, - header.qoffset_y, - header.qoffset_z, - ); - // https://nifti.nimh.nih.gov/nifti-1/documentation/nifti1fields/nifti1fields_pages/qsform.html - const method3Transform = convertAffine(header.affine); - method3Transform; - const method2Transform = translationRotationScaleZReflectionToMat4( - mat4.create(), - qoffset, - quat.fromValues(quatern_b, quatern_c, quatern_d, quatern_a), - kOneVec, - qfac, - ); - const transform = matrix.createIdentity(Float64Array, rank + 1); - const copyRank = Math.min(3, rank); - for (let row = 0; row < copyRank; ++row) { - for (let col = 0; col < copyRank; ++col) { - transform[col * (rank + 1) + row] = method2Transform[col * 4 + row]; - } - transform[rank * (rank + 1) + row] = method2Transform[12 + row]; + let timeUnit = ""; + let timeInvScale = 1; + switch (header.xyzt_units & NIFTI1.TEMPORAL_UNITS_MASK) { + case NIFTI1.UNITS_SEC: + timeUnit = "s"; + timeInvScale = 1; + break; + case NIFTI1.UNITS_MSEC: + timeUnit = "s"; + timeInvScale = 1e3; + break; + case NIFTI1.UNITS_USEC: + timeUnit = "s"; + timeInvScale = 1e6; + break; + case NIFTI1.UNITS_HZ: + timeUnit = "Hz"; + timeInvScale = 1; + break; + case NIFTI1.UNITS_RADS: + timeUnit = "rad/s"; + timeInvScale = 1; + break; + } + let units: string[] = [ + spatialUnit, + spatialUnit, + spatialUnit, + timeUnit, + "", + "", + "", + ]; + let sourceScales = Float64Array.of( + header.pixDims[1] / spatialInvScale, + header.pixDims[2] / spatialInvScale, + header.pixDims[3] / spatialInvScale, + header.pixDims[4] / timeInvScale, + header.pixDims[5], + header.pixDims[6], + header.pixDims[7], + ); + let viewScales = Float64Array.of( + 1 / spatialInvScale, + 1 / spatialInvScale, + 1 / spatialInvScale, + 1 / timeInvScale, + 1, + 1, + 1, + ); + let sourceNames = ["i", "j", "k", "m", "c^", "c1^", "c2^"]; + let viewNames = ["x", "y", "z", "t", "c^", "c1^", "c2^"]; + const rank = header.dims[0]; + sourceNames = sourceNames.slice(0, rank); + viewNames = viewNames.slice(0, rank); + units = units.slice(0, rank); + sourceScales = sourceScales.slice(0, rank); + viewScales = viewScales.slice(0, rank); + const { quatern_b, quatern_c, quatern_d } = header; + const quatern_a = Math.sqrt( + 1.0 - + quatern_b * quatern_b - + quatern_c * quatern_c - + quatern_d * quatern_d, + ); + const qfac = header.pixDims[0] === -1 ? -1 : 1; + const qoffset = vec3.fromValues( + header.qoffset_x, + header.qoffset_y, + header.qoffset_z, + ); + // https://nifti.nimh.nih.gov/nifti-1/documentation/nifti1fields/nifti1fields_pages/qsform.html + const method3Transform = convertAffine(header.affine); + method3Transform; + const method2Transform = translationRotationScaleZReflectionToMat4( + mat4.create(), + qoffset, + quat.fromValues(quatern_b, quatern_c, quatern_d, quatern_a), + kOneVec, + qfac, + ); + const transform = matrix.createIdentity(Float64Array, rank + 1); + const copyRank = Math.min(3, rank); + for (let row = 0; row < copyRank; ++row) { + for (let col = 0; col < copyRank; ++col) { + transform[col * (rank + 1) + row] = method2Transform[col * 4 + row]; } - const info: NiftiVolumeInfo = { - rank, - sourceNames, - viewNames, - units, - sourceScales, - viewScales, - description: header.description, - transform, - dataType: dataTypeInfo.dataType, - volumeSize: Uint32Array.from(header.dims.slice(1, 1 + rank)), - }; - return { value: info }; - } finally { - chunkManager.dispose(); - credentialsProvider?.dispose(); + transform[rank * (rank + 1) + row] = method2Transform[12 + row]; } + const info: NiftiVolumeInfo = { + rank, + sourceNames, + viewNames, + units, + sourceScales, + viewScales, + description: header.description, + transform, + dataType: dataTypeInfo.dataType, + volumeSize: Uint32Array.from(header.dims.slice(1, 1 + rank)), + }; + return { value: info }; }, ); @registerSharedObject() export class NiftiVolumeChunkSource extends WithParameters( - WithSharedCredentialsProviderCounterpart()( - VolumeChunkSource, - ), + WithSharedKvStoreContextCounterpart(VolumeChunkSource), VolumeSourceParameters, ) { - async download(chunk: VolumeChunk, cancellationToken: CancellationToken) { + async download(chunk: VolumeChunk, signal: AbortSignal) { chunk.chunkDataSize = this.spec.chunkDataSize; const data = await getNiftiFileData( - this.chunkManager, - this.credentialsProvider, + this.sharedKvStoreContext, this.parameters.url, - () => ({ priorityTier: chunk.priorityTier, priority: chunk.priority }), - cancellationToken, + { signal }, ); const imageBuffer = readImage(data.header, data.uncompressedData); await decodeRawChunk( chunk, - cancellationToken, + signal, imageBuffer, data.header.littleEndian ? Endianness.LITTLE : Endianness.BIG, ); diff --git a/src/datasource/nifti/frontend.ts b/src/datasource/nifti/frontend.ts index c61ebdbfb7..35bdceeeb3 100644 --- a/src/datasource/nifti/frontend.ts +++ b/src/datasource/nifti/frontend.ts @@ -20,28 +20,29 @@ */ import { makeDataBoundsBoundingBoxAnnotationSet } from "#src/annotation/index.js"; -import type { ChunkManager } from "#src/chunk_manager/frontend.js"; import { WithParameters } from "#src/chunk_manager/frontend.js"; import { makeCoordinateSpace, makeIdentityTransformedBoundingBox, } from "#src/coordinate_transform.js"; import { - getCredentialsProviderCounterpart, - WithCredentialsProvider, -} from "#src/credentials_provider/chunk_source_frontend.js"; -import type { CredentialsManager } from "#src/credentials_provider/index.js"; -import type { - CompleteUrlOptions, - DataSource, - GetDataSourceOptions, + type DataSource, + type GetKvStoreBasedDataSourceOptions, + type KvStoreBasedDataSourceProvider, } from "#src/datasource/index.js"; -import { DataSourceProvider } from "#src/datasource/index.js"; import type { NiftiVolumeInfo } from "#src/datasource/nifti/base.js"; import { GET_NIFTI_VOLUME_INFO_RPC_ID, VolumeSourceParameters, } from "#src/datasource/nifti/base.js"; +import type { + AutoDetectFileOptions, + AutoDetectFileSpec, + AutoDetectRegistry, +} from "#src/kvstore/auto_detect.js"; +import { WithSharedKvStoreContext } from "#src/kvstore/chunk_source_frontend.js"; +import type { SharedKvStoreContext } from "#src/kvstore/frontend.js"; +import { ensureEmptyUrlSuffix } from "#src/kvstore/url.js"; import type { VolumeSourceOptions } from "#src/sliceview/volume/base.js"; import { makeVolumeChunkSpecificationWithDefaultCompression, @@ -51,29 +52,22 @@ import { MultiscaleVolumeChunkSource, VolumeChunkSource, } from "#src/sliceview/volume/frontend.js"; -import type { CancellationToken } from "#src/util/cancellation.js"; -import { uncancelableToken } from "#src/util/cancellation.js"; -import { completeHttpPath } from "#src/util/http_path_completion.js"; +import { Endianness } from "#src/util/endian.js"; import * as matrix from "#src/util/matrix.js"; -import type { - SpecialProtocolCredentials, - SpecialProtocolCredentialsProvider, -} from "#src/util/special_protocol_request.js"; -import { parseSpecialUrl } from "#src/util/special_protocol_request.js"; +import type { ProgressOptions } from "#src/util/progress_listener.js"; class NiftiVolumeChunkSource extends WithParameters( - WithCredentialsProvider()(VolumeChunkSource), + WithSharedKvStoreContext(VolumeChunkSource), VolumeSourceParameters, ) {} export class NiftiMultiscaleVolumeChunkSource extends MultiscaleVolumeChunkSource { constructor( - chunkManager: ChunkManager, - public credentialsProvider: SpecialProtocolCredentialsProvider, + public sharedKvStoreContext: SharedKvStoreContext, public url: string, public info: NiftiVolumeInfo, ) { - super(chunkManager); + super(sharedKvStoreContext.chunkManager); } get dataType() { return this.info.dataType; @@ -105,7 +99,7 @@ export class NiftiMultiscaleVolumeChunkSource extends MultiscaleVolumeChunkSourc chunkSource: this.chunkManager.getChunkSource( NiftiVolumeChunkSource, { - credentialsProvider: this.credentialsProvider, + sharedKvStoreContext: this.sharedKvStoreContext, spec, parameters: { url: this.url }, }, @@ -118,48 +112,37 @@ export class NiftiMultiscaleVolumeChunkSource extends MultiscaleVolumeChunkSourc } function getNiftiVolumeInfo( - chunkManager: ChunkManager, - credentialsProvider: SpecialProtocolCredentialsProvider, + sharedKvStoreContext: SharedKvStoreContext, url: string, - cancellationToken: CancellationToken, + options: Partial, ) { - return chunkManager.rpc!.promiseInvoke( + return sharedKvStoreContext.chunkManager.rpc!.promiseInvoke( GET_NIFTI_VOLUME_INFO_RPC_ID, { - chunkManager: chunkManager.addCounterpartRef(), - credentialsProvider: - getCredentialsProviderCounterpart( - chunkManager, - credentialsProvider, - ), + sharedKvStoreContext: sharedKvStoreContext.rpcId, url: url, }, - cancellationToken, + { signal: options.signal, progressListener: options.progressListener }, ); } function getDataSource( - chunkManager: ChunkManager, - credentialsManager: CredentialsManager, + sharedKvStoreContext: SharedKvStoreContext, url: string, + options: Partial, ) { - return chunkManager.memoize.getUncounted( + return sharedKvStoreContext.chunkManager.memoize.getAsync( { type: "nifti/getVolume", url }, - async () => { - const { url: parsedUrl, credentialsProvider } = parseSpecialUrl( - url, - credentialsManager, - ); + options, + async (progressOptions) => { const info = await getNiftiVolumeInfo( - chunkManager, - credentialsProvider, - parsedUrl, - uncancelableToken, + sharedKvStoreContext, + url, + progressOptions, ); const volume = new NiftiMultiscaleVolumeChunkSource( - chunkManager, - credentialsProvider, - parsedUrl, + sharedKvStoreContext, + url, info, ); const box = { @@ -180,6 +163,7 @@ function getDataSource( units: info.units, }); const dataSource: DataSource = { + canonicalUrl: `${url}|nifti:`, subsources: [ { id: "default", @@ -207,23 +191,70 @@ function getDataSource( ); } -export class NiftiDataSource extends DataSourceProvider { +export class NiftiDataSource implements KvStoreBasedDataSourceProvider { + get scheme() { + return "nifti"; + } get description() { - return "Single NIfTI file"; + return "NIfTI"; } - get(options: GetDataSourceOptions): Promise { + get singleFile() { + return true; + } + get(options: GetKvStoreBasedDataSourceOptions): Promise { + ensureEmptyUrlSuffix(options.url); return getDataSource( - options.chunkManager, - options.credentialsManager, - options.providerUrl, + options.registry.sharedKvStoreContext, + options.kvStoreUrl, + options, ); } +} - completeUrl(options: CompleteUrlOptions) { - return completeHttpPath( - options.credentialsManager, - options.providerUrl, - options.cancellationToken, +function getAutoDetectSpec( + headerSize: number, + magicStringOffset: number, + magicString: string, + version: string, +): AutoDetectFileSpec { + async function match(options: AutoDetectFileOptions) { + const { prefix } = options; + if (prefix.length < magicStringOffset + magicString.length) return []; + const dv = new DataView( + prefix.buffer, + prefix.byteOffset, + prefix.byteLength, ); + let endianness: Endianness; + if (dv.getInt32(0, /*littleEndian=*/ true) === headerSize) { + endianness = Endianness.LITTLE; + } else if (dv.getInt32(0, /*littleEndian=*/ false) === headerSize) { + endianness = Endianness.BIG; + } else { + return []; + } + for (let i = 0; i < magicString.length; ++i) { + if (magicString.charCodeAt(i) !== prefix[i + magicStringOffset]) + return []; + } + + return [ + { + suffix: "nifti:", + description: `NIfTI ${version} (${Endianness[endianness].toLowerCase()}-endian)`, + }, + ]; } + return { + prefixLength: magicStringOffset + magicString.length, + suffixLength: 0, + match, + }; +} + +export function registerAutoDetect(registry: AutoDetectRegistry) { + registry.registerFileFormat(getAutoDetectSpec(348, 344, "n+1\0", "v1")); + registry.registerFileFormat( + getAutoDetectSpec(540, 4, "n+2\0\r\n\x1a\n", "v2"), + ); } diff --git a/src/datasource/nifti/register_default.ts b/src/datasource/nifti/register_default.ts index cdf9a6c4ee..41ed086d2f 100644 --- a/src/datasource/nifti/register_default.ts +++ b/src/datasource/nifti/register_default.ts @@ -14,7 +14,18 @@ * limitations under the License. */ -import { registerProvider } from "#src/datasource/default_provider.js"; -import { NiftiDataSource } from "#src/datasource/nifti/frontend.js"; +import { + dataSourceAutoDetectRegistry, + registerKvStoreBasedDataProvider, + registerProvider, +} from "#src/datasource/default_provider.js"; +import { KvStoreBasedDataSourceLegacyUrlAdapter } from "#src/datasource/index.js"; +import { + NiftiDataSource, + registerAutoDetect, +} from "#src/datasource/nifti/frontend.js"; -registerProvider("nifti", () => new NiftiDataSource()); +const provider = new NiftiDataSource(); +registerKvStoreBasedDataProvider(provider); +registerProvider(new KvStoreBasedDataSourceLegacyUrlAdapter(provider)); +registerAutoDetect(dataSourceAutoDetectRegistry); diff --git a/src/datasource/obj/backend.ts b/src/datasource/obj/backend.ts index 0cbb36b33a..27554ccc35 100644 --- a/src/datasource/obj/backend.ts +++ b/src/datasource/obj/backend.ts @@ -16,18 +16,26 @@ import { parseOBJFromArrayBuffer } from "#src/async_computation/obj_mesh_request.js"; import { requestAsyncComputation } from "#src/async_computation/request.js"; -import { GenericSharedDataSource } from "#src/chunk_manager/generic_file_source.js"; +import { getCachedDecodedUrl } from "#src/chunk_manager/generic_file_source.js"; +import type { ReadResponse } from "#src/kvstore/index.js"; import { registerSingleMeshFactory } from "#src/single_mesh/backend.js"; -import type { CancellationToken } from "#src/util/cancellation.js"; +import type { ProgressOptions } from "#src/util/progress_listener.js"; /** - * This needs to be a global function, because it identifies the instance of GenericSharedDataSource + * This needs to be a global function, because it identifies the instance of SimpleAsyncCache * to use. */ -function parse(buffer: ArrayBuffer, cancellationToken: CancellationToken) { +async function parse( + readResponse: ReadResponse | undefined, + progressOptions: Partial, +) { + if (readResponse === undefined) { + throw new Error("Not found"); + } + const buffer = await readResponse.response.arrayBuffer(); return requestAsyncComputation( parseOBJFromArrayBuffer, - cancellationToken, + progressOptions.signal, [buffer], buffer, ); @@ -35,19 +43,6 @@ function parse(buffer: ArrayBuffer, cancellationToken: CancellationToken) { registerSingleMeshFactory("obj", { description: "OBJ", - getMesh: ( - chunkManager, - credentialsProvider, - url, - getPriority, - cancellationToken, - ) => - GenericSharedDataSource.getUrl( - chunkManager, - credentialsProvider, - parse, - url, - getPriority, - cancellationToken, - ), + getMesh: (sharedKvStoreContext, url, options) => + getCachedDecodedUrl(sharedKvStoreContext, url, parse, options), }); diff --git a/src/datasource/obj/frontend.ts b/src/datasource/obj/frontend.ts deleted file mode 100644 index a5a6e09500..0000000000 --- a/src/datasource/obj/frontend.ts +++ /dev/null @@ -1,66 +0,0 @@ -/** - * @license - * Copyright 2020 Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { - makeCoordinateSpace, - makeIdentityTransform, -} from "#src/coordinate_transform.js"; -import type { - CompleteUrlOptions, - DataSource, - GetDataSourceOptions, -} from "#src/datasource/index.js"; -import { DataSourceProvider } from "#src/datasource/index.js"; -import { getSingleMeshSource } from "#src/single_mesh/frontend.js"; -import { completeHttpPath } from "#src/util/http_path_completion.js"; - -export class ObjDataSource extends DataSourceProvider { - get description() { - return "Wavefront OBJ mesh file"; - } - - async get(options: GetDataSourceOptions): Promise { - const meshSource = await getSingleMeshSource( - options.chunkManager, - options.credentialsManager, - options.url, - ); - const modelSpace = makeCoordinateSpace({ - rank: 3, - names: ["x", "y", "z"], - units: ["m", "m", "m"], - scales: Float64Array.of(1e-9, 1e-9, 1e-9), - }); - const dataSource: DataSource = { - modelTransform: makeIdentityTransform(modelSpace), - subsources: [ - { - id: "default", - default: true, - subsource: { singleMesh: meshSource }, - }, - ], - }; - return dataSource; - } - completeUrl(options: CompleteUrlOptions) { - return completeHttpPath( - options.credentialsManager, - options.providerUrl, - options.cancellationToken, - ); - } -} diff --git a/src/datasource/obj/register_default.ts b/src/datasource/obj/register_default.ts index 7f846e4743..b7a9b56ec3 100644 --- a/src/datasource/obj/register_default.ts +++ b/src/datasource/obj/register_default.ts @@ -14,7 +14,13 @@ * limitations under the License. */ -import { registerProvider } from "#src/datasource/default_provider.js"; -import { ObjDataSource } from "#src/datasource/obj/frontend.js"; +import { + registerKvStoreBasedDataProvider, + registerProvider, +} from "#src/datasource/default_provider.js"; +import { KvStoreBasedDataSourceLegacyUrlAdapter } from "#src/datasource/index.js"; +import { SingleMeshDataSource } from "#src/single_mesh/frontend.js"; -registerProvider("obj", () => new ObjDataSource()); +const provider = new SingleMeshDataSource("obj", "Wavefront OBJ mesh"); +registerKvStoreBasedDataProvider(provider); +registerProvider(new KvStoreBasedDataSourceLegacyUrlAdapter(provider)); diff --git a/src/datasource/precomputed/async_computation.ts b/src/datasource/precomputed/async_computation.ts index e6b6457a4f..16f6033b9a 100644 --- a/src/datasource/precomputed/async_computation.ts +++ b/src/datasource/precomputed/async_computation.ts @@ -1,5 +1,4 @@ import "#src/async_computation/decode_jpeg.js"; import "#src/async_computation/decode_jxl.js"; -import "#src/async_computation/decode_gzip.js"; import "#src/async_computation/decode_compresso.js"; import "#src/async_computation/decode_png.js"; diff --git a/src/datasource/precomputed/backend.ts b/src/datasource/precomputed/backend.ts index ac308f0db0..4bf3912530 100644 --- a/src/datasource/precomputed/backend.ts +++ b/src/datasource/precomputed/backend.ts @@ -30,25 +30,24 @@ import { annotationTypeHandlers, annotationTypes, } from "#src/annotation/index.js"; -import { decodeGzip } from "#src/async_computation/decode_gzip_request.js"; -import { requestAsyncComputation } from "#src/async_computation/request.js"; -import type { Chunk, ChunkManager } from "#src/chunk_manager/backend.js"; import { WithParameters } from "#src/chunk_manager/backend.js"; -import { GenericSharedDataSource } from "#src/chunk_manager/generic_file_source.js"; -import { WithSharedCredentialsProviderCounterpart } from "#src/credentials_provider/shared_counterpart.js"; -import type { ShardingParameters } from "#src/datasource/precomputed/base.js"; import { AnnotationSourceParameters, AnnotationSpatialIndexSourceParameters, - DataEncoding, - IndexedSegmentPropertySourceParameters, MeshSourceParameters, MultiscaleMeshSourceParameters, - ShardingHashFunction, SkeletonSourceParameters, VolumeChunkEncoding, VolumeChunkSourceParameters, } from "#src/datasource/precomputed/base.js"; +import type { + ShardedKvStore, + ShardInfo, +} from "#src/datasource/precomputed/sharded.js"; +import { getShardedKvStoreIfApplicable } from "#src/datasource/precomputed/sharded.js"; +import { WithSharedKvStoreContextCounterpart } from "#src/kvstore/backend.js"; +import type { KvStoreWithPath, ReadResponse } from "#src/kvstore/index.js"; +import { readKvStore } from "#src/kvstore/index.js"; import type { FragmentChunk, ManifestChunk, @@ -66,7 +65,6 @@ import { MultiscaleMeshSource, } from "#src/mesh/backend.js"; import { decodeDracoPartitioned } from "#src/mesh/draco/index.js"; -import { IndexedSegmentPropertySourceBackend } from "#src/segmentation_display_state/backend.js"; import type { SkeletonChunk } from "#src/skeleton/backend.js"; import { SkeletonSource } from "#src/skeleton/backend.js"; import { decodeSkeletonChunk } from "#src/skeleton/decode_precomputed_skeleton.js"; @@ -79,24 +77,8 @@ import { decodePngChunk } from "#src/sliceview/backend_chunk_decoders/png.js"; import { decodeRawChunk } from "#src/sliceview/backend_chunk_decoders/raw.js"; import type { VolumeChunk } from "#src/sliceview/volume/backend.js"; import { VolumeChunkSource } from "#src/sliceview/volume/backend.js"; -import { fetchSpecialHttpByteRange } from "#src/util/byte_range_http_requests.js"; -import type { CancellationToken } from "#src/util/cancellation.js"; -import type { Borrowed } from "#src/util/disposable.js"; import { convertEndian32, Endianness } from "#src/util/endian.js"; import { vec3 } from "#src/util/geom.js"; -import { murmurHash3_x86_128Hash64Bits } from "#src/util/hash.js"; -import { - isNotFoundError, - responseArrayBuffer, - responseJson, -} from "#src/util/http_request.js"; -import { stableStringify } from "#src/util/json.js"; -import { getObjectId } from "#src/util/object_id.js"; -import type { - SpecialProtocolCredentials, - SpecialProtocolCredentialsProvider, -} from "#src/util/special_protocol_request.js"; -import { cancellableFetchSpecialOk } from "#src/util/special_protocol_request.js"; import { Uint64 } from "#src/util/uint64.js"; import { encodeZIndexCompressed, @@ -108,265 +90,6 @@ import { registerSharedObject } from "#src/worker_rpc.js"; // Set to true to validate the multiscale index. const DEBUG_MULTISCALE_INDEX = false; -const shardingHashFunctions: Map void> = - new Map([ - [ - ShardingHashFunction.MURMURHASH3_X86_128, - (out) => { - murmurHash3_x86_128Hash64Bits(out, 0, out.low, out.high); - }, - ], - [ShardingHashFunction.IDENTITY, (_out) => {}], - ]); - -interface ShardInfo { - shardUrl: string; - offset: Uint64; -} - -interface DecodedMinishardIndex { - data: Uint32Array; - shardUrl: string; -} - -interface MinishardIndexSource - extends GenericSharedDataSource { - sharding: ShardingParameters; - credentialsProvider: SpecialProtocolCredentialsProvider; -} - -function getMinishardIndexDataSource( - chunkManager: Borrowed, - credentialsProvider: SpecialProtocolCredentialsProvider, - parameters: { url: string; sharding: ShardingParameters | undefined }, -): MinishardIndexSource | undefined { - const { url, sharding } = parameters; - if (sharding === undefined) return undefined; - const source = GenericSharedDataSource.get< - Uint64, - DecodedMinishardIndex | undefined - >( - chunkManager, - stableStringify({ - type: "precomputed:shardedDataSource", - url, - sharding, - credentialsProvider: getObjectId(credentialsProvider), - }), - { - download: async ( - shardAndMinishard: Uint64, - cancellationToken: CancellationToken, - ) => { - const minishard = Uint64.lowMask(new Uint64(), sharding.minishardBits); - Uint64.and(minishard, minishard, shardAndMinishard); - const shard = Uint64.lowMask(new Uint64(), sharding.shardBits); - const temp = new Uint64(); - Uint64.rshift(temp, shardAndMinishard, sharding.minishardBits); - Uint64.and(shard, shard, temp); - const shardUrl = `${url}/${shard - .toString(16) - .padStart(Math.ceil(sharding.shardBits / 4), "0")}.shard`; - // Retrive minishard index start/end offsets. - const shardIndexSize = new Uint64(16); - Uint64.lshift(shardIndexSize, shardIndexSize, sharding.minishardBits); - - // Multiply minishard by 16. - const shardIndexStart = Uint64.lshift(new Uint64(), minishard, 4); - const shardIndexEnd = Uint64.addUint32( - new Uint64(), - shardIndexStart, - 16, - ); - let shardIndexResponse: ArrayBuffer; - try { - shardIndexResponse = await fetchSpecialHttpByteRange( - credentialsProvider, - shardUrl, - shardIndexStart, - shardIndexEnd, - cancellationToken, - ); - } catch (e) { - if (isNotFoundError(e)) return { data: undefined, size: 0 }; - throw e; - } - if (shardIndexResponse.byteLength !== 16) { - throw new Error("Failed to retrieve minishard offset"); - } - const shardIndexDv = new DataView(shardIndexResponse); - const minishardStartOffset = new Uint64( - shardIndexDv.getUint32(0, /*littleEndian=*/ true), - shardIndexDv.getUint32(4, /*littleEndian=*/ true), - ); - const minishardEndOffset = new Uint64( - shardIndexDv.getUint32(8, /*littleEndian=*/ true), - shardIndexDv.getUint32(12, /*littleEndian=*/ true), - ); - if (Uint64.equal(minishardStartOffset, minishardEndOffset)) { - return { data: undefined, size: 0 }; - } - // The start/end offsets in the shard index are relative to the end of the shard - // index. - Uint64.add(minishardStartOffset, minishardStartOffset, shardIndexSize); - Uint64.add(minishardEndOffset, minishardEndOffset, shardIndexSize); - - let minishardIndexResponse = await fetchSpecialHttpByteRange( - credentialsProvider, - shardUrl, - minishardStartOffset, - minishardEndOffset, - cancellationToken, - ); - if (sharding.minishardIndexEncoding === DataEncoding.GZIP) { - minishardIndexResponse = ( - await requestAsyncComputation( - decodeGzip, - cancellationToken, - [minishardIndexResponse], - new Uint8Array(minishardIndexResponse), - ) - ).buffer; - } - if (minishardIndexResponse.byteLength % 24 !== 0) { - throw new Error( - `Invalid minishard index length: ${minishardIndexResponse.byteLength}`, - ); - } - const minishardIndex = new Uint32Array(minishardIndexResponse); - convertEndian32(minishardIndex, Endianness.LITTLE); - - const minishardIndexSize = minishardIndex.byteLength / 24; - let prevEntryKeyLow = 0; - let prevEntryKeyHigh = 0; - // Offsets in the minishard index are relative to the end of the shard index. - let prevStartLow = shardIndexSize.low; - let prevStartHigh = shardIndexSize.high; - for (let i = 0; i < minishardIndexSize; ++i) { - let entryKeyLow = prevEntryKeyLow + minishardIndex[i * 2]; - let entryKeyHigh = prevEntryKeyHigh + minishardIndex[i * 2 + 1]; - if (entryKeyLow >= 4294967296) { - entryKeyLow -= 4294967296; - entryKeyHigh += 1; - } - prevEntryKeyLow = minishardIndex[i * 2] = entryKeyLow; - prevEntryKeyHigh = minishardIndex[i * 2 + 1] = entryKeyHigh; - let startLow = - prevStartLow + minishardIndex[(minishardIndexSize + i) * 2]; - let startHigh = - prevStartHigh + minishardIndex[(minishardIndexSize + i) * 2 + 1]; - if (startLow >= 4294967296) { - startLow -= 4294967296; - startHigh += 1; - } - minishardIndex[(minishardIndexSize + i) * 2] = startLow; - minishardIndex[(minishardIndexSize + i) * 2 + 1] = startHigh; - const sizeLow = minishardIndex[(2 * minishardIndexSize + i) * 2]; - const sizeHigh = minishardIndex[(2 * minishardIndexSize + i) * 2 + 1]; - let endLow = startLow + sizeLow; - let endHigh = startHigh + sizeHigh; - if (endLow >= 4294967296) { - endLow -= 4294967296; - endHigh += 1; - } - prevStartLow = endLow; - prevStartHigh = endHigh; - minishardIndex[(2 * minishardIndexSize + i) * 2] = endLow; - minishardIndex[(2 * minishardIndexSize + i) * 2 + 1] = endHigh; - } - return { - data: { data: minishardIndex, shardUrl }, - size: minishardIndex.byteLength, - }; - }, - encodeKey: (key: Uint64) => key.toString(), - sourceQueueLevel: 1, - }, - ) as MinishardIndexSource; - source.sharding = sharding; - source.credentialsProvider = credentialsProvider; - return source; -} - -function findMinishardEntry( - minishardIndex: DecodedMinishardIndex, - key: Uint64, -): { startOffset: Uint64; endOffset: Uint64 } | undefined { - const minishardIndexData = minishardIndex.data; - const minishardIndexSize = minishardIndexData.length / 6; - const keyLow = key.low; - const keyHigh = key.high; - for (let i = 0; i < minishardIndexSize; ++i) { - if ( - minishardIndexData[i * 2] !== keyLow || - minishardIndexData[i * 2 + 1] !== keyHigh - ) { - continue; - } - const startOffset = new Uint64( - minishardIndexData[(minishardIndexSize + i) * 2], - minishardIndexData[(minishardIndexSize + i) * 2 + 1], - ); - const endOffset = new Uint64( - minishardIndexData[(2 * minishardIndexSize + i) * 2], - minishardIndexData[(2 * minishardIndexSize + i) * 2 + 1], - ); - return { startOffset, endOffset }; - } - return undefined; -} - -async function getShardedData( - minishardIndexSource: MinishardIndexSource, - chunk: Chunk, - key: Uint64, - cancellationToken: CancellationToken, -): Promise<{ shardInfo: ShardInfo; data: ArrayBuffer } | undefined> { - const { sharding } = minishardIndexSource; - const hashFunction = shardingHashFunctions.get(sharding.hash)!; - const hashCode = Uint64.rshift(new Uint64(), key, sharding.preshiftBits); - hashFunction(hashCode); - const shardAndMinishard = Uint64.lowMask( - new Uint64(), - sharding.minishardBits + sharding.shardBits, - ); - Uint64.and(shardAndMinishard, shardAndMinishard, hashCode); - const getPriority = () => ({ - priorityTier: chunk.priorityTier, - priority: chunk.priority, - }); - const minishardIndex = await minishardIndexSource.getData( - shardAndMinishard, - getPriority, - cancellationToken, - ); - if (minishardIndex === undefined) return undefined; - const minishardEntry = findMinishardEntry(minishardIndex, key); - if (minishardEntry === undefined) return undefined; - const { startOffset, endOffset } = minishardEntry; - let data = await fetchSpecialHttpByteRange( - minishardIndexSource.credentialsProvider, - minishardIndex.shardUrl, - startOffset, - endOffset, - cancellationToken, - ); - if (minishardIndexSource.sharding.dataEncoding === DataEncoding.GZIP) { - data = ( - await requestAsyncComputation( - decodeGzip, - cancellationToken, - [data], - new Uint8Array(data), - ) - ).buffer; - } - return { - data, - shardInfo: { shardUrl: minishardIndex.shardUrl, offset: startOffset }, - }; -} - function getOrNotFoundError(v: T | undefined) { if (v === undefined) throw new Error("not found"); return v; @@ -385,16 +108,17 @@ chunkDecoders.set(VolumeChunkEncoding.JXL, decodeJxlChunk); @registerSharedObject() export class PrecomputedVolumeChunkSource extends WithParameters( - WithSharedCredentialsProviderCounterpart()( - VolumeChunkSource, - ), + WithSharedKvStoreContextCounterpart(VolumeChunkSource), VolumeChunkSourceParameters, ) { chunkDecoder = chunkDecoders.get(this.parameters.encoding)!; - private minishardIndexSource = getMinishardIndexDataSource( - this.chunkManager, - this.credentialsProvider, - this.parameters, + kvStore = this.sharedKvStoreContext.kvStoreContext.getKvStore( + this.parameters.url, + ); + shardedKvStore = getShardedKvStoreIfApplicable( + this, + this.kvStore, + this.parameters.sharding, ); gridShape = (() => { @@ -406,43 +130,25 @@ export class PrecomputedVolumeChunkSource extends WithParameters( return gridShape; })(); - async download( - chunk: VolumeChunk, - cancellationToken: CancellationToken, - ): Promise { - const { parameters } = this; - - const { minishardIndexSource } = this; - let response: ArrayBuffer | undefined; - if (minishardIndexSource === undefined) { - let url: string; + async download(chunk: VolumeChunk, signal: AbortSignal): Promise { + const { shardedKvStore } = this; + let readResponse: ReadResponse | undefined; + if (shardedKvStore === undefined) { + const { kvStore } = this; + let path: string; { // chunkPosition must not be captured, since it will be invalidated by the next call to // computeChunkBounds. const chunkPosition = this.computeChunkBounds(chunk); const chunkDataSize = chunk.chunkDataSize!; - url = - `${parameters.url}/${chunkPosition[0]}-${ + path = + `${kvStore.path}${chunkPosition[0]}-${ chunkPosition[0] + chunkDataSize[0] }_` + `${chunkPosition[1]}-${chunkPosition[1] + chunkDataSize[1]}_` + `${chunkPosition[2]}-${chunkPosition[2] + chunkDataSize[2]}`; } - try { - response = await cancellableFetchSpecialOk( - this.credentialsProvider, - url, - {}, - responseArrayBuffer, - cancellationToken, - ); - } catch (e) { - if (isNotFoundError(e)) { - response = undefined; - } else { - throw e; - } - } + readResponse = await kvStore.store.read(path, { signal }); } else { this.computeChunkBounds(chunk); const { gridShape } = this; @@ -451,7 +157,6 @@ export class PrecomputedVolumeChunkSource extends WithParameters( const yBits = Math.ceil(Math.log2(gridShape[1])); const zBits = Math.ceil(Math.log2(gridShape[2])); const chunkIndex = encodeZIndexCompressed3d( - new Uint64(), xBits, yBits, zBits, @@ -459,17 +164,14 @@ export class PrecomputedVolumeChunkSource extends WithParameters( chunkGridPosition[1], chunkGridPosition[2], ); - response = ( - await getShardedData( - minishardIndexSource, - chunk, - chunkIndex, - cancellationToken, - ) - )?.data; + readResponse = await shardedKvStore.read(chunkIndex, { signal }); } - if (response !== undefined) { - await this.chunkDecoder(chunk, cancellationToken, response); + if (readResponse !== undefined) { + await this.chunkDecoder( + chunk, + signal, + await readResponse.response.arrayBuffer(), + ); } } } @@ -497,36 +199,30 @@ export function decodeFragmentChunk( @registerSharedObject() export class PrecomputedMeshSource extends WithParameters( - WithSharedCredentialsProviderCounterpart()( - MeshSource, - ), + WithSharedKvStoreContextCounterpart(MeshSource), MeshSourceParameters, ) { - async download(chunk: ManifestChunk, cancellationToken: CancellationToken) { - const { parameters } = this; - const response = await cancellableFetchSpecialOk( - this.credentialsProvider, - `${parameters.url}/${chunk.objectId}:${parameters.lod}`, - {}, - responseJson, - cancellationToken, + kvStore = this.sharedKvStoreContext.kvStoreContext.getKvStore( + this.parameters.url, + ); + async download(chunk: ManifestChunk, signal: AbortSignal) { + const { parameters, kvStore } = this; + const response = await readKvStore( + kvStore.store, + `${kvStore.path}${chunk.objectId}:${parameters.lod}`, + { signal, throwIfMissing: true }, ); - decodeManifestChunk(chunk, response); + decodeManifestChunk(chunk, await response.response.json()); } - async downloadFragment( - chunk: FragmentChunk, - cancellationToken: CancellationToken, - ) { - const { parameters } = this; - const response = await cancellableFetchSpecialOk( - this.credentialsProvider, - `${parameters.url}/${chunk.fragmentId}`, - {}, - responseArrayBuffer, - cancellationToken, + async downloadFragment(chunk: FragmentChunk, signal: AbortSignal) { + const { kvStore } = this; + const response = await readKvStore( + kvStore.store, + `${kvStore.path}${chunk.fragmentId}`, + { signal, throwIfMissing: true }, ); - decodeFragmentChunk(chunk, response); + decodeFragmentChunk(chunk, await response.response.arrayBuffer()); } } @@ -774,152 +470,128 @@ async function decodeMultiscaleFragmentChunk( @registerSharedObject() // export class PrecomputedMultiscaleMeshSource extends WithParameters( - WithSharedCredentialsProviderCounterpart()( - MultiscaleMeshSource, - ), + WithSharedKvStoreContextCounterpart(MultiscaleMeshSource), MultiscaleMeshSourceParameters, ) { - private minishardIndexSource = getMinishardIndexDataSource( - this.chunkManager, - this.credentialsProvider, - { url: this.parameters.url, sharding: this.parameters.metadata.sharding }, + kvStore = this.sharedKvStoreContext.kvStoreContext.getKvStore( + this.parameters.url, + ); + shardedKvStore = getShardedKvStoreIfApplicable( + this, + this.kvStore, + this.parameters.metadata.sharding, ); async download( chunk: PrecomputedMultiscaleManifestChunk, - cancellationToken: CancellationToken, + signal: AbortSignal, ): Promise { - const { parameters, minishardIndexSource } = this; - let data: ArrayBuffer; - if (minishardIndexSource === undefined) { - data = await cancellableFetchSpecialOk( - this.credentialsProvider, - `${parameters.url}/${chunk.objectId}.index`, - {}, - responseArrayBuffer, - cancellationToken, + const { shardedKvStore } = this; + let readResponse: ReadResponse | undefined; + if (shardedKvStore === undefined) { + const { kvStore } = this; + readResponse = await kvStore.store.read( + `${kvStore.path}${chunk.objectId}.index`, + { signal }, ); } else { - ({ data, shardInfo: chunk.shardInfo } = getOrNotFoundError( - await getShardedData( - minishardIndexSource, - chunk, - chunk.objectId, - cancellationToken, - ), - )); + ({ response: readResponse, shardInfo: chunk.shardInfo } = + getOrNotFoundError( + await shardedKvStore.readWithShardInfo(chunk.objectId.toBigInt(), { + signal, + }), + )); } + + const data = await getOrNotFoundError(readResponse).response.arrayBuffer(); + decodeMultiscaleManifestChunk(chunk, data); } async downloadFragment( chunk: MultiscaleFragmentChunk, - cancellationToken: CancellationToken, + signal: AbortSignal, ): Promise { - const { parameters } = this; + const { kvStore } = this; const manifestChunk = chunk.manifestChunk! as PrecomputedMultiscaleManifestChunk; const chunkIndex = chunk.chunkIndex; const { shardInfo, offsets } = manifestChunk; const startOffset = offsets[chunkIndex]; const endOffset = offsets[chunkIndex + 1]; - let requestUrl: string; - let adjustedStartOffset: Uint64 | number; - let adjustedEndOffset: Uint64 | number; + let requestPath: string; + let adjustedStartOffset: number; + let adjustedEndOffset: number; if (shardInfo !== undefined) { - requestUrl = shardInfo.shardUrl; + requestPath = shardInfo.shardPath; const fullDataSize = offsets[offsets.length - 1]; - let startLow = shardInfo.offset.low - fullDataSize + startOffset; - let startHigh = shardInfo.offset.high; - let endLow = startLow + endOffset - startOffset; - let endHigh = startHigh; - while (startLow < 0) { - startLow += 4294967296; - startHigh -= 1; - } - while (endLow < 0) { - endLow += 4294967296; - endHigh -= 1; - } - while (endLow > 4294967296) { - endLow -= 4294967296; - endHigh += 1; - } - adjustedStartOffset = new Uint64(startLow, startHigh); - adjustedEndOffset = new Uint64(endLow, endHigh); + const start = shardInfo.offset - fullDataSize + startOffset; + const end = start + endOffset - startOffset; + adjustedStartOffset = start; + adjustedEndOffset = end; } else { - requestUrl = `${parameters.url}/${manifestChunk.objectId}`; + requestPath = `${kvStore.path}${manifestChunk.objectId}`; adjustedStartOffset = startOffset; adjustedEndOffset = endOffset; } - const response = await fetchSpecialHttpByteRange( - this.credentialsProvider, - requestUrl, - adjustedStartOffset, - adjustedEndOffset, - cancellationToken, + const readResponse = await readKvStore(kvStore.store, requestPath, { + signal, + byteRange: { + offset: adjustedStartOffset, + length: adjustedEndOffset - adjustedStartOffset, + }, + throwIfMissing: true, + strictByteRange: true, + }); + await decodeMultiscaleFragmentChunk( + chunk, + await readResponse.response.arrayBuffer(), ); - await decodeMultiscaleFragmentChunk(chunk, response); } } async function fetchByUint64( - credentialsProvider: SpecialProtocolCredentialsProvider, - url: string, - chunk: Chunk, - minishardIndexSource: MinishardIndexSource | undefined, + chunkSource: { + kvStore: KvStoreWithPath; + shardedKvStore: ShardedKvStore | undefined; + }, id: Uint64, - cancellationToken: CancellationToken, -) { - if (minishardIndexSource === undefined) { - try { - return await cancellableFetchSpecialOk( - credentialsProvider, - `${url}/${id}`, - {}, - responseArrayBuffer, - cancellationToken, - ); - } catch (e) { - if (isNotFoundError(e)) return undefined; - throw e; - } + signal: AbortSignal, +): Promise { + const { shardedKvStore } = chunkSource; + if (shardedKvStore === undefined) { + const { kvStore } = chunkSource; + return kvStore.store.read(`${kvStore.path}${id}`, { + signal, + }); + } else { + return shardedKvStore.read(id.toBigInt(), { signal }); } - const result = await getShardedData( - minishardIndexSource, - chunk, - id, - cancellationToken, - ); - if (result === undefined) return undefined; - return result.data; } @registerSharedObject() // export class PrecomputedSkeletonSource extends WithParameters( - WithSharedCredentialsProviderCounterpart()( - SkeletonSource, - ), + WithSharedKvStoreContextCounterpart(SkeletonSource), SkeletonSourceParameters, ) { - private minishardIndexSource = getMinishardIndexDataSource( - this.chunkManager, - this.credentialsProvider, - { url: this.parameters.url, sharding: this.parameters.metadata.sharding }, + kvStore = this.sharedKvStoreContext.kvStoreContext.getKvStore( + this.parameters.url, + ); + shardedKvStore = getShardedKvStoreIfApplicable( + this, + this.kvStore, + this.parameters.metadata.sharding, ); - async download(chunk: SkeletonChunk, cancellationToken: CancellationToken) { + async download(chunk: SkeletonChunk, signal: AbortSignal) { const { parameters } = this; const response = getOrNotFoundError( - await fetchByUint64( - this.credentialsProvider, - parameters.url, - chunk, - this.minishardIndexSource, - chunk.objectId, - cancellationToken, - ), + await fetchByUint64(this, chunk.objectId, signal), + ); + decodeSkeletonChunk( + chunk, + await response.response.arrayBuffer(), + parameters.metadata.vertexAttributes, ); - decodeSkeletonChunk(chunk, response, parameters.metadata.vertexAttributes); } } @@ -950,7 +622,7 @@ function parseAnnotations( } const geometryData = new AnnotationGeometryData(); const origData = new Uint8Array(buffer, 8, numBytes * countLow); - let data: Uint8Array; + let data: Uint8Array; const { propertyGroupBytes } = propertySerializer; if (propertyGroupBytes.length > 1) { // Need to transpose the property data. @@ -1062,59 +734,39 @@ function parseSingleAnnotation( @registerSharedObject() // export class PrecomputedAnnotationSpatialIndexSourceBackend extends WithParameters( - WithSharedCredentialsProviderCounterpart()( - AnnotationGeometryChunkSourceBackend, - ), + WithSharedKvStoreContextCounterpart(AnnotationGeometryChunkSourceBackend), AnnotationSpatialIndexSourceParameters, ) { - private minishardIndexSource = getMinishardIndexDataSource( - this.chunkManager, - this.credentialsProvider, - this.parameters, + kvStore = this.sharedKvStoreContext.kvStoreContext.getKvStore( + this.parameters.url, ); - parent: PrecomputedAnnotationSourceBackend; - async download( - chunk: AnnotationGeometryChunk, - cancellationToken: CancellationToken, - ) { - const { parameters } = this; - - const { minishardIndexSource } = this; + shardedKvStore = getShardedKvStoreIfApplicable( + this, + this.kvStore, + this.parameters.sharding, + ); + declare parent: PrecomputedAnnotationSourceBackend; + async download(chunk: AnnotationGeometryChunk, signal: AbortSignal) { + const { shardedKvStore } = this; const { parent } = this; - let response: ArrayBuffer | undefined; + let response: ReadResponse | undefined; const { chunkGridPosition } = chunk; - if (minishardIndexSource === undefined) { - const url = `${parameters.url}/${chunkGridPosition.join("_")}`; - try { - response = await cancellableFetchSpecialOk( - this.credentialsProvider, - url, - {}, - responseArrayBuffer, - cancellationToken, - ); - } catch (e) { - if (!isNotFoundError(e)) throw e; - } + if (shardedKvStore === undefined) { + const { kvStore } = this; + const path = `${kvStore.path}${chunkGridPosition.join("_")}`; + response = await kvStore.store.read(path, { signal }); } else { const { upperChunkBound } = this.spec; const { chunkGridPosition } = chunk; const chunkIndex = encodeZIndexCompressed( - new Uint64(), chunkGridPosition, upperChunkBound, ); - const result = await getShardedData( - minishardIndexSource, - chunk, - chunkIndex, - cancellationToken, - ); - if (result !== undefined) response = result.data; + response = await shardedKvStore.read(chunkIndex, { signal }); } if (response !== undefined) { chunk.data = parseAnnotations( - response, + await response.response.arrayBuffer(), parent.parameters, parent.annotationPropertySerializer, ); @@ -1124,19 +776,26 @@ export class PrecomputedAnnotationSpatialIndexSourceBackend extends WithParamete @registerSharedObject() // export class PrecomputedAnnotationSourceBackend extends WithParameters( - WithSharedCredentialsProviderCounterpart()( - AnnotationSource, - ), + WithSharedKvStoreContextCounterpart(AnnotationSource), AnnotationSourceParameters, ) { - private byIdMinishardIndexSource = getMinishardIndexDataSource( - this.chunkManager, - this.credentialsProvider, - this.parameters.byId, + kvStore = this.sharedKvStoreContext.kvStoreContext.getKvStore( + this.parameters.byId.url, ); - private relationshipIndexSource = this.parameters.relationships.map((x) => - getMinishardIndexDataSource(this.chunkManager, this.credentialsProvider, x), + shardedKvStore = getShardedKvStoreIfApplicable( + this, + this.kvStore, + this.parameters.byId.sharding, ); + private relationshipIndexSource = this.parameters.relationships.map((x) => { + const kvStore = this.sharedKvStoreContext.kvStoreContext.getKvStore(x.url); + const shardedKvStore = getShardedKvStoreIfApplicable( + this, + kvStore, + x.sharding, + ); + return { kvStore, shardedKvStore }; + }); annotationPropertySerializer = new AnnotationPropertySerializer( this.parameters.rank, annotationTypeHandlers[this.parameters.type].serializedBytes( @@ -1148,45 +807,30 @@ export class PrecomputedAnnotationSourceBackend extends WithParameters( async downloadSegmentFilteredGeometry( chunk: AnnotationSubsetGeometryChunk, relationshipIndex: number, - cancellationToken: CancellationToken, + signal: AbortSignal, ) { - const { parameters } = this; const response = await fetchByUint64( - this.credentialsProvider, - parameters.relationships[relationshipIndex].url, - chunk, this.relationshipIndexSource[relationshipIndex], chunk.objectId, - cancellationToken, + signal, ); if (response !== undefined) { chunk.data = parseAnnotations( - response, + await response.response.arrayBuffer(), this.parameters, this.annotationPropertySerializer, ); } } - async downloadMetadata( - chunk: AnnotationMetadataChunk, - cancellationToken: CancellationToken, - ) { - const { parameters } = this; + async downloadMetadata(chunk: AnnotationMetadataChunk, signal: AbortSignal) { const id = Uint64.parseString(chunk.key!); - const response = await fetchByUint64( - this.credentialsProvider, - parameters.byId.url, - chunk, - this.byIdMinishardIndexSource, - id, - cancellationToken, - ); + const response = await fetchByUint64(this, id, signal); if (response === undefined) { chunk.annotation = null; } else { chunk.annotation = parseSingleAnnotation( - response, + await response.response.arrayBuffer(), this.parameters, this.annotationPropertySerializer, chunk.key!, @@ -1194,17 +838,3 @@ export class PrecomputedAnnotationSourceBackend extends WithParameters( } } } - -@registerSharedObject() -export class PrecomputedIndexedSegmentPropertySourceBackend extends WithParameters( - WithSharedCredentialsProviderCounterpart()( - IndexedSegmentPropertySourceBackend, - ), - IndexedSegmentPropertySourceParameters, -) { - minishardIndexSource = getMinishardIndexDataSource( - this.chunkManager, - this.credentialsProvider, - this.parameters, - ); -} diff --git a/src/datasource/precomputed/frontend.ts b/src/datasource/precomputed/frontend.ts index 3ee7808d4b..69393aca7e 100644 --- a/src/datasource/precomputed/frontend.ts +++ b/src/datasource/precomputed/frontend.ts @@ -37,16 +37,15 @@ import { makeIdentityTransform, makeIdentityTransformedBoundingBox, } from "#src/coordinate_transform.js"; -import { WithCredentialsProvider } from "#src/credentials_provider/chunk_source_frontend.js"; -import type { - CompleteUrlOptions, - ConvertLegacyUrlOptions, - DataSource, - DataSubsourceEntry, - GetDataSourceOptions, - NormalizeUrlOptions, +import { + KvStoreBasedDataSourceLegacyUrlAdapter, + type ConvertLegacyUrlOptions, + type DataSource, + type DataSourceLookupResult, + type DataSubsourceEntry, + type GetKvStoreBasedDataSourceOptions, + type KvStoreBasedDataSourceProvider, } from "#src/datasource/index.js"; -import { DataSourceProvider, RedirectError } from "#src/datasource/index.js"; import type { MultiscaleMeshMetadata, ShardingParameters, @@ -56,7 +55,6 @@ import { AnnotationSourceParameters, AnnotationSpatialIndexSourceParameters, DataEncoding, - IndexedSegmentPropertySourceParameters, MeshSourceParameters, MultiscaleMeshSourceParameters, ShardingHashFunction, @@ -64,6 +62,16 @@ import { VolumeChunkEncoding, VolumeChunkSourceParameters, } from "#src/datasource/precomputed/base.js"; +import type { AutoDetectRegistry } from "#src/kvstore/auto_detect.js"; +import { simpleFilePresenceAutoDetectDirectorySpec } from "#src/kvstore/auto_detect.js"; +import { WithSharedKvStoreContext } from "#src/kvstore/chunk_source_frontend.js"; +import type { KvStoreContext } from "#src/kvstore/context.js"; +import type { SharedKvStoreContext } from "#src/kvstore/frontend.js"; +import { + kvstoreEnsureDirectoryPipelineUrl, + parseUrlSuffix, + pipelineUrlJoin, +} from "#src/kvstore/url.js"; import { VertexPositionFormat } from "#src/mesh/base.js"; import { MeshSource, MultiscaleMeshSource } from "#src/mesh/frontend.js"; import type { @@ -71,7 +79,6 @@ import type { InlineSegmentPropertyMap, } from "#src/segmentation_display_state/property_map.js"; import { - IndexedSegmentPropertySource, normalizeInlineSegmentPropertyMap, SegmentPropertyMap, } from "#src/segmentation_display_state/property_map.js"; @@ -90,10 +97,7 @@ import { } from "#src/sliceview/volume/frontend.js"; import { transposeNestedArrays } from "#src/util/array.js"; import { DATA_TYPE_ARRAY_CONSTRUCTOR, DataType } from "#src/util/data_type.js"; -import type { Borrowed } from "#src/util/disposable.js"; import { mat4, vec3 } from "#src/util/geom.js"; -import { completeHttpPath } from "#src/util/http_path_completion.js"; -import { isNotFoundError, responseJson } from "#src/util/http_request.js"; import { parseArray, parseFixedLengthArray, @@ -113,34 +117,27 @@ import { verifyOptionalBoolean, } from "#src/util/json.js"; import * as matrix from "#src/util/matrix.js"; -import { getObjectId } from "#src/util/object_id.js"; -import type { - SpecialProtocolCredentials, - SpecialProtocolCredentialsProvider, -} from "#src/util/special_protocol_request.js"; -import { - cancellableFetchSpecialOk, - parseSpecialUrl, -} from "#src/util/special_protocol_request.js"; +import type { ProgressOptions } from "#src/util/progress_listener.js"; +import { ProgressSpan } from "#src/util/progress_listener.js"; import { Uint64 } from "#src/util/uint64.js"; export class PrecomputedVolumeChunkSource extends WithParameters( - WithCredentialsProvider()(VolumeChunkSource), + WithSharedKvStoreContext(VolumeChunkSource), VolumeChunkSourceParameters, ) {} class PrecomputedMeshSource extends WithParameters( - WithCredentialsProvider()(MeshSource), + WithSharedKvStoreContext(MeshSource), MeshSourceParameters, ) {} class PrecomputedMultiscaleMeshSource extends WithParameters( - WithCredentialsProvider()(MultiscaleMeshSource), + WithSharedKvStoreContext(MultiscaleMeshSource), MultiscaleMeshSourceParameters, ) {} class PrecomputedSkeletonSource extends WithParameters( - WithCredentialsProvider()(SkeletonSource), + WithSharedKvStoreContext(SkeletonSource), SkeletonSourceParameters, ) { get skeletonVertexCoordinatesInVoxels() { @@ -151,20 +148,6 @@ class PrecomputedSkeletonSource extends WithParameters( } } -export function resolvePath(a: string, b: string) { - const outputParts = a.split("/"); - for (const part of b.split("/")) { - if (part === "..") { - if (outputParts.length !== 0) { - outputParts.length = outputParts.length - 1; - continue; - } - } - outputParts.push(part); - } - return outputParts.join("/"); -} - class ScaleInfo { key: string; encoding: VolumeChunkEncoding; @@ -325,12 +308,11 @@ export class PrecomputedMultiscaleVolumeChunkSource extends MultiscaleVolumeChun } constructor( - chunkManager: ChunkManager, - public credentialsProvider: SpecialProtocolCredentialsProvider, + public sharedKvStoreContext: SharedKvStoreContext, public url: string, public info: MultiscaleVolumeInfo, ) { - super(chunkManager); + super(sharedKvStoreContext.chunkManager); } getSources(volumeSourceOptions: VolumeSourceOptions) { @@ -380,10 +362,15 @@ export class PrecomputedMultiscaleVolumeChunkSource extends MultiscaleVolumeChun chunkSource: this.chunkManager.getChunkSource( PrecomputedVolumeChunkSource, { - credentialsProvider: this.credentialsProvider, + sharedKvStoreContext: this.sharedKvStoreContext, spec, parameters: { - url: resolvePath(this.url, scaleInfo.key), + url: kvstoreEnsureDirectoryPipelineUrl( + this.sharedKvStoreContext.kvStoreContext.resolveRelativePath( + this.url, + scaleInfo.key, + ), + ), encoding: scaleInfo.encoding, sharding: scaleInfo.sharding, }, @@ -400,30 +387,25 @@ export class PrecomputedMultiscaleVolumeChunkSource extends MultiscaleVolumeChun } const MultiscaleAnnotationSourceBase = WithParameters( - WithCredentialsProvider()( - MultiscaleAnnotationSource, - ), + WithSharedKvStoreContext(MultiscaleAnnotationSource), AnnotationSourceParameters, ); class PrecomputedAnnotationSpatialIndexSource extends WithParameters( - WithCredentialsProvider()( - AnnotationGeometryChunkSource, - ), + WithSharedKvStoreContext(AnnotationGeometryChunkSource), AnnotationSpatialIndexSourceParameters, ) {} interface PrecomputedAnnotationSourceOptions { metadata: AnnotationMetadata; parameters: AnnotationSourceParameters; - credentialsProvider: SpecialProtocolCredentialsProvider; + sharedKvStoreContext: SharedKvStoreContext; } export class PrecomputedAnnotationSource extends MultiscaleAnnotationSourceBase { - key: any; + declare key: any; metadata: AnnotationMetadata; - credentialsProvider: SpecialProtocolCredentialsProvider; - OPTIONS: PrecomputedAnnotationSourceOptions; + declare OPTIONS: PrecomputedAnnotationSourceOptions; constructor( chunkManager: ChunkManager, options: PrecomputedAnnotationSourceOptions, @@ -433,11 +415,11 @@ export class PrecomputedAnnotationSource extends MultiscaleAnnotationSourceBase rank: parameters.rank, relationships: parameters.relationships.map((x) => x.name), properties: parameters.properties, + sharedKvStoreContext: options.sharedKvStoreContext, parameters, } as any); this.readonly = true; this.metadata = options.metadata; - this.credentialsProvider = options.credentialsProvider; } getSources(): SliceViewSingleResolutionSource[][] { @@ -448,7 +430,7 @@ export class PrecomputedAnnotationSource extends MultiscaleAnnotationSourceBase chunkSource: this.chunkManager.getChunkSource( PrecomputedAnnotationSpatialIndexSource, { - credentialsProvider: this.credentialsProvider, + sharedKvStoreContext: this.sharedKvStoreContext, parent: this, spec, parameters: spatialIndexLevel.parameters, @@ -462,14 +444,16 @@ export class PrecomputedAnnotationSource extends MultiscaleAnnotationSourceBase } function getLegacyMeshSource( - chunkManager: ChunkManager, - credentialsProvider: SpecialProtocolCredentialsProvider, + sharedKvStoreContext: SharedKvStoreContext, parameters: MeshSourceParameters, ) { - return chunkManager.getChunkSource(PrecomputedMeshSource, { - parameters, - credentialsProvider, - }); + return sharedKvStoreContext.chunkManager.getChunkSource( + PrecomputedMeshSource, + { + parameters, + sharedKvStoreContext, + }, + ); } function parseTransform(data: any): mat4 { @@ -533,20 +517,20 @@ function parseMeshMetadata(data: any): ParsedMeshMetadata { } async function getMeshMetadata( - chunkManager: ChunkManager, - credentialsProvider: SpecialProtocolCredentialsProvider, + sharedKvStoreContext: SharedKvStoreContext, url: string, + options: Partial, ): Promise { - let metadata: any; - try { - metadata = await getJsonMetadata(chunkManager, credentialsProvider, url); - } catch (e) { - if (isNotFoundError(e)) { - // If we fail to fetch the info file, assume it is the legacy - // single-resolution mesh format. - return { metadata: undefined }; - } - throw e; + const metadata = await getJsonMetadata( + sharedKvStoreContext, + url, + /*required=*/ false, + options, + ); + if (metadata === undefined) { + // If the info file is missing, assume it is the legacy + // single-resolution mesh format. + return { metadata: undefined }; } return parseMeshMetadata(metadata); } @@ -649,14 +633,15 @@ function parseSkeletonMetadata(data: any): ParsedSkeletonMetadata { } async function getSkeletonMetadata( - chunkManager: ChunkManager, - credentialsProvider: SpecialProtocolCredentialsProvider, + sharedKvStoreContext: SharedKvStoreContext, url: string, + options: Partial, ): Promise { const metadata = await getJsonMetadata( - chunkManager, - credentialsProvider, + sharedKvStoreContext, url, + /*required=*/ true, + options, ); return parseSkeletonMetadata(metadata); } @@ -670,18 +655,18 @@ function getDefaultCoordinateSpace() { } async function getMeshSource( - chunkManager: ChunkManager, - credentialsProvider: SpecialProtocolCredentialsProvider, + sharedKvStoreContext: SharedKvStoreContext, url: string, + options: Partial, ) { const { metadata, segmentPropertyMap } = await getMeshMetadata( - chunkManager, - credentialsProvider, + sharedKvStoreContext, url, + options, ); if (metadata === undefined) { return { - source: getLegacyMeshSource(chunkManager, credentialsProvider, { + source: getLegacyMeshSource(sharedKvStoreContext, { url, lod: 0, }), @@ -701,60 +686,71 @@ async function getMeshSource( ); } return { - source: chunkManager.getChunkSource(PrecomputedMultiscaleMeshSource, { - credentialsProvider, - parameters: { url, metadata }, - format: { - fragmentRelativeVertices: true, - vertexPositionFormat, + source: sharedKvStoreContext.chunkManager.getChunkSource( + PrecomputedMultiscaleMeshSource, + { + sharedKvStoreContext, + parameters: { url, metadata }, + format: { + fragmentRelativeVertices: true, + vertexPositionFormat, + }, }, - }), + ), transform: metadata.transform, segmentPropertyMap, }; } async function getSkeletonSource( - chunkManager: ChunkManager, - credentialsProvider: SpecialProtocolCredentialsProvider, + sharedKvStoreContext: SharedKvStoreContext, url: string, + options: Partial, ) { const { metadata, segmentPropertyMap } = await getSkeletonMetadata( - chunkManager, - credentialsProvider, + sharedKvStoreContext, url, + options, ); return { - source: chunkManager.getChunkSource(PrecomputedSkeletonSource, { - credentialsProvider, - parameters: { - url, - metadata, + source: sharedKvStoreContext.chunkManager.getChunkSource( + PrecomputedSkeletonSource, + { + sharedKvStoreContext, + parameters: { + url, + metadata, + }, }, - }), + ), transform: metadata.transform, segmentPropertyMap, }; } -function getJsonMetadata( - chunkManager: ChunkManager, - credentialsProvider: SpecialProtocolCredentialsProvider, +export function getJsonMetadata( + sharedKvStoreContext: SharedKvStoreContext, url: string, + required: boolean, + options: Partial, ): Promise { - return chunkManager.memoize.getUncounted( + return sharedKvStoreContext.chunkManager.memoize.getAsync( { type: "precomputed:metadata", url, - credentialsProvider: getObjectId(credentialsProvider), }, - async () => { - return await cancellableFetchSpecialOk( - credentialsProvider, - `${url}/info`, - {}, - responseJson, - ); + options, + async (options) => { + const infoUrl = pipelineUrlJoin(url, "info"); + using _span = new ProgressSpan(options.progressListener, { + message: `Reading neuroglancer_precomputed metadata from ${infoUrl}`, + }); + const response = await sharedKvStoreContext.kvStoreContext.read(infoUrl, { + ...options, + throwIfMissing: required, + }); + if (response === undefined) return undefined; + return await response.response.json(); }, ); } @@ -769,15 +765,14 @@ function getSubsourceToModelSubspaceTransform(info: MultiscaleVolumeInfo) { } async function getVolumeDataSource( - options: GetDataSourceOptions, - credentialsProvider: SpecialProtocolCredentialsProvider, + sharedKvStoreContext: SharedKvStoreContext, url: string, metadata: any, + options: Partial, ): Promise { const info = parseMultiscaleVolumeInfo(metadata); const volume = new PrecomputedMultiscaleVolumeChunkSource( - options.chunkManager, - credentialsProvider, + sharedKvStoreContext, url, info, ); @@ -799,18 +794,19 @@ async function getVolumeDataSource( }, ]; if (info.segmentPropertyMap !== undefined) { - const mapUrl = resolvePath(url, info.segmentPropertyMap); - const metadata = await getJsonMetadata( - options.chunkManager, - credentialsProvider, - mapUrl, + const mapUrl = kvstoreEnsureDirectoryPipelineUrl( + sharedKvStoreContext.kvStoreContext.resolveRelativePath( + url, + info.segmentPropertyMap, + ), ); - const segmentPropertyMap = getSegmentPropertyMap( - options.chunkManager, - credentialsProvider, - metadata, + const metadata = await getJsonMetadata( + sharedKvStoreContext, mapUrl, + /*required=*/ true, + options, ); + const segmentPropertyMap = getSegmentPropertyMap(metadata); subsources.push({ id: "properties", default: true, @@ -818,11 +814,13 @@ async function getVolumeDataSource( }); } if (info.mesh !== undefined) { - const meshUrl = resolvePath(url, info.mesh); + const meshUrl = kvstoreEnsureDirectoryPipelineUrl( + sharedKvStoreContext.kvStoreContext.resolveRelativePath(url, info.mesh), + ); const { source: meshSource, transform } = await getMeshSource( - options.chunkManager, - credentialsProvider, + sharedKvStoreContext, meshUrl, + options, ); const subsourceToModelSubspaceTransform = getSubsourceToModelSubspaceTransform(info); @@ -839,11 +837,16 @@ async function getVolumeDataSource( }); } if (info.skeletons !== undefined) { - const skeletonsUrl = resolvePath(url, info.skeletons); + const skeletonsUrl = kvstoreEnsureDirectoryPipelineUrl( + sharedKvStoreContext.kvStoreContext.resolveRelativePath( + url, + info.skeletons, + ), + ); const { source: skeletonSource, transform } = await getSkeletonSource( - options.chunkManager, - credentialsProvider, + sharedKvStoreContext, skeletonsUrl, + options, ); const subsourceToModelSubspaceTransform = getSubsourceToModelSubspaceTransform(info); @@ -863,15 +866,15 @@ async function getVolumeDataSource( } async function getSkeletonsDataSource( - options: GetDataSourceOptions, - credentialsProvider: SpecialProtocolCredentialsProvider, + sharedKvStoreContext: SharedKvStoreContext, url: string, + options: Partial, ): Promise { const { source: skeletons, transform, segmentPropertyMap, - } = await getSkeletonSource(options.chunkManager, credentialsProvider, url); + } = await getSkeletonSource(sharedKvStoreContext, url, options); const subsources: DataSubsourceEntry[] = [ { id: "default", @@ -881,18 +884,19 @@ async function getSkeletonsDataSource( }, ]; if (segmentPropertyMap !== undefined) { - const mapUrl = resolvePath(url, segmentPropertyMap); - const metadata = await getJsonMetadata( - options.chunkManager, - credentialsProvider, - mapUrl, + const mapUrl = kvstoreEnsureDirectoryPipelineUrl( + sharedKvStoreContext.kvStoreContext.resolveRelativePath( + url, + segmentPropertyMap, + ), ); - const segmentPropertyMapData = getSegmentPropertyMap( - options.chunkManager, - credentialsProvider, - metadata, + const metadata = await getJsonMetadata( + sharedKvStoreContext, mapUrl, + /*required=*/ true, + options, ); + const segmentPropertyMapData = getSegmentPropertyMap(metadata); subsources.push({ id: "properties", default: true, @@ -905,10 +909,17 @@ async function getSkeletonsDataSource( }; } -function parseKeyAndShardingSpec(url: string, obj: any) { +function parseKeyAndShardingSpec( + kvStoreContext: KvStoreContext, + url: string, + obj: any, +) { verifyObject(obj); + const relativePath = verifyObjectProperty(obj, "key", verifyString); return { - url: resolvePath(url, verifyObjectProperty(obj, "key", verifyString)), + url: kvstoreEnsureDirectoryPipelineUrl( + kvStoreContext.resolveRelativePath(url, relativePath), + ), sharding: verifyObjectProperty(obj, "sharding", parseShardingParameters), }; } @@ -924,6 +935,7 @@ class AnnotationMetadata { parameters: AnnotationSourceParameters; spatialIndices: AnnotationSpatialIndexLevelMetadata[]; constructor( + kvStoreContext: KvStoreContext, public url: string, metadata: any, ) { @@ -973,7 +985,7 @@ class AnnotationMetadata { "relationships", (relsObj) => parseArray(relsObj, (relObj) => { - const common = parseKeyAndShardingSpec(url, relObj); + const common = parseKeyAndShardingSpec(kvStoreContext, url, relObj); const name = verifyObjectProperty(relObj, "id", verifyString); return { ...common, name }; }), @@ -984,7 +996,7 @@ class AnnotationMetadata { parseAnnotationPropertySpecs, ), byId: verifyObjectProperty(metadata, "by_id", (obj) => - parseKeyAndShardingSpec(url, obj), + parseKeyAndShardingSpec(kvStoreContext, url, obj), ), }; this.spatialIndices = verifyObjectProperty( @@ -993,7 +1005,7 @@ class AnnotationMetadata { (spatialObj) => parseArray(spatialObj, (levelObj) => { const common: AnnotationSpatialIndexSourceParameters = - parseKeyAndShardingSpec(url, levelObj); + parseKeyAndShardingSpec(kvStoreContext, url, levelObj); const gridShape = verifyObjectProperty(levelObj, "grid_shape", (j) => parseFixedLengthArray(new Float32Array(rank), j, verifyPositiveInt), ); @@ -1041,13 +1053,16 @@ class AnnotationMetadata { } } -async function getAnnotationDataSource( - options: GetDataSourceOptions, - credentialsProvider: SpecialProtocolCredentialsProvider, +function getAnnotationDataSource( + sharedKvStoreContext: SharedKvStoreContext, url: string, metadata: any, -): Promise { - const info = new AnnotationMetadata(url, metadata); +): DataSource { + const info = new AnnotationMetadata( + sharedKvStoreContext.kvStoreContext, + url, + metadata, + ); const dataSource: DataSource = { modelTransform: makeIdentityTransform(info.coordinateSpace), subsources: [ @@ -1055,10 +1070,10 @@ async function getAnnotationDataSource( id: "default", default: true, subsource: { - annotation: options.chunkManager.getChunkSource( + annotation: sharedKvStoreContext.chunkManager.getChunkSource( PrecomputedAnnotationSource, { - credentialsProvider, + sharedKvStoreContext, metadata: info, parameters: info.parameters, }, @@ -1071,15 +1086,15 @@ async function getAnnotationDataSource( } async function getMeshDataSource( - options: GetDataSourceOptions, - credentialsProvider: SpecialProtocolCredentialsProvider, + sharedKvStoreContext: SharedKvStoreContext, url: string, + options: Partial, ): Promise { const { source: mesh, transform, segmentPropertyMap, - } = await getMeshSource(options.chunkManager, credentialsProvider, url); + } = await getMeshSource(sharedKvStoreContext, url, options); const subsources: DataSubsourceEntry[] = [ { id: "default", @@ -1089,18 +1104,19 @@ async function getMeshDataSource( }, ]; if (segmentPropertyMap !== undefined) { - const mapUrl = resolvePath(url, segmentPropertyMap); - const metadata = await getJsonMetadata( - options.chunkManager, - credentialsProvider, - mapUrl, + const mapUrl = kvstoreEnsureDirectoryPipelineUrl( + sharedKvStoreContext.kvStoreContext.resolveRelativePath( + url, + segmentPropertyMap, + ), ); - const segmentPropertyMapData = getSegmentPropertyMap( - options.chunkManager, - credentialsProvider, - metadata, + const metadata = await getJsonMetadata( + sharedKvStoreContext, mapUrl, + /*required=*/ true, + options, ); + const segmentPropertyMapData = getSegmentPropertyMap(metadata); subsources.push({ id: "properties", default: true, @@ -1236,44 +1252,7 @@ function parseInlinePropertyMap(data: unknown): InlineSegmentPropertyMap { return normalizeInlineSegmentPropertyMap({ ids, properties }); } -export const PrecomputedIndexedSegmentPropertySource = WithParameters( - WithCredentialsProvider()( - IndexedSegmentPropertySource, - ), - IndexedSegmentPropertySourceParameters, -); - -// function parseIndexedPropertyMap(data: unknown): { -// sharding: ShardingParameters|undefined, -// properties: readonly Readonly[] -// } { -// verifyObject(data); -// const sharding = verifyObjectProperty(data, 'sharding', parseShardingParameters); -// const properties = verifyObjectProperty( -// data, 'properties', -// propertiesObj => parseArray(propertiesObj, (propertyObj): IndexedSegmentProperty => { -// const id = verifyObjectProperty(propertyObj, 'id', verifyString); -// const description = verifyOptionalObjectProperty(propertyObj, 'description', verifyString); -// const type = verifyObjectProperty(propertyObj, 'type', type => { -// if (type !== 'string') { -// throw new Error(`Invalid property type: ${JSON.stringify(type)}`); -// } -// return type; -// }); -// return {id, description, type}; -// })); -// return {sharding, properties}; -// } - -export function getSegmentPropertyMap( - chunkManager: Borrowed, - credentialsProvider: SpecialProtocolCredentialsProvider, - data: unknown, - url: string, -): SegmentPropertyMap { - chunkManager; - credentialsProvider; - url; +export function getSegmentPropertyMap(data: unknown): SegmentPropertyMap { try { const t = verifyObjectProperty(data, "@type", verifyString); if (t !== "neuroglancer_segment_properties") { @@ -1286,25 +1265,13 @@ export function getSegmentPropertyMap( "inline", parseInlinePropertyMap, ); - // const indexedProperties = verifyOptionalObjectProperty(data, 'indexed', indexedObj => { - // const {sharding, properties} = parseIndexedPropertyMap(indexedObj); - // return chunkManager.getChunkSource( - // PrecomputedIndexedSegmentPropertySource, - // {credentialsProvider, properties, parameters: {sharding, url}}); - // }); return new SegmentPropertyMap({ inlineProperties }); } catch (e) { throw new Error(`Error parsing segment property map: ${e.message}`); } } -async function getSegmentPropertyMapDataSource( - options: GetDataSourceOptions, - credentialsProvider: SpecialProtocolCredentialsProvider, - url: string, - metadata: unknown, -): Promise { - options; +function getSegmentPropertyMapDataSource(metadata: unknown): DataSource { return { modelTransform: makeIdentityTransform(emptyValidCoordinateSpace), subsources: [ @@ -1312,12 +1279,7 @@ async function getSegmentPropertyMapDataSource( id: "default", default: true, subsource: { - segmentPropertyMap: getSegmentPropertyMap( - options.chunkManager, - credentialsProvider, - metadata, - url, - ), + segmentPropertyMap: getSegmentPropertyMap(metadata), }, }, ], @@ -1343,54 +1305,47 @@ export function unparseProviderUrl(url: string, parameters: any) { return url; } -export class PrecomputedDataSource extends DataSourceProvider { - get description() { - return "Precomputed file-backed data source"; +export class PrecomputedDataSource implements KvStoreBasedDataSourceProvider { + get scheme() { + return "neuroglancer-precomputed"; } - - normalizeUrl(options: NormalizeUrlOptions): string { - const { url, parameters } = parseProviderUrl(options.providerUrl); - return ( - options.providerProtocol + "://" + unparseProviderUrl(url, parameters) - ); + get expectsDirectory() { + return true; } - - convertLegacyUrl(options: ConvertLegacyUrlOptions): string { - const { url, parameters } = parseProviderUrl(options.providerUrl); - if (options.type === "mesh") { - parameters.type = "mesh"; - } - return ( - options.providerProtocol + "://" + unparseProviderUrl(url, parameters) - ); + get description() { + return "Neuroglancer Precomputed data source"; } - get(options: GetDataSourceOptions): Promise { - const { url: providerUrl, parameters } = parseProviderUrl( - options.providerUrl, + get( + options: GetKvStoreBasedDataSourceOptions, + ): Promise { + const { authorityAndPath, query, fragment } = parseUrlSuffix( + options.url.suffix, ); - return options.chunkManager.memoize.getUncounted( - { type: "precomputed:get", providerUrl, parameters }, - async (): Promise => { - const { url, credentialsProvider } = parseSpecialUrl( - providerUrl, - options.credentialsManager, + if (query) { + throw new Error( + `Invalid URL ${JSON.stringify(options.url.url)}: query parameters not supported`, + ); + } + if (authorityAndPath) { + throw new Error( + `Invalid URL ${JSON.stringify(options.url.url)}: non-empty path not supported`, + ); + } + const parameters = parseQueryStringParameters(fragment ?? ""); + const url = kvstoreEnsureDirectoryPipelineUrl(options.kvStoreUrl); + return options.registry.chunkManager.memoize.getAsync( + { type: "precomputed:get", url, parameters }, + options, + async (progressOptions) => { + const { sharedKvStoreContext } = options.registry; + const metadata = await getJsonMetadata( + sharedKvStoreContext, + url, + /*required=*/ parameters.type !== "mesh", + progressOptions, ); - let metadata: any; - try { - metadata = await getJsonMetadata( - options.chunkManager, - credentialsProvider, - url, - ); - } catch (e) { - if (isNotFoundError(e)) { - if (parameters.type === "mesh") { - return await getMeshDataSource(options, credentialsProvider, url); - } - } - throw e; - } + const canonicalUrl = `${url}|${options.url.scheme}:`; verifyObject(metadata); const redirect = verifyOptionalObjectProperty( metadata, @@ -1398,52 +1353,74 @@ export class PrecomputedDataSource extends DataSourceProvider { verifyString, ); if (redirect !== undefined) { - throw new RedirectError(redirect); + return { canonicalUrl, targetUrl: redirect }; } const t = verifyOptionalObjectProperty(metadata, "@type", verifyString); + let dataSource: DataSource; switch (t) { case "neuroglancer_skeletons": - return await getSkeletonsDataSource( - options, - credentialsProvider, + dataSource = await getSkeletonsDataSource( + sharedKvStoreContext, url, + progressOptions, ); + break; case "neuroglancer_multilod_draco": case "neuroglancer_legacy_mesh": - return await getMeshDataSource(options, credentialsProvider, url); - case "neuroglancer_annotations_v1": - return await getAnnotationDataSource( - options, - credentialsProvider, + dataSource = await getMeshDataSource( + sharedKvStoreContext, url, - metadata, + progressOptions, ); - case "neuroglancer_segment_properties": - return await getSegmentPropertyMapDataSource( - options, - credentialsProvider, + break; + case "neuroglancer_annotations_v1": + dataSource = getAnnotationDataSource( + sharedKvStoreContext, url, metadata, ); + break; + case "neuroglancer_segment_properties": + dataSource = getSegmentPropertyMapDataSource(metadata); + break; case "neuroglancer_multiscale_volume": case undefined: - return await getVolumeDataSource( - options, - credentialsProvider, + dataSource = await getVolumeDataSource( + sharedKvStoreContext, url, metadata, + progressOptions, ); + break; default: throw new Error(`Invalid type: ${JSON.stringify(t)}`); } + dataSource.canonicalUrl = canonicalUrl; + return dataSource; }, ); } - completeUrl(options: CompleteUrlOptions) { - return completeHttpPath( - options.credentialsManager, - options.providerUrl, - options.cancellationToken, - ); +} + +export class PrecomputedLegacyUrlDataSource extends KvStoreBasedDataSourceLegacyUrlAdapter { + constructor() { + super(new PrecomputedDataSource(), "precomputed"); } + + convertLegacyUrl(options: ConvertLegacyUrlOptions): string { + const { url, parameters } = parseProviderUrl(options.providerUrl); + if (options.type === "mesh") { + parameters.type = "mesh"; + } + return options.providerScheme + "://" + unparseProviderUrl(url, parameters); + } +} + +export function registerAutoDetect(registry: AutoDetectRegistry) { + registry.registerDirectoryFormat( + simpleFilePresenceAutoDetectDirectorySpec(new Set(["info"]), { + suffix: "neuroglancer-precomputed:", + description: "Neuroglancer Precomputed data source", + }), + ); } diff --git a/src/datasource/precomputed/register_default.ts b/src/datasource/precomputed/register_default.ts index ae5ed2d680..154b42bb80 100644 --- a/src/datasource/precomputed/register_default.ts +++ b/src/datasource/precomputed/register_default.ts @@ -14,7 +14,17 @@ * limitations under the License. */ -import { registerProvider } from "#src/datasource/default_provider.js"; -import { PrecomputedDataSource } from "#src/datasource/precomputed/frontend.js"; +import { + dataSourceAutoDetectRegistry, + registerKvStoreBasedDataProvider, + registerProvider, +} from "#src/datasource/default_provider.js"; +import { + PrecomputedDataSource, + PrecomputedLegacyUrlDataSource, + registerAutoDetect, +} from "#src/datasource/precomputed/frontend.js"; -registerProvider("precomputed", () => new PrecomputedDataSource()); +registerKvStoreBasedDataProvider(new PrecomputedDataSource()); +registerProvider(new PrecomputedLegacyUrlDataSource()); +registerAutoDetect(dataSourceAutoDetectRegistry); diff --git a/src/datasource/precomputed/sharded.ts b/src/datasource/precomputed/sharded.ts new file mode 100644 index 0000000000..55d9bc8b71 --- /dev/null +++ b/src/datasource/precomputed/sharded.ts @@ -0,0 +1,312 @@ +/** + * @license + * Copyright 2016 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ChunkManager } from "#src/chunk_manager/backend.js"; +import { SimpleAsyncCache } from "#src/chunk_manager/generic_file_source.js"; +import { + DataEncoding, + ShardingHashFunction, + type ShardingParameters, +} from "#src/datasource/precomputed/base.js"; +import { FileByteRangeHandle } from "#src/kvstore/byte_range/file_handle.js"; +import { GzipFileHandle } from "#src/kvstore/gzip/file_handle.js"; +import type { + ByteRange, + DriverReadOptions, + FileHandle, + KvStoreWithPath, + ReadableKvStore, + ReadResponse, + StatOptions, + StatResponse, +} from "#src/kvstore/index.js"; +import { KvStoreFileHandle, readFileHandle } from "#src/kvstore/index.js"; +import type { Owned } from "#src/util/disposable.js"; +import { RefCounted } from "#src/util/disposable.js"; +import { convertEndian64, Endianness } from "#src/util/endian.js"; +import { murmurHash3_x86_128Hash64Bits_Bigint } from "#src/util/hash.js"; +import type { ProgressOptions } from "#src/util/progress_listener.js"; + +const shardingHashFunctions: Map< + ShardingHashFunction, + (input: bigint) => bigint +> = new Map([ + [ + ShardingHashFunction.MURMURHASH3_X86_128, + (input) => murmurHash3_x86_128Hash64Bits_Bigint(/*seed=*/ 0, input), + ], + [ShardingHashFunction.IDENTITY, (input) => input], +]); + +export interface ShardInfo { + shardPath: string; + offset: number; +} + +interface DecodedMinishardIndex { + data: BigUint64Array; + shardPath: string; +} + +type MinishardIndexCache = SimpleAsyncCache< + bigint, + DecodedMinishardIndex | undefined +>; + +function decodeFileHandle(handle: FileHandle, encoding: DataEncoding) { + if (encoding === DataEncoding.GZIP) { + handle = new GzipFileHandle(handle, "gzip"); + } + return handle; +} + +function makeMinishardIndexCache( + chunkManager: ChunkManager, + base: KvStoreWithPath, + sharding: ShardingParameters, +): MinishardIndexCache { + return new SimpleAsyncCache(chunkManager.addRef(), { + encodeKey: (key) => key.toString(), + get: async ( + shardAndMinishard: bigint, + progressOptions: Partial, + ) => { + const minishard = + shardAndMinishard & ((1n << BigInt(sharding.minishardBits)) - 1n); + const shard = + ((1n << BigInt(sharding.shardBits)) - 1n) & + (shardAndMinishard >> BigInt(sharding.minishardBits)); + const shardPath = + base.path + + shard.toString(16).padStart(Math.ceil(sharding.shardBits / 4), "0") + + ".shard"; + + const shardFileHandle = new KvStoreFileHandle(base.store, shardPath); + + // Retrive minishard index start/end offsets. + const shardIndexSize = BigInt(16) << BigInt(sharding.minishardBits); + + // Multiply minishard by 16. + const shardIndexStart = minishard << 4n; + const response = await readFileHandle(shardFileHandle, { + ...progressOptions, + byteRange: { offset: Number(shardIndexStart), length: 16 }, + strictByteRange: true, + }); + if (response === undefined) { + return { data: undefined, size: 0 }; + } + const shardIndexResponse = await response.response.arrayBuffer(); + const shardIndexDv = new DataView(shardIndexResponse); + let minishardStartOffset = shardIndexDv.getBigUint64( + 0, + /*littleEndian=*/ true, + ); + let minishardEndOffset = shardIndexDv.getBigUint64( + 8, + /*littleEndian=*/ true, + ); + if (minishardStartOffset === minishardEndOffset) { + return { data: undefined, size: 0 }; + } + // The start/end offsets in the shard index are relative to the end of the shard + // index. + minishardStartOffset += shardIndexSize; + minishardEndOffset += shardIndexSize; + + const minishardIndexBuffer = await ( + await readFileHandle( + decodeFileHandle( + new FileByteRangeHandle(shardFileHandle, { + offset: Number(minishardStartOffset), + length: Number(minishardEndOffset - minishardStartOffset), + }), + sharding.minishardIndexEncoding, + ), + { + ...progressOptions, + strictByteRange: true, + throwIfMissing: true, + }, + ) + ).response.arrayBuffer(); + if (minishardIndexBuffer.byteLength % 24 !== 0) { + throw new Error( + `Invalid minishard index length: ${minishardIndexBuffer.byteLength}`, + ); + } + const minishardIndex = new BigUint64Array(minishardIndexBuffer); + convertEndian64(minishardIndex, Endianness.LITTLE); + + const minishardIndexSize = minishardIndex.byteLength / 24; + let prevEntryKey = 0n; + // Offsets in the minishard index are relative to the end of the shard index. + let prevStart = shardIndexSize; + for (let i = 0; i < minishardIndexSize; ++i) { + const entryKey = prevEntryKey + minishardIndex[i]; + prevEntryKey = minishardIndex[i] = entryKey; + const start = prevStart + minishardIndex[minishardIndexSize + i]; + minishardIndex[minishardIndexSize + i] = start; + const size = minishardIndex[2 * minishardIndexSize + i]; + const end = start + size; + prevStart = end; + minishardIndex[2 * minishardIndexSize + i] = end; + } + return { + data: { data: minishardIndex, shardPath }, + size: minishardIndex.byteLength, + }; + }, + }); +} + +function findMinishardEntry( + minishardIndex: DecodedMinishardIndex, + key: bigint, +): ByteRange | undefined { + const minishardIndexData = minishardIndex.data; + const minishardIndexSize = minishardIndexData.length / 3; + for (let i = 0; i < minishardIndexSize; ++i) { + if (minishardIndexData[i] !== key) { + continue; + } + const startOffset = minishardIndexData[minishardIndexSize + i]; + const endOffset = minishardIndexData[2 * minishardIndexSize + i]; + + return { + offset: Number(startOffset), + length: Number(endOffset - startOffset), + }; + } + return undefined; +} + +export class ShardedKvStore + extends RefCounted + implements ReadableKvStore +{ + private minishardIndexCache: Owned; + + constructor( + chunkManager: ChunkManager, + private base: KvStoreWithPath, + private sharding: ShardingParameters, + ) { + super(); + this.minishardIndexCache = this.registerDisposer( + makeMinishardIndexCache(chunkManager, base, sharding), + ); + } + + getUrl(key: bigint): string { + return `chunk ${key} in ${this.base.store.getUrl(this.base.path)}`; + } + + async findKey( + key: bigint, + progressOptions: Partial, + ): Promise<{ minishardEntry: ByteRange; shardInfo: ShardInfo } | undefined> { + const { sharding } = this; + const hashFunction = shardingHashFunctions.get(sharding.hash)!; + const hashCode = hashFunction(key >> BigInt(sharding.preshiftBits)); + const shardAndMinishard = + hashCode & + ((1n << BigInt(sharding.minishardBits + sharding.shardBits)) - 1n); + const minishardIndex = await this.minishardIndexCache.get( + shardAndMinishard, + progressOptions, + ); + if (minishardIndex === undefined) return undefined; + const minishardEntry = findMinishardEntry(minishardIndex, key); + if (minishardEntry === undefined) return undefined; + return { + minishardEntry, + shardInfo: { + shardPath: minishardIndex.shardPath, + offset: minishardEntry.offset, + }, + }; + } + + async readWithShardInfo( + key: bigint, + options: DriverReadOptions, + ): Promise< + | { + response: ReadResponse; + shardInfo: ShardInfo; + } + | undefined + > { + const { sharding } = this; + const findResult = await this.findKey(key, options); + if (findResult === undefined) return undefined; + const { minishardEntry, shardInfo } = findResult; + return { + response: (await decodeFileHandle( + new FileByteRangeHandle( + new KvStoreFileHandle(this.base.store, shardInfo.shardPath), + minishardEntry, + ), + sharding.dataEncoding, + ).read(options))!, + shardInfo, + }; + } + + async stat( + key: bigint, + options: StatOptions, + ): Promise { + const findResult = await this.findKey(key, options); + if (findResult === undefined) return undefined; + const { sharding } = this; + if (sharding.dataEncoding !== DataEncoding.RAW) { + return { totalSize: undefined }; + } else { + return { totalSize: findResult.minishardEntry.length }; + } + } + + async read( + key: bigint, + options: DriverReadOptions, + ): Promise { + const response = await this.readWithShardInfo(key, options); + if (response === undefined) return undefined; + return response.response; + } + + get supportsOffsetReads() { + return this.sharding.dataEncoding === DataEncoding.RAW; + } + get supportsSuffixReads() { + return this.sharding.dataEncoding === DataEncoding.RAW; + } +} + +export function getShardedKvStoreIfApplicable( + chunkSource: RefCounted & { + chunkManager: ChunkManager; + }, + base: KvStoreWithPath, + sharding: ShardingParameters | undefined, +) { + if (sharding === undefined) return undefined; + return chunkSource.registerDisposer( + new ShardedKvStore(chunkSource.chunkManager, base, sharding), + ); +} diff --git a/src/datasource/python/backend.ts b/src/datasource/python/backend.ts index 134ef939bc..988e7533be 100644 --- a/src/datasource/python/backend.ts +++ b/src/datasource/python/backend.ts @@ -38,12 +38,8 @@ import { VolumeChunk, VolumeChunkSource, } from "#src/sliceview/volume/backend.js"; -import { CancellationToken } from "#src/util/cancellation.js"; import { Endianness } from "#src/util/endian.js"; -import { - cancellableFetchOk, - responseArrayBuffer, -} from "#src/util/http_request.js"; +import { fetchOk } from "#src/util/http_request.js"; import { registerSharedObject } from "#src/worker_rpc.js"; const chunkDecoders = new Map(); @@ -59,7 +55,7 @@ export class PythonVolumeChunkSource extends WithParameters( chunkDecoder = chunkDecoders.get(this.parameters["encoding"])!; encoding = VolumeChunkEncoding[this.parameters.encoding].toLowerCase(); - async download(chunk: VolumeChunk, cancellationToken: CancellationToken) { + async download(chunk: VolumeChunk, signal: AbortSignal) { const { parameters } = this; let path = `../../neuroglancer/${this.encoding}/${parameters.key}/${parameters.scaleKey}`; { @@ -74,13 +70,10 @@ export class PythonVolumeChunkSource extends WithParameters( path += (chunkPosition[i] + chunkDataSize[i]).toString(); } } - const response = await cancellableFetchOk( - new URL(path, parameters.baseUrl).href, - {}, - responseArrayBuffer, - cancellationToken, - ); - await this.chunkDecoder(chunk, cancellationToken, response); + const response = await fetchOk(new URL(path, parameters.baseUrl).href, { + signal: signal, + }); + await this.chunkDecoder(chunk, signal, await response.arrayBuffer()); } } @@ -112,17 +105,16 @@ export class PythonMeshSource extends WithParameters( return Promise.resolve(undefined); } - downloadFragment(chunk: FragmentChunk, cancellationToken: CancellationToken) { + downloadFragment(chunk: FragmentChunk, signal: AbortSignal) { const { parameters } = this; const requestPath = `../../neuroglancer/mesh/${parameters.key}/${ chunk.manifestChunk!.objectId }`; - return cancellableFetchOk( - new URL(requestPath, parameters.baseUrl).href, - {}, - responseArrayBuffer, - cancellationToken, - ).then((response) => decodeFragmentChunk(chunk, response)); + return fetchOk(new URL(requestPath, parameters.baseUrl).href, { + signal: signal, + }) + .then((response) => response.arrayBuffer()) + .then((response) => decodeFragmentChunk(chunk, response)); } } @@ -131,16 +123,15 @@ export class PythonSkeletonSource extends WithParameters( SkeletonSource, SkeletonSourceParameters, ) { - download(chunk: SkeletonChunk, cancellationToken: CancellationToken) { + download(chunk: SkeletonChunk, signal: AbortSignal) { const { parameters } = this; const requestPath = `../../neuroglancer/skeleton/${parameters.key}/${chunk.objectId}`; - return cancellableFetchOk( - new URL(requestPath, parameters.baseUrl).href, - {}, - responseArrayBuffer, - cancellationToken, - ).then((response) => - decodeSkeletonChunk(chunk, response, parameters.vertexAttributes), - ); + return fetchOk(new URL(requestPath, parameters.baseUrl).href, { + signal: signal, + }) + .then((response) => response.arrayBuffer()) + .then((response) => + decodeSkeletonChunk(chunk, response, parameters.vertexAttributes), + ); } } diff --git a/src/datasource/python/frontend.ts b/src/datasource/python/frontend.ts index 73e6b4943b..a417a68e30 100644 --- a/src/datasource/python/frontend.ts +++ b/src/datasource/python/frontend.ts @@ -65,7 +65,6 @@ import { VolumeChunkSource, } from "#src/sliceview/volume/frontend.js"; import { transposeNestedArrays } from "#src/util/array.js"; -import { Borrowed, Owned } from "#src/util/disposable.js"; import { fetchOk } from "#src/util/http_request.js"; import { parseFixedLengthArray, @@ -94,20 +93,18 @@ function WithPythonDataSource< >, >(Base: TBase) { type Options = InstanceType["OPTIONS"] & { - dataSource: Borrowed; + dataSource: PythonDataSource; generation: number; }; class C extends Base { - OPTIONS: Options; - dataSource: Owned; + declare OPTIONS: Options; + dataSource: PythonDataSource; generation: number; - parameters: PythonSourceParameters; + declare parameters: PythonSourceParameters; constructor(...args: any[]) { super(...args); const options: Options = args[1]; - const dataSource = (this.dataSource = this.registerDisposer( - options.dataSource.addRef(), - )); + const dataSource = (this.dataSource = options.dataSource); this.generation = options.generation; const key = options.parameters.key; dataSource.registerSource(key, this); @@ -238,7 +235,7 @@ export class PythonMultiscaleVolumeChunkSource extends MultiscaleVolumeChunkSour // TODO(jbms): Properly handle reference counting of `dataSource`. constructor( - public dataSource: Borrowed, + public dataSource: PythonDataSource, chunkManager: ChunkManager, public key: string, public response: any, @@ -480,17 +477,19 @@ function getVolumeDataSource( options: GetDataSourceOptions, key: string, ) { - return options.chunkManager.memoize.getUncounted( + return options.registry.chunkManager.memoize.getAsync( { type: "python:VolumeDataSource", key }, - async () => { + options, + async (progressOptions) => { const response = await ( await fetchOk( new URL(`../../neuroglancer/info/${key}`, window.location.href).href, + progressOptions, ) ).json(); const volume = new PythonMultiscaleVolumeChunkSource( dataSourceProvider, - options.chunkManager, + options.registry.chunkManager, key, response, ); @@ -527,14 +526,17 @@ function getVolumeDataSource( default: true, subsourceToModelSubspaceTransform, subsource: { - mesh: options.chunkManager.getChunkSource(PythonMeshSource, { - dataSource: dataSourceProvider, - generation: volume.generation, - parameters: { - baseUrl: window.location.href, - key: key, + mesh: options.registry.chunkManager.getChunkSource( + PythonMeshSource, + { + dataSource: dataSourceProvider, + generation: volume.generation, + parameters: { + baseUrl: window.location.href, + key: key, + }, }, - }), + ), }, }); } @@ -548,15 +550,17 @@ function getSkeletonDataSource( options: GetDataSourceOptions, key: string, ) { - return options.chunkManager.memoize.getUncounted( + return options.registry.chunkManager.memoize.getAsync( { type: "python:SkeletonDataSource", key }, - async () => { + options, + async (progressOptions) => { const response = await ( await fetchOk( new URL( `../../neuroglancer/skeletoninfo/${key}`, window.location.href, ).href, + progressOptions, ) ).json(); const { baseModelSpace, subsourceToModelTransform } = @@ -567,7 +571,7 @@ function getSkeletonDataSource( (x) => verifyObjectAsMap(x, parseVertexAttributeInfo), ); const generation = verifyObjectProperty(response, "generation", (x) => x); - const skeletonSource = options.chunkManager.getChunkSource( + const skeletonSource = options.registry.chunkManager.getChunkSource( PythonSkeletonSource, { dataSource: dataSourceProvider, @@ -597,10 +601,14 @@ function getSkeletonDataSource( ); } -export class PythonDataSource extends DataSourceProvider { +export class PythonDataSource implements DataSourceProvider { private sources = new Map>(); sourceGenerations = new Map(); + get scheme() { + return "python"; + } + registerSource(key: string, source: PythonChunkSource) { let existingSet = this.sources.get(key); if (existingSet === undefined) { diff --git a/src/async_computation/decode_gzip_request.ts b/src/datasource/python/register_default.ts similarity index 72% rename from src/async_computation/decode_gzip_request.ts rename to src/datasource/python/register_default.ts index 91dddb6b85..d70ae3dfdb 100644 --- a/src/async_computation/decode_gzip_request.ts +++ b/src/datasource/python/register_default.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2019 Google Inc. + * Copyright 2024 Google Inc. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -14,7 +14,7 @@ * limitations under the License. */ -import { asyncComputation } from "#src/async_computation/index.js"; +import { registerProvider } from "#src/datasource/default_provider.js"; +import { PythonDataSource } from "#src/datasource/python/frontend.js"; -export const decodeGzip = - asyncComputation<(data: Uint8Array) => Uint8Array>("decodeGzip"); +registerProvider(new PythonDataSource()); diff --git a/src/datasource/render/backend.ts b/src/datasource/render/backend.ts index ad53c010c4..bd78682201 100644 --- a/src/datasource/render/backend.ts +++ b/src/datasource/render/backend.ts @@ -23,27 +23,19 @@ import { postProcessRawData } from "#src/sliceview/backend_chunk_decoders/postpr import { decodeRawChunk } from "#src/sliceview/backend_chunk_decoders/raw.js"; import type { VolumeChunk } from "#src/sliceview/volume/backend.js"; import { VolumeChunkSource } from "#src/sliceview/volume/backend.js"; -import type { CancellationToken } from "#src/util/cancellation.js"; import { Endianness } from "#src/util/endian.js"; import { vec3 } from "#src/util/geom.js"; -import { - cancellableFetchOk, - responseArrayBuffer, -} from "#src/util/http_request.js"; +import { fetchOk } from "#src/util/http_request.js"; import { registerSharedObject } from "#src/worker_rpc.js"; const chunkDecoders = new Map(); chunkDecoders.set( "jpg", - async ( - chunk: VolumeChunk, - cancellationToken: CancellationToken, - response: ArrayBuffer, - ) => { + async (chunk: VolumeChunk, signal: AbortSignal, response: ArrayBuffer) => { const chunkDataSize = chunk.chunkDataSize!; const { uint8Array: decoded } = await requestAsyncComputation( decodeJpeg, - cancellationToken, + signal, [response], new Uint8Array(response), undefined, @@ -52,11 +44,11 @@ chunkDecoders.set( 3, true, ); - await postProcessRawData(chunk, cancellationToken, decoded); + await postProcessRawData(chunk, signal, decoded); }, ); -chunkDecoders.set("raw16", (chunk, cancellationToken, response) => { - return decodeRawChunk(chunk, cancellationToken, response, Endianness.BIG); +chunkDecoders.set("raw16", (chunk, signal, response) => { + return decodeRawChunk(chunk, signal, response, Endianness.BIG); }); @registerSharedObject() @@ -95,7 +87,7 @@ export class TileChunkSource extends WithParameters( return query_params.join("&"); })(); - async download(chunk: VolumeChunk, cancellationToken: CancellationToken) { + async download(chunk: VolumeChunk, signal: AbortSignal) { const { parameters } = this; const { chunkGridPosition } = chunk; @@ -124,12 +116,10 @@ export class TileChunkSource extends WithParameters( imageMethod = "jpeg-image"; } const path = `/render-ws/v1/owner/${parameters.owner}/project/${parameters.project}/stack/${parameters.stack}/z/${chunkPosition[2]}/box/${chunkPosition[0]},${chunkPosition[1]},${xTileSize},${yTileSize},${scale}/${imageMethod}`; - const response = await cancellableFetchOk( + const response = await fetchOk( `${parameters.baseUrl}${path}?${this.queryString}`, - {}, - responseArrayBuffer, - cancellationToken, + { signal: signal }, ); - await this.chunkDecoder(chunk, cancellationToken, response); + await this.chunkDecoder(chunk, signal, await response.arrayBuffer()); } } diff --git a/src/datasource/render/frontend.ts b/src/datasource/render/frontend.ts index 66370a7154..46d700430e 100644 --- a/src/datasource/render/frontend.ts +++ b/src/datasource/render/frontend.ts @@ -32,8 +32,8 @@ import type { CompletionResult, DataSource, GetDataSourceOptions, + DataSourceProvider, } from "#src/datasource/index.js"; -import { DataSourceProvider } from "#src/datasource/index.js"; import { TileChunkSourceParameters } from "#src/datasource/render/base.js"; import type { SliceViewSingleResolutionSource } from "#src/sliceview/frontend.js"; import type { VolumeSourceOptions } from "#src/sliceview/volume/base.js"; @@ -64,6 +64,7 @@ import { verifyOptionalString, verifyString, } from "#src/util/json.js"; +import type { ProgressOptions } from "#src/util/progress_listener.js"; const VALID_ENCODINGS = new Set(["jpg", "raw16"]); @@ -249,7 +250,7 @@ function parseStackVersionInfo(stackVersionObj: any): vec3 { "stackResolutionZ", verifyFloat, ); - } catch (ignoredError) { + } catch { // default is 1, 1, 1 voxelResolution[0] = 1; voxelResolution[1] = 1; @@ -505,11 +506,13 @@ export function getOwnerInfo( chunkManager: ChunkManager, hostname: string, owner: string, + options: Partial, ): Promise { - return chunkManager.memoize.getUncounted( + return chunkManager.memoize.getAsync( { type: "render:getOwnerInfo", hostname, owner }, - () => - fetchOk(`${hostname}/render-ws/v1/owner/${owner}/stacks`) + options, + (progressOptions) => + fetchOk(`${hostname}/render-ws/v1/owner/${owner}/stacks`, progressOptions) .then((response) => response.json()) .then(parseOwnerInfo), ); @@ -519,7 +522,11 @@ const pathPattern = /^([^/?]+)(?:\/([^/?]+))?(?:\/([^/?]+))(?:\/([^/?]*))?(?:\?(.*))?$/; const urlPattern = /^((?:(?:(?:http|https):\/\/[^,/]+)[^/?]))\/(.*)$/; -function getVolume(chunkManager: ChunkManager, datasourcePath: string) { +function getVolume( + chunkManager: ChunkManager, + datasourcePath: string, + options: Partial, +) { let hostname: string; let path: string; { @@ -543,10 +550,16 @@ function getVolume(chunkManager: ChunkManager, datasourcePath: string) { const parameters = parseQueryStringParameters(match[5] || ""); - return chunkManager.memoize.getUncounted( + return chunkManager.memoize.getAsync( { type: "render:MultiscaleVolumeChunkSource", hostname, path }, - async () => { - const ownerInfo = await getOwnerInfo(chunkManager, hostname, owner); + options, + async (progressOptions) => { + const ownerInfo = await getOwnerInfo( + chunkManager, + hostname, + owner, + progressOptions, + ); const volume = new RenderMultiscaleVolumeChunkSource( chunkManager, hostname, @@ -599,6 +612,7 @@ export async function stackAndProjectCompleter( chunkManager: ChunkManager, hostname: string, path: string, + options: Partial, ): Promise { const stackMatch = path.match( /^(?:([^/]+)(?:\/([^/]*))?(?:\/([^/]*))?(\/.*?)?)?$/, @@ -613,7 +627,12 @@ export async function stackAndProjectCompleter( } if (stackMatch[3] === undefined) { const projectPrefix = stackMatch[2] || ""; - const ownerInfo = await getOwnerInfo(chunkManager, hostname, stackMatch[1]); + const ownerInfo = await getOwnerInfo( + chunkManager, + hostname, + stackMatch[1], + options, + ); const completions = getPrefixMatchesWithDescriptions( projectPrefix, ownerInfo.projects, @@ -624,7 +643,12 @@ export async function stackAndProjectCompleter( } if (stackMatch[4] === undefined) { const stackPrefix = stackMatch[3] || ""; - const ownerInfo = await getOwnerInfo(chunkManager, hostname, stackMatch[1]); + const ownerInfo = await getOwnerInfo( + chunkManager, + hostname, + stackMatch[1], + options, + ); const projectInfo = ownerInfo.projects.get(stackMatch[2]); if (projectInfo === undefined) { throw null; @@ -643,7 +667,12 @@ export async function stackAndProjectCompleter( }; } const channelPrefix = stackMatch[4].substr(1) || ""; - const ownerInfo = await getOwnerInfo(chunkManager, hostname, stackMatch[1]); + const ownerInfo = await getOwnerInfo( + chunkManager, + hostname, + stackMatch[1], + options, + ); const projectInfo = ownerInfo.projects.get(stackMatch[2]); if (projectInfo === undefined) { throw null; @@ -673,6 +702,7 @@ export async function stackAndProjectCompleter( export async function volumeCompleter( url: string, chunkManager: ChunkManager, + options: Partial, ): Promise { const match = url.match(urlPattern); if (match === null) { @@ -686,18 +716,30 @@ export async function volumeCompleter( chunkManager, hostname, path, + options, ); return applyCompletionOffset(match![1].length + 1, completions); } -export class RenderDataSource extends DataSourceProvider { +export class RenderDataSource implements DataSourceProvider { + get scheme() { + return "render"; + } get description() { return "Render"; } get(options: GetDataSourceOptions): Promise { - return getVolume(options.chunkManager, options.providerUrl); + return getVolume( + options.registry.chunkManager, + options.providerUrl, + options, + ); } completeUrl(options: CompleteUrlOptions) { - return volumeCompleter(options.providerUrl, options.chunkManager); + return volumeCompleter( + options.providerUrl, + options.registry.chunkManager, + options, + ); } } diff --git a/src/datasource/render/register_default.ts b/src/datasource/render/register_default.ts index ae5a9241a0..3c4f1c8d27 100644 --- a/src/datasource/render/register_default.ts +++ b/src/datasource/render/register_default.ts @@ -17,4 +17,4 @@ import { registerProvider } from "#src/datasource/default_provider.js"; import { RenderDataSource } from "#src/datasource/render/frontend.js"; -registerProvider("render", () => new RenderDataSource()); +registerProvider(new RenderDataSource()); diff --git a/src/datasource/state_share.ts b/src/datasource/state_share.ts index 9535ba2c66..27f3184872 100644 --- a/src/datasource/state_share.ts +++ b/src/datasource/state_share.ts @@ -1,11 +1,6 @@ -import { defaultCredentialsManager } from "#src/credentials_provider/default_manager.js"; +import { HttpKvStore } from "#src/kvstore/http/index.js"; import { StatusMessage } from "#src/status.js"; import { RefCounted } from "#src/util/disposable.js"; -import { responseJson } from "#src/util/http_request.js"; -import { - cancellableFetchSpecialOk, - parseSpecialUrl, -} from "#src/util/special_protocol_request.js"; import type { Viewer } from "#src/viewer.js"; import { makeIcon } from "#src/widget/icon.js"; @@ -78,28 +73,32 @@ export class StateShare extends RefCounted { const selectedStateServer = this.selectStateServerElement ? this.selectStateServerElement.value : Object.values(STATE_SERVERS)[0].url; - const protocol = new URL(selectedStateServer).protocol; - const { url: parsedUrl, credentialsProvider } = parseSpecialUrl( - selectedStateServer, - defaultCredentialsManager, - ); + + const { store, path } = + viewer.dataSourceProvider.sharedKvStoreContext.kvStoreContext.getKvStore( + selectedStateServer, + ); + + if (!(store instanceof HttpKvStore)) { + throw new Error( + `Non-HTTP protocol not supported: ${selectedStateServer}`, + ); + } StatusMessage.forPromise( - cancellableFetchSpecialOk( - credentialsProvider, - parsedUrl, - { + store + .fetchOkImpl(store.baseUrl + path, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(viewer.state.toJSON()), - }, - responseJson, - ) + }) + .then((response) => response.json()) .then((res) => { const stateUrlProtcol = new URL(res).protocol; const stateUrlWithoutProtocol = res.substring( stateUrlProtcol.length, ); + const protocol = new URL(selectedStateServer).protocol; const link = `${window.location.origin}/#!${protocol}${stateUrlWithoutProtocol}`; navigator.clipboard.writeText(link).then(() => { StatusMessage.showTemporaryMessage( diff --git a/src/datasource/vtk/backend.ts b/src/datasource/vtk/backend.ts index d58fd46af6..a3fd399fdc 100644 --- a/src/datasource/vtk/backend.ts +++ b/src/datasource/vtk/backend.ts @@ -16,20 +16,28 @@ import { requestAsyncComputation } from "#src/async_computation/request.js"; import { parseVTKFromArrayBuffer } from "#src/async_computation/vtk_mesh_request.js"; -import { GenericSharedDataSource } from "#src/chunk_manager/generic_file_source.js"; +import { getCachedDecodedUrl } from "#src/chunk_manager/generic_file_source.js"; +import type { ReadResponse } from "#src/kvstore/index.js"; import type { SingleMesh } from "#src/single_mesh/backend.js"; import { registerSingleMeshFactory } from "#src/single_mesh/backend.js"; -import type { CancellationToken } from "#src/util/cancellation.js"; import { DataType } from "#src/util/data_type.js"; +import type { ProgressOptions } from "#src/util/progress_listener.js"; /** - * This needs to be a global function, because it identifies the instance of GenericSharedDataSource + * This needs to be a global function, because it identifies the instance of SimpleAsyncCache * to use. */ -function parse(buffer: ArrayBuffer, cancellationToken: CancellationToken) { +async function parse( + readResponse: ReadResponse | undefined, + progressOptions: Partial, +) { + if (readResponse === undefined) { + throw new Error("Not found"); + } + const buffer = await readResponse.response.arrayBuffer(); return requestAsyncComputation( parseVTKFromArrayBuffer, - cancellationToken, + progressOptions.signal, [buffer], buffer, ); @@ -37,39 +45,31 @@ function parse(buffer: ArrayBuffer, cancellationToken: CancellationToken) { registerSingleMeshFactory("vtk", { description: "VTK", - getMesh: ( - chunkManager, - credentialsProvider, - url, - getPriority, - cancellationToken, - ) => - GenericSharedDataSource.getUrl( - chunkManager, - credentialsProvider, - parse, + getMesh: async (sharedKvStoreContext, url, options) => { + const mesh = await getCachedDecodedUrl( + sharedKvStoreContext, url, - getPriority, - cancellationToken, - ).then((mesh) => { - const result: SingleMesh = { - info: { - numTriangles: mesh.numTriangles, - numVertices: mesh.numVertices, - vertexAttributes: [], - }, - indices: mesh.indices, - vertexPositions: mesh.vertexPositions, + parse, + options, + ); + const result: SingleMesh = { + info: { + numTriangles: mesh.numTriangles, + numVertices: mesh.numVertices, vertexAttributes: [], - }; - for (const attribute of mesh.vertexAttributes) { - result.info.vertexAttributes.push({ - name: attribute.name, - dataType: DataType.FLOAT32, - numComponents: attribute.numComponents, - }); - result.vertexAttributes.push(attribute.data); - } - return result; - }), + }, + indices: mesh.indices, + vertexPositions: mesh.vertexPositions, + vertexAttributes: [], + }; + for (const attribute of mesh.vertexAttributes) { + result.info.vertexAttributes.push({ + name: attribute.name, + dataType: DataType.FLOAT32, + numComponents: attribute.numComponents, + }); + result.vertexAttributes.push(attribute.data); + } + return result; + }, }); diff --git a/src/datasource/vtk/frontend.ts b/src/datasource/vtk/frontend.ts deleted file mode 100644 index 086dbf54fb..0000000000 --- a/src/datasource/vtk/frontend.ts +++ /dev/null @@ -1,66 +0,0 @@ -/** - * @license - * Copyright 2019 Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { - makeCoordinateSpace, - makeIdentityTransform, -} from "#src/coordinate_transform.js"; -import type { - CompleteUrlOptions, - DataSource, - GetDataSourceOptions, -} from "#src/datasource/index.js"; -import { DataSourceProvider } from "#src/datasource/index.js"; -import { getSingleMeshSource } from "#src/single_mesh/frontend.js"; -import { completeHttpPath } from "#src/util/http_path_completion.js"; - -export class VtkDataSource extends DataSourceProvider { - get description() { - return "VTK mesh file"; - } - - async get(options: GetDataSourceOptions): Promise { - const meshSource = await getSingleMeshSource( - options.chunkManager, - options.credentialsManager, - options.url, - ); - const modelSpace = makeCoordinateSpace({ - rank: 3, - names: ["x", "y", "z"], - units: ["m", "m", "m"], - scales: Float64Array.of(1e-9, 1e-9, 1e-9), - }); - const dataSource: DataSource = { - modelTransform: makeIdentityTransform(modelSpace), - subsources: [ - { - id: "default", - default: true, - subsource: { singleMesh: meshSource }, - }, - ], - }; - return dataSource; - } - completeUrl(options: CompleteUrlOptions) { - return completeHttpPath( - options.credentialsManager, - options.providerUrl, - options.cancellationToken, - ); - } -} diff --git a/src/datasource/vtk/parse.ts b/src/datasource/vtk/parse.ts index a5107d7e18..39069bab42 100644 --- a/src/datasource/vtk/parse.ts +++ b/src/datasource/vtk/parse.ts @@ -49,7 +49,7 @@ export interface VTKHeader { export interface VertexAttribute { name: string; - data: Float32Array; + data: Float32Array; numComponents: number; tableName: string; dataType: string; @@ -59,9 +59,9 @@ export class TriangularMesh { constructor( public header: VTKHeader, public numVertices: number, - public vertexPositions: Float32Array, + public vertexPositions: Float32Array, public numTriangles: number, - public indices: Uint32Array, + public indices: Uint32Array, public vertexAttributes: VertexAttribute[], ) {} } diff --git a/src/datasource/vtk/register_default.ts b/src/datasource/vtk/register_default.ts index 3c3b4e571f..7bf980be94 100644 --- a/src/datasource/vtk/register_default.ts +++ b/src/datasource/vtk/register_default.ts @@ -14,7 +14,13 @@ * limitations under the License. */ -import { registerProvider } from "#src/datasource/default_provider.js"; -import { VtkDataSource } from "#src/datasource/vtk/frontend.js"; +import { + registerKvStoreBasedDataProvider, + registerProvider, +} from "#src/datasource/default_provider.js"; +import { KvStoreBasedDataSourceLegacyUrlAdapter } from "#src/datasource/index.js"; +import { SingleMeshDataSource } from "#src/single_mesh/frontend.js"; -registerProvider("vtk", () => new VtkDataSource()); +const provider = new SingleMeshDataSource("vtk", "VTK mesh"); +registerKvStoreBasedDataProvider(provider); +registerProvider(new KvStoreBasedDataSourceLegacyUrlAdapter(provider)); diff --git a/src/datasource/zarr/async_computation.ts b/src/datasource/zarr/async_computation.ts index df029623c4..db56b860ff 100644 --- a/src/datasource/zarr/async_computation.ts +++ b/src/datasource/zarr/async_computation.ts @@ -1,3 +1,2 @@ -import "#src/async_computation/decode_gzip.js"; import "#src/async_computation/decode_blosc.js"; import "#src/async_computation/decode_zstd.js"; diff --git a/src/datasource/zarr/backend.ts b/src/datasource/zarr/backend.ts index 66e23bea90..7370f7af0e 100644 --- a/src/datasource/zarr/backend.ts +++ b/src/datasource/zarr/backend.ts @@ -20,7 +20,6 @@ import "#src/datasource/zarr/codec/bytes/decode.js"; import "#src/datasource/zarr/codec/crc32c/decode.js"; import { WithParameters } from "#src/chunk_manager/backend.js"; -import { WithSharedCredentialsProviderCounterpart } from "#src/credentials_provider/shared_counterpart.js"; import { VolumeChunkSourceParameters } from "#src/datasource/zarr/base.js"; import { applySharding, @@ -30,31 +29,24 @@ import "#src/datasource/zarr/codec/gzip/decode.js"; import "#src/datasource/zarr/codec/sharding_indexed/decode.js"; import "#src/datasource/zarr/codec/transpose/decode.js"; import { ChunkKeyEncoding } from "#src/datasource/zarr/metadata/index.js"; -import { getSpecialProtocolKvStore } from "#src/kvstore/special/index.js"; +import { WithSharedKvStoreContextCounterpart } from "#src/kvstore/backend.js"; import { postProcessRawData } from "#src/sliceview/backend_chunk_decoders/postprocess.js"; import type { VolumeChunk } from "#src/sliceview/volume/backend.js"; import { VolumeChunkSource } from "#src/sliceview/volume/backend.js"; -import type { CancellationToken } from "#src/util/cancellation.js"; -import type { SpecialProtocolCredentials } from "#src/util/special_protocol_request.js"; import { registerSharedObject } from "#src/worker_rpc.js"; @registerSharedObject() export class ZarrVolumeChunkSource extends WithParameters( - WithSharedCredentialsProviderCounterpart()( - VolumeChunkSource, - ), + WithSharedKvStoreContextCounterpart(VolumeChunkSource), VolumeChunkSourceParameters, ) { private chunkKvStore = applySharding( this.chunkManager, this.parameters.metadata.codecs, - getSpecialProtocolKvStore( - this.credentialsProvider, - this.parameters.url + "/", - ), + this.sharedKvStoreContext.kvStoreContext.getKvStore(this.parameters.url), ); - async download(chunk: VolumeChunk, cancellationToken: CancellationToken) { + async download(chunk: VolumeChunk, signal: AbortSignal) { chunk.chunkDataSize = this.spec.chunkDataSize; const { parameters } = this; const { chunkGridPosition } = chunk; @@ -94,15 +86,15 @@ export class ZarrVolumeChunkSource extends WithParameters( const { chunkKvStore } = this; const response = await chunkKvStore.kvStore.read( chunkKvStore.getChunkKey(chunkGridPosition, baseKey), - { cancellationToken }, + { signal }, ); if (response !== undefined) { const decoded = await decodeArray( chunkKvStore.decodeCodecs, - response.data, - cancellationToken, + new Uint8Array(await response.response.arrayBuffer()), + signal, ); - await postProcessRawData(chunk, cancellationToken, decoded); + await postProcessRawData(chunk, signal, decoded); } } } diff --git a/src/datasource/zarr/codec/blosc/decode.ts b/src/datasource/zarr/codec/blosc/decode.ts index f7d125f1df..6931f9c8dc 100644 --- a/src/datasource/zarr/codec/blosc/decode.ts +++ b/src/datasource/zarr/codec/blosc/decode.ts @@ -19,20 +19,15 @@ import { requestAsyncComputation } from "#src/async_computation/request.js"; import type { Configuration } from "#src/datasource/zarr/codec/blosc/resolve.js"; import { registerCodec } from "#src/datasource/zarr/codec/decode.js"; import { CodecKind } from "#src/datasource/zarr/codec/index.js"; -import type { CancellationToken } from "#src/util/cancellation.js"; registerCodec({ name: "blosc", kind: CodecKind.bytesToBytes, - decode( - configuration: Configuration, - encoded: Uint8Array, - cancellationToken: CancellationToken, - ): Promise { + decode(configuration: Configuration, encoded, signal: AbortSignal) { configuration; return requestAsyncComputation( decodeBlosc, - cancellationToken, + signal, [encoded.buffer], encoded, ); diff --git a/src/datasource/zarr/codec/bytes/decode.ts b/src/datasource/zarr/codec/bytes/decode.ts index 53ae1eda0a..d94353e097 100644 --- a/src/datasource/zarr/codec/bytes/decode.ts +++ b/src/datasource/zarr/codec/bytes/decode.ts @@ -18,7 +18,6 @@ import type { Configuration } from "#src/datasource/zarr/codec/bytes/resolve.js" import { registerCodec } from "#src/datasource/zarr/codec/decode.js"; import type { CodecArrayInfo } from "#src/datasource/zarr/codec/index.js"; import { CodecKind } from "#src/datasource/zarr/codec/index.js"; -import type { CancellationToken } from "#src/util/cancellation.js"; import { DATA_TYPE_BYTES, makeDataTypeArrayView } from "#src/util/data_type.js"; import { convertEndian } from "#src/util/endian.js"; @@ -28,10 +27,10 @@ registerCodec({ async decode( configuration: Configuration, decodedArrayInfo: CodecArrayInfo, - encoded: Uint8Array, - cancellationToken: CancellationToken, - ): Promise { - cancellationToken; + encoded, + signal: AbortSignal, + ) { + signal; const { dataType, chunkShape } = decodedArrayInfo; const numElements = chunkShape.reduce((a, b) => a * b, 1); const bytesPerElement = DATA_TYPE_BYTES[dataType]; diff --git a/src/datasource/zarr/codec/crc32c/decode.ts b/src/datasource/zarr/codec/crc32c/decode.ts index 569b2b477c..6cf60c8c01 100644 --- a/src/datasource/zarr/codec/crc32c/decode.ts +++ b/src/datasource/zarr/codec/crc32c/decode.ts @@ -17,20 +17,15 @@ import type { Configuration } from "#src/datasource/zarr/codec/crc32c/resolve.js"; import { registerCodec } from "#src/datasource/zarr/codec/decode.js"; import { CodecKind } from "#src/datasource/zarr/codec/index.js"; -import type { CancellationToken } from "#src/util/cancellation.js"; const checksumSize = 4; registerCodec({ name: "crc32c", kind: CodecKind.bytesToBytes, - async decode( - configuration: Configuration, - encoded: Uint8Array, - cancellationToken: CancellationToken, - ): Promise { + async decode(configuration: Configuration, encoded, signal: AbortSignal) { configuration; - cancellationToken; + signal; if (encoded.length < checksumSize) { throw new Error( `Expected buffer of size at least ${checksumSize} bytes but received: ${encoded.length} bytes`, diff --git a/src/datasource/zarr/codec/decode.ts b/src/datasource/zarr/codec/decode.ts index bd5c5f49a7..2cc3ea9184 100644 --- a/src/datasource/zarr/codec/decode.ts +++ b/src/datasource/zarr/codec/decode.ts @@ -20,8 +20,7 @@ import type { CodecChainSpec, } from "#src/datasource/zarr/codec/index.js"; import { CodecKind } from "#src/datasource/zarr/codec/index.js"; -import type { ReadableKvStore } from "#src/kvstore/index.js"; -import type { CancellationToken } from "#src/util/cancellation.js"; +import type { KvStoreWithPath, ReadableKvStore } from "#src/kvstore/index.js"; import type { RefCounted } from "#src/util/disposable.js"; export interface Codec { @@ -34,9 +33,9 @@ export interface ArrayToArrayCodec extends Codec { decode( configuration: Configuration, decodedArrayInfo: CodecArrayInfo, - encoded: ArrayBufferView, - cancellationToken: CancellationToken, - ): Promise; + encoded: ArrayBufferView, + signal: AbortSignal, + ): Promise>; } export interface ArrayToBytesCodec extends Codec { @@ -44,9 +43,9 @@ export interface ArrayToBytesCodec extends Codec { decode( configuration: Configuration, decodedArrayInfo: CodecArrayInfo, - encoded: Uint8Array, - cancellationToken: CancellationToken, - ): Promise; + encoded: Uint8Array, + signal: AbortSignal, + ): Promise>; } export type ShardingKey = { @@ -67,9 +66,9 @@ export interface BytesToBytesCodec extends Codec { kind: CodecKind.bytesToBytes; decode( configuration: Configuration, - encoded: Uint8Array, - cancellationToken: CancellationToken, - ): Promise; + encoded: Uint8Array, + signal: AbortSignal, + ): Promise>; } const codecRegistry = { @@ -95,9 +94,9 @@ export function registerCodec( export async function decodeArray( codecs: CodecChainSpec, - encoded: Uint8Array, - cancellationToken: CancellationToken, -): Promise { + encoded: Uint8Array, + signal: AbortSignal, +): Promise> { const bytesToBytes = codecs[CodecKind.bytesToBytes]; for (let i = bytesToBytes.length; i--; ) { const codec = bytesToBytes[i]; @@ -105,14 +104,10 @@ export async function decodeArray( if (impl === undefined) { throw new Error(`Unsupported codec: ${JSON.stringify(codec.name)}`); } - encoded = await impl.decode( - codec.configuration, - encoded, - cancellationToken, - ); + encoded = await impl.decode(codec.configuration, encoded, signal); } - let decoded: ArrayBufferView; + let decoded: ArrayBufferView; { const codec = codecs[CodecKind.arrayToBytes]; const impl = codecRegistry[CodecKind.arrayToBytes].get(codec.name); @@ -123,7 +118,7 @@ export async function decodeArray( codec.configuration, codecs.arrayInfo[codecs.arrayInfo.length - 1], encoded, - cancellationToken, + signal, ); } @@ -138,7 +133,7 @@ export async function decodeArray( codec.configuration, codecs.arrayInfo[i], decoded, - cancellationToken, + signal, ); } @@ -148,7 +143,7 @@ export async function decodeArray( export function applySharding( chunkManager: ChunkManager, codecs: CodecChainSpec, - baseKvStore: ReadableKvStore, + baseKvStore: KvStoreWithPath, ): { kvStore: ReadableKvStore; getChunkKey: ( @@ -157,7 +152,7 @@ export function applySharding( ) => unknown; decodeCodecs: CodecChainSpec; } { - let kvStore: ReadableKvStore = baseKvStore; + let kvStore: ReadableKvStore = baseKvStore.store; let curCodecs = codecs; while (true) { const { shardingInfo } = curCodecs; @@ -177,11 +172,13 @@ export function applySharding( const decodeCodecs = curCodecs; + const pathPrefix = baseKvStore.path; + function getChunkKey( chunkGridPosition: ArrayLike, baseKey: string, ): unknown { - let key: unknown = baseKey; + let key: unknown = pathPrefix + baseKey; const rank = chunkGridPosition.length; let curCodecs = codecs; while (curCodecs.shardingInfo !== undefined) { diff --git a/src/datasource/zarr/codec/gzip/decode.ts b/src/datasource/zarr/codec/gzip/decode.ts index 3be3ef77e9..f2f9263df7 100644 --- a/src/datasource/zarr/codec/gzip/decode.ts +++ b/src/datasource/zarr/codec/gzip/decode.ts @@ -14,27 +14,23 @@ * limitations under the License. */ -import { decodeGzip } from "#src/async_computation/decode_gzip_request.js"; -import { requestAsyncComputation } from "#src/async_computation/request.js"; import { registerCodec } from "#src/datasource/zarr/codec/decode.js"; import type { Configuration } from "#src/datasource/zarr/codec/gzip/resolve.js"; import { CodecKind } from "#src/datasource/zarr/codec/index.js"; -import type { CancellationToken } from "#src/util/cancellation.js"; +import { decodeGzip } from "#src/util/gzip.js"; -registerCodec({ - name: "gzip", - kind: CodecKind.bytesToBytes, - decode( - configuration: Configuration, - encoded: Uint8Array, - cancellationToken: CancellationToken, - ): Promise { - configuration; - return requestAsyncComputation( - decodeGzip, - cancellationToken, - [encoded.buffer], - encoded, - ); - }, -}); +for (const [name, compressionFormat] of [ + ["gzip", "gzip"], + ["zlib", "deflate"], +] as const) { + registerCodec({ + name, + kind: CodecKind.bytesToBytes, + async decode(configuration: Configuration, encoded, signal: AbortSignal) { + configuration; + return new Uint8Array( + await decodeGzip(encoded, compressionFormat, signal), + ); + }, + }); +} diff --git a/src/datasource/zarr/codec/gzip/resolve.ts b/src/datasource/zarr/codec/gzip/resolve.ts index eec56f4c64..60d058247d 100644 --- a/src/datasource/zarr/codec/gzip/resolve.ts +++ b/src/datasource/zarr/codec/gzip/resolve.ts @@ -26,12 +26,14 @@ export interface Configuration { level: number; } -registerCodec({ - name: "gzip", - kind: CodecKind.bytesToBytes, - resolve(configuration: unknown): { configuration: Configuration } { - verifyObject(configuration); - const level = verifyObjectProperty(configuration, "level", verifyInt); - return { configuration: { level } }; - }, -}); +for (const name of ["gzip", "zlib"]) { + registerCodec({ + name, + kind: CodecKind.bytesToBytes, + resolve(configuration: unknown): { configuration: Configuration } { + verifyObject(configuration); + const level = verifyObjectProperty(configuration, "level", verifyInt); + return { configuration: { level } }; + }, + }); +} diff --git a/src/datasource/zarr/codec/sharding_indexed/decode.ts b/src/datasource/zarr/codec/sharding_indexed/decode.ts index 1c7a97ba0b..dbcb08bdaf 100644 --- a/src/datasource/zarr/codec/sharding_indexed/decode.ts +++ b/src/datasource/zarr/codec/sharding_indexed/decode.ts @@ -21,29 +21,80 @@ import { registerCodec, } from "#src/datasource/zarr/codec/decode.js"; import { CodecKind } from "#src/datasource/zarr/codec/index.js"; -import type { Configuration } from "#src/datasource/zarr/codec/sharding_indexed/resolve.js"; +import type { + Configuration, + IndexConfiguration, +} from "#src/datasource/zarr/codec/sharding_indexed/resolve.js"; import { ShardIndexLocation } from "#src/datasource/zarr/codec/sharding_indexed/resolve.js"; +import { FileByteRangeHandle } from "#src/kvstore/byte_range/file_handle.js"; import type { ByteRangeRequest, ReadableKvStore, - ReadOptions, + DriverReadOptions, ReadResponse, + StatResponse, + StatOptions, + ByteRange, } from "#src/kvstore/index.js"; -import { composeByteRangeRequest } from "#src/kvstore/index.js"; -import type { CancellationToken } from "#src/util/cancellation.js"; -import { uncancelableToken } from "#src/util/cancellation.js"; +import { KvStoreFileHandle } from "#src/kvstore/index.js"; import type { Owned } from "#src/util/disposable.js"; import { RefCounted } from "#src/util/disposable.js"; +import type { ProgressOptions } from "#src/util/progress_listener.js"; type ShardIndex = BigUint64Array | undefined; const MISSING_VALUE = BigInt("18446744073709551615"); +type ShardIndexCache = SimpleAsyncCache; + +function makeIndexCache( + chunkManager: ChunkManager, + base: ReadableKvStore, + configuration: IndexConfiguration, +): ShardIndexCache { + return new SimpleAsyncCache(chunkManager.addRef(), { + get: async (key: BaseKey, progressOptions: ProgressOptions) => { + const { indexCodecs } = configuration; + const encodedSize = + indexCodecs.encodedSize[indexCodecs.encodedSize.length - 1]; + let byteRange: ByteRangeRequest; + switch (configuration.indexLocation) { + case ShardIndexLocation.START: + byteRange = { offset: 0, length: encodedSize! }; + break; + case ShardIndexLocation.END: + byteRange = { suffixLength: encodedSize! }; + break; + } + const response = await base.read(key, { + ...progressOptions, + byteRange, + }); + if (response === undefined) { + return { size: 0, data: undefined }; + } + const index = await decodeArray( + configuration.indexCodecs, + new Uint8Array(await response.response.arrayBuffer()), + progressOptions.signal, + ); + return { + size: index.byteLength, + data: new BigUint64Array( + index.buffer, + index.byteOffset, + index.byteLength / 8, + ), + }; + }, + }); +} + class ShardedKvStore extends RefCounted implements ReadableKvStore<{ base: BaseKey; subChunk: number[] }> { - private indexCache: Owned>; + private indexCache: Owned>; private indexStrides: number[]; constructor( private configuration: Configuration, @@ -52,42 +103,7 @@ class ShardedKvStore ) { super(); this.indexCache = this.registerDisposer( - new SimpleAsyncCache(chunkManager.addRef(), { - get: async (key: BaseKey, cancellationToken: CancellationToken) => { - const { indexCodecs } = configuration; - const encodedSize = - indexCodecs.encodedSize[indexCodecs.encodedSize.length - 1]; - let byteRange: ByteRangeRequest; - switch (configuration.indexLocation) { - case ShardIndexLocation.START: - byteRange = { offset: 0, length: encodedSize! }; - break; - case ShardIndexLocation.END: - byteRange = { suffixLength: encodedSize! }; - break; - } - const response = await base.read(key, { - cancellationToken, - byteRange, - }); - if (response === undefined) { - return { size: 0, data: undefined }; - } - const index = await decodeArray( - configuration.indexCodecs, - response.data, - cancellationToken, - ); - return { - size: index.byteLength, - data: new BigUint64Array( - index.buffer, - index.byteOffset, - index.byteLength / 8, - ), - }; - }, - }), + makeIndexCache(chunkManager, base, configuration), ); const { subChunkGridShape } = this.configuration; const rank = subChunkGridShape.length; @@ -107,14 +123,14 @@ class ShardedKvStore } } - async read( - key: { base: BaseKey; subChunk: number[] }, - options: ReadOptions, - ): Promise { - const shardIndex = await this.indexCache.get( - key.base, - options.cancellationToken ?? uncancelableToken, - ); + private async findKey( + key: { + base: BaseKey; + subChunk: number[]; + }, + progressOptions: Partial, + ): Promise { + const shardIndex = await this.indexCache.get(key.base, progressOptions); if (shardIndex === undefined) { // Shard not present. return undefined; @@ -133,42 +149,42 @@ class ShardedKvStore // Sub-chunk not present. return undefined; } - const fullByteRange = { + return { offset: Number(dataOffset), length: Number(dataLength), }; - const { outer: outerByteRange, inner: innerByteRange } = - composeByteRangeRequest(fullByteRange, options.byteRange); - if (outerByteRange.length === 0) { - return { - data: new Uint8Array(0), - dataRange: innerByteRange, - totalSize: fullByteRange.length, - }; - } - const response = await this.base.read(key.base, { - cancellationToken: options.cancellationToken, - byteRange: outerByteRange, - }); - if (response === undefined) { - // Shard unexpectedly deleted. - return undefined; - } - if ( - response.dataRange.offset !== outerByteRange.offset || - response.dataRange.length !== outerByteRange.length - ) { - throw new Error( - `Received truncated response, expected ${JSON.stringify( - outerByteRange, - )} but received ${JSON.stringify(response.dataRange)}`, - ); - } - return { - data: response.data, - dataRange: innerByteRange, - totalSize: fullByteRange.length, - }; + } + + async stat( + key: { base: BaseKey; subChunk: number[] }, + options: StatOptions, + ): Promise { + const fullByteRange = await this.findKey(key, options); + if (fullByteRange === undefined) return undefined; + return { totalSize: fullByteRange.length }; + } + + async read( + key: { base: BaseKey; subChunk: number[] }, + options: DriverReadOptions, + ): Promise { + const fullByteRange = await this.findKey(key, options); + if (fullByteRange === undefined) return undefined; + return new FileByteRangeHandle( + new KvStoreFileHandle(this.base, key.base), + fullByteRange, + ).read(options); + } + + getUrl(key: { base: BaseKey; subChunk: number[] }): string { + return `subchunk ${JSON.stringify(key.subChunk)} within shard ${this.base.getUrl(key.base)}`; + } + + get supportsOffsetReads() { + return true; + } + get supportsSuffixReads() { + return true; } } diff --git a/src/datasource/zarr/codec/sharding_indexed/resolve.ts b/src/datasource/zarr/codec/sharding_indexed/resolve.ts index 58fd2212d5..53aa858d02 100644 --- a/src/datasource/zarr/codec/sharding_indexed/resolve.ts +++ b/src/datasource/zarr/codec/sharding_indexed/resolve.ts @@ -38,9 +38,12 @@ export enum ShardIndexLocation { END, } -export interface Configuration { +export interface IndexConfiguration { indexCodecs: CodecChainSpec; indexLocation: ShardIndexLocation; +} + +export interface Configuration extends IndexConfiguration { subChunkCodecs: CodecChainSpec; subChunkShape: number[]; subChunkGridShape: number[]; diff --git a/src/datasource/zarr/codec/transpose/decode.ts b/src/datasource/zarr/codec/transpose/decode.ts index a08d4a36e8..3b15e228a6 100644 --- a/src/datasource/zarr/codec/transpose/decode.ts +++ b/src/datasource/zarr/codec/transpose/decode.ts @@ -18,7 +18,6 @@ import { registerCodec } from "#src/datasource/zarr/codec/decode.js"; import type { CodecArrayInfo } from "#src/datasource/zarr/codec/index.js"; import { CodecKind } from "#src/datasource/zarr/codec/index.js"; import type { Configuration } from "#src/datasource/zarr/codec/transpose/resolve.js"; -import type { CancellationToken } from "#src/util/cancellation.js"; registerCodec({ name: "transpose", @@ -26,11 +25,11 @@ registerCodec({ async decode( configuration: Configuration, decodedArrayInfo: CodecArrayInfo, - encoded: ArrayBufferView, - cancellationToken: CancellationToken, - ): Promise { + encoded, + signal: AbortSignal, + ) { decodedArrayInfo; - cancellationToken; + signal; configuration; return encoded; }, diff --git a/src/datasource/zarr/codec/zstd/decode.ts b/src/datasource/zarr/codec/zstd/decode.ts index f29aef6dbd..157ebf7a57 100644 --- a/src/datasource/zarr/codec/zstd/decode.ts +++ b/src/datasource/zarr/codec/zstd/decode.ts @@ -19,20 +19,15 @@ import { requestAsyncComputation } from "#src/async_computation/request.js"; import { registerCodec } from "#src/datasource/zarr/codec/decode.js"; import { CodecKind } from "#src/datasource/zarr/codec/index.js"; import type { Configuration } from "#src/datasource/zarr/codec/zstd/resolve.js"; -import type { CancellationToken } from "#src/util/cancellation.js"; registerCodec({ name: "zstd", kind: CodecKind.bytesToBytes, - decode( - configuration: Configuration, - encoded: Uint8Array, - cancellationToken: CancellationToken, - ): Promise { + decode(configuration: Configuration, encoded, signal: AbortSignal) { configuration; return requestAsyncComputation( decodeZstd, - cancellationToken, + signal, [encoded.buffer], encoded, ); diff --git a/src/datasource/zarr/frontend.ts b/src/datasource/zarr/frontend.ts index d27f478097..3060a75fe6 100644 --- a/src/datasource/zarr/frontend.ts +++ b/src/datasource/zarr/frontend.ts @@ -18,7 +18,6 @@ import "#src/datasource/zarr/codec/blosc/resolve.js"; import "#src/datasource/zarr/codec/zstd/resolve.js"; import { makeDataBoundsBoundingBoxAnnotationSet } from "#src/annotation/index.js"; -import type { ChunkManager } from "#src/chunk_manager/frontend.js"; import { WithParameters } from "#src/chunk_manager/frontend.js"; import type { CoordinateSpace } from "#src/coordinate_transform.js"; import { @@ -26,13 +25,12 @@ import { makeIdentityTransform, makeIdentityTransformedBoundingBox, } from "#src/coordinate_transform.js"; -import { WithCredentialsProvider } from "#src/credentials_provider/chunk_source_frontend.js"; import type { - CompleteUrlOptions, DataSource, - GetDataSourceOptions, + GetKvStoreBasedDataSourceOptions, + KvStoreBasedDataSourceProvider, } from "#src/datasource/index.js"; -import { DataSourceProvider } from "#src/datasource/index.js"; +import { getKvStorePathCompletions } from "#src/datasource/kvstore_completions.js"; import { VolumeChunkSourceParameters } from "#src/datasource/zarr/base.js"; import "#src/datasource/zarr/codec/bytes/resolve.js"; import "#src/datasource/zarr/codec/crc32c/resolve.js"; @@ -53,6 +51,16 @@ import { } from "#src/datasource/zarr/metadata/parse.js"; import type { OmeMultiscaleMetadata } from "#src/datasource/zarr/ome.js"; import { parseOmeMetadata } from "#src/datasource/zarr/ome.js"; +import type { AutoDetectRegistry } from "#src/kvstore/auto_detect.js"; +import { simpleFilePresenceAutoDetectDirectorySpec } from "#src/kvstore/auto_detect.js"; +import { WithSharedKvStoreContext } from "#src/kvstore/chunk_source_frontend.js"; +import type { CompletionResult } from "#src/kvstore/context.js"; +import type { SharedKvStoreContext } from "#src/kvstore/frontend.js"; +import { + kvstoreEnsureDirectoryPipelineUrl, + parseUrlSuffix, + pipelineUrlJoin, +} from "#src/kvstore/url.js"; import type { SliceViewSingleResolutionSource } from "#src/sliceview/frontend.js"; import type { VolumeSourceOptions } from "#src/sliceview/volume/base.js"; import { @@ -69,27 +77,17 @@ import { applyCompletionOffset, completeQueryStringParametersFromTable, } from "#src/util/completion.js"; -import type { Borrowed } from "#src/util/disposable.js"; -import { completeHttpPath } from "#src/util/http_path_completion.js"; -import { isNotFoundError, responseJson } from "#src/util/http_request.js"; import { parseQueryStringParameters, verifyObject, verifyOptionalObjectProperty, } from "#src/util/json.js"; import * as matrix from "#src/util/matrix.js"; -import { getObjectId } from "#src/util/object_id.js"; -import type { - SpecialProtocolCredentials, - SpecialProtocolCredentialsProvider, -} from "#src/util/special_protocol_request.js"; -import { - cancellableFetchSpecialOk, - parseSpecialUrl, -} from "#src/util/special_protocol_request.js"; +import type { ProgressOptions } from "#src/util/progress_listener.js"; +import { ProgressSpan } from "#src/util/progress_listener.js"; class ZarrVolumeChunkSource extends WithParameters( - WithCredentialsProvider()(VolumeChunkSource), + WithSharedKvStoreContext(VolumeChunkSource), VolumeChunkSourceParameters, ) {} @@ -109,11 +107,10 @@ export class MultiscaleVolumeChunkSource extends GenericMultiscaleVolumeChunkSou } constructor( - chunkManager: Borrowed, - public credentialsProvider: SpecialProtocolCredentialsProvider, + public sharedKvStoreContext: SharedKvStoreContext, public multiscale: ZarrMultiscaleInfo, ) { - super(chunkManager); + super(sharedKvStoreContext.chunkManager); this.volumeType = VolumeType.IMAGE; } @@ -160,7 +157,7 @@ export class MultiscaleVolumeChunkSource extends GenericMultiscaleVolumeChunkSou chunkSource: this.chunkManager.getChunkSource( ZarrVolumeChunkSource, { - credentialsProvider: this.credentialsProvider, + sharedKvStoreContext: this.sharedKvStoreContext, spec, parameters: { url: scale.url, @@ -177,28 +174,27 @@ export class MultiscaleVolumeChunkSource extends GenericMultiscaleVolumeChunkSou } function getJsonResource( - chunkManager: ChunkManager, - credentialsProvider: SpecialProtocolCredentialsProvider, + sharedKvStoreContext: SharedKvStoreContext, url: string, + description: string, + options: Partial, ): Promise { - return chunkManager.memoize.getUncounted( + return sharedKvStoreContext.chunkManager.memoize.getAsync( { type: "zarr:json", url, - credentialsProvider: getObjectId(credentialsProvider), }, - async () => { - try { - return await cancellableFetchSpecialOk( - credentialsProvider, - url, - {}, - responseJson, - ); - } catch (e) { - if (isNotFoundError(e)) return undefined; - throw e; - } + options, + async (options) => { + using _span = new ProgressSpan(options.progressListener, { + message: `Reading ${description} from ${url}`, + }); + const response = await sharedKvStoreContext.kvStoreContext.read( + url, + options, + ); + if (response === undefined) return undefined; + return await response.response.json(); }, ); } @@ -297,26 +293,19 @@ function getMultiscaleInfoForSingleArray( } async function resolveOmeMultiscale( - chunkManager: ChunkManager, - credentialsProvider: SpecialProtocolCredentialsProvider, + sharedKvStoreContext: SharedKvStoreContext, multiscale: OmeMultiscaleMetadata, options: { explicitDimensionSeparator: DimensionSeparator | undefined; zarrVersion: 2 | 3; - }, + } & Partial, ): Promise { const scaleZarrMetadata = await Promise.all( multiscale.scales.map(async (scale) => { - const metadata = await getMetadata( - chunkManager, - credentialsProvider, - scale.url, - { - zarrVersion: options.zarrVersion, - expectedNodeType: "array", - explicitDimensionSeparator: options.explicitDimensionSeparator, - }, - ); + const metadata = await getMetadata(sharedKvStoreContext, scale.url, { + ...options, + expectedNodeType: "array", + }); if (metadata === undefined) { throw new Error( `zarr v{zarrVersion} array metadata not found at ${scale.url}`, @@ -386,19 +375,28 @@ async function resolveOmeMultiscale( } async function getMetadata( - chunkManager: ChunkManager, - credentialsProvider: SpecialProtocolCredentialsProvider, + sharedKvStoreContext: SharedKvStoreContext, url: string, options: { zarrVersion?: 2 | 3 | undefined; expectedNodeType?: NodeType | undefined; explicitDimensionSeparator?: DimensionSeparator | undefined; - }, + } & Partial, ): Promise { if (options.zarrVersion === 2) { const [zarray, zattrs] = await Promise.all([ - getJsonResource(chunkManager, credentialsProvider, `${url}/.zarray`), - getJsonResource(chunkManager, credentialsProvider, `${url}/.zattrs`), + getJsonResource( + sharedKvStoreContext, + `${url}.zarray`, + "zarr v2 array metadata", + options, + ), + getJsonResource( + sharedKvStoreContext, + `${url}.zattrs`, + "zarr v2 attributes", + options, + ), ]); if (zarray === undefined) { if (zattrs === undefined) { @@ -424,9 +422,10 @@ async function getMetadata( } if (options.zarrVersion === 3) { const zarrJson = await getJsonResource( - chunkManager, - credentialsProvider, - `${url}/zarr.json`, + sharedKvStoreContext, + `${url}zarr.json`, + "zarr v3 metadata", + options, ); if (zarrJson === undefined) return undefined; if (options.explicitDimensionSeparator !== undefined) { @@ -437,11 +436,11 @@ async function getMetadata( return parseV3Metadata(zarrJson, options.expectedNodeType); } const [v2Result, v3Result] = await Promise.all([ - getMetadata(chunkManager, credentialsProvider, url, { + getMetadata(sharedKvStoreContext, url, { ...options, zarrVersion: 2, }), - getMetadata(chunkManager, credentialsProvider, url, { + getMetadata(sharedKvStoreContext, url, { ...options, zarrVersion: 3, }), @@ -452,77 +451,99 @@ async function getMetadata( return v2Result ?? v3Result; } -export class ZarrDataSource extends DataSourceProvider { - constructor(public zarrVersion: 2 | 3 | undefined = undefined) { - super(); +function resolveUrl(options: GetKvStoreBasedDataSourceOptions) { + const { + authorityAndPath: additionalPath, + query, + fragment, + } = parseUrlSuffix(options.url.suffix); + + if (query) { + throw new Error( + `Invalid URL ${JSON.stringify(options.url.url)}: query parameters not supported`, + ); + } + return { + kvStoreUrl: kvstoreEnsureDirectoryPipelineUrl(options.kvStoreUrl), + additionalPath: additionalPath ?? "", + fragment, + }; +} + +export class ZarrDataSource implements KvStoreBasedDataSourceProvider { + constructor(public zarrVersion: 2 | 3 | undefined = undefined) {} + get scheme() { + return `zarr${this.zarrVersion ?? ""}`; + } + get expectsDirectory() { + return true; } get description() { const versionStr = this.zarrVersion === undefined ? "" : ` v${this.zarrVersion}`; return `Zarr${versionStr} data source`; } - get(options: GetDataSourceOptions): Promise { - // Pattern is infallible. - let [, providerUrl, query] = - options.providerUrl.match(/([^?]*)(?:\?(.*))?$/)!; - const parameters = parseQueryStringParameters(query || ""); + get(options: GetKvStoreBasedDataSourceOptions): Promise { + let { kvStoreUrl, additionalPath, fragment } = resolveUrl(options); + kvStoreUrl = kvstoreEnsureDirectoryPipelineUrl( + pipelineUrlJoin(kvStoreUrl, additionalPath), + ); + const parameters = parseQueryStringParameters(fragment || ""); verifyObject(parameters); const dimensionSeparator = verifyOptionalObjectProperty( parameters, "dimension_separator", parseDimensionSeparator, ); - if (providerUrl.endsWith("/")) { - providerUrl = providerUrl.substring(0, providerUrl.length - 1); - } - return options.chunkManager.memoize.getUncounted( + return options.registry.chunkManager.memoize.getAsync( { type: "zarr:MultiscaleVolumeChunkSource", - providerUrl, + kvStoreUrl, dimensionSeparator, }, - async () => { - const { url, credentialsProvider } = parseSpecialUrl( - providerUrl, - options.credentialsManager, - ); - const metadata = await getMetadata( - options.chunkManager, - credentialsProvider, - url, - { - zarrVersion: this.zarrVersion, - explicitDimensionSeparator: dimensionSeparator, - }, - ); + options, + async (progressOptions) => { + const { sharedKvStoreContext } = options.registry; + const metadata = await getMetadata(sharedKvStoreContext, kvStoreUrl, { + ...progressOptions, + zarrVersion: this.zarrVersion, + explicitDimensionSeparator: dimensionSeparator, + }); if (metadata === undefined) { throw new Error("No zarr metadata found"); } let multiscaleInfo: ZarrMultiscaleInfo; if (metadata.nodeType === "group") { // May be an OME-zarr multiscale dataset. - const multiscale = parseOmeMetadata(url, metadata.userAttributes); + const multiscale = parseOmeMetadata( + kvStoreUrl, + metadata.userAttributes, + metadata.zarrVersion, + ); if (multiscale === undefined) { - throw new Error("Neithre array nor OME multiscale metadata found"); + throw new Error("Neither array nor OME multiscale metadata found"); } multiscaleInfo = await resolveOmeMultiscale( - options.chunkManager, - credentialsProvider, + sharedKvStoreContext, multiscale, { + ...progressOptions, zarrVersion: metadata.zarrVersion, explicitDimensionSeparator: dimensionSeparator, }, ); } else { - multiscaleInfo = getMultiscaleInfoForSingleArray(url, metadata); + multiscaleInfo = getMultiscaleInfoForSingleArray( + kvStoreUrl, + metadata, + ); } const volume = new MultiscaleVolumeChunkSource( - options.chunkManager, - credentialsProvider, + sharedKvStoreContext, multiscaleInfo, ); return { + canonicalUrl: `${kvStoreUrl}|zarr${metadata.zarrVersion}:`, modelTransform: makeIdentityTransform(volume.modelSpace), subsources: [ { @@ -546,23 +567,46 @@ export class ZarrDataSource extends DataSourceProvider { }, ); } - - async completeUrl(options: CompleteUrlOptions) { - // Pattern is infallible. - const [, , query] = options.providerUrl.match(/([^?]*)(?:\?(.*))?$/)!; - if (query !== undefined) { - return applyCompletionOffset( - options.providerUrl.length - query.length, - await completeQueryStringParametersFromTable( - query, - supportedQueryParameters, - ), - ); + async completeUrl( + options: GetKvStoreBasedDataSourceOptions, + ): Promise { + const { kvStoreUrl, additionalPath, fragment } = resolveUrl(options); + if (fragment === undefined) { + return getKvStorePathCompletions(options.registry.sharedKvStoreContext, { + baseUrl: kvStoreUrl, + path: additionalPath, + directoryOnly: true, + signal: options.signal, + progressListener: options.progressListener, + }); + } + if (this.zarrVersion === 3) { + throw new Error("URL fragment parameters not supported"); } - return await completeHttpPath( - options.credentialsManager, - options.providerUrl, - options.cancellationToken, + return applyCompletionOffset( + options.url.url.length - fragment.length, + await completeQueryStringParametersFromTable( + fragment, + supportedQueryParameters, + ), ); } } + +export function registerAutoDetectV2(registry: AutoDetectRegistry) { + registry.registerDirectoryFormat( + simpleFilePresenceAutoDetectDirectorySpec(new Set([".zarray", ".zattrs"]), { + suffix: "zarr2:", + description: "Zarr v2 data source", + }), + ); +} + +export function registerAutoDetectV3(registry: AutoDetectRegistry) { + registry.registerDirectoryFormat( + simpleFilePresenceAutoDetectDirectorySpec(new Set(["zarr.json"]), { + suffix: "zarr3:", + description: "Zarr v3 data source", + }), + ); +} diff --git a/src/datasource/zarr/metadata/parse.ts b/src/datasource/zarr/metadata/parse.ts index af158972b5..3af2732fe0 100644 --- a/src/datasource/zarr/metadata/parse.ts +++ b/src/datasource/zarr/metadata/parse.ts @@ -77,7 +77,7 @@ const UNITS = new Map([ ["foot", { unit: "m", scale: 0.3048 }], ["inch", { unit: "m", scale: 0.0254 }], ["mile", { unit: "m", scale: 1609.34 }], - // eslint-disable-next-line @typescript-eslint/no-loss-of-precision + // eslint-disable-next-line no-loss-of-precision ["parsec", { unit: "m", scale: 3.0856775814913673e16 }], ["yard", { unit: "m", scale: 0.9144 }], ["minute", { unit: "s", scale: 60 }], @@ -396,16 +396,9 @@ export function parseV2Metadata( break; case "zlib": case "gzip": - codecs.push({ - name: "gzip", - configuration: { - level: verifyObjectProperty(compressor, "level", verifyInt), - }, - }); - break; case "zstd": codecs.push({ - name: "zstd", + name: id, configuration: { level: verifyObjectProperty(compressor, "level", verifyInt), }, diff --git a/src/datasource/zarr/ome.ts b/src/datasource/zarr/ome.ts index 91a2455aed..e3f049af56 100644 --- a/src/datasource/zarr/ome.ts +++ b/src/datasource/zarr/ome.ts @@ -39,14 +39,14 @@ export interface OmeMultiscaleMetadata { coordinateSpace: CoordinateSpace; } -const SUPPORTED_OME_MULTISCALE_VERSIONS = new Set(["0.4", "0.5-dev"]); +const SUPPORTED_OME_MULTISCALE_VERSIONS = new Set(["0.4", "0.5-dev", "0.5"]); const OME_UNITS = new Map([ ["angstrom", { unit: "m", scale: 1e-10 }], ["foot", { unit: "m", scale: 0.3048 }], ["inch", { unit: "m", scale: 0.0254 }], ["mile", { unit: "m", scale: 1609.34 }], - // eslint-disable-next-line @typescript-eslint/no-loss-of-precision + // eslint-disable-next-line no-loss-of-precision ["parsec", { unit: "m", scale: 3.0856775814913673e16 }], ["yard", { unit: "m", scale: 0.9144 }], ["minute", { unit: "s", scale: 60 }], @@ -138,7 +138,7 @@ const coordinateTransformParsers = new Map([ function parseOmeCoordinateTransform( rank: number, transformJson: unknown, -): Float64Array { +): Float64Array { verifyObject(transformJson); const transformType = verifyObjectProperty( transformJson, @@ -163,7 +163,7 @@ function parseOmeCoordinateTransforms( parseArray(transforms, (transformJson) => { const newTransform = parseOmeCoordinateTransform(rank, transformJson); transform = matrix.multiply( - new Float64Array(transform.length), + new Float64Array(transform.length) as Float64Array, rank + 1, newTransform, rank + 1, @@ -188,7 +188,7 @@ function parseMultiscaleScale( "coordinateTransformations", (x) => parseOmeCoordinateTransforms(rank, x), ); - const scaleUrl = `${url}/${path}`; + const scaleUrl = `${url}${path}/`; return { url: scaleUrl, transform }; } @@ -211,7 +211,7 @@ function parseOmeMultiscale( parseArray(obj, (x) => { const scale = parseMultiscaleScale(rank, url, x); scale.transform = matrix.multiply( - new Float64Array((rank + 1) ** 2), + new Float64Array((rank + 1) ** 2) as Float64Array, rank + 1, transform, rank + 1, @@ -265,8 +265,11 @@ function parseOmeMultiscale( export function parseOmeMetadata( url: string, attrs: any, + zarrVersion: number, ): OmeMultiscaleMetadata | undefined { - const multiscales = attrs.multiscales; + const ome = attrs.ome; + const multiscales = ome == undefined ? attrs.multiscales : ome.multiscales; // >0.4 + if (!Array.isArray(multiscales)) return undefined; const errors: string[] = []; for (const multiscale of multiscales) { @@ -278,7 +281,9 @@ export function parseOmeMetadata( // Not valid OME multiscale spec. return undefined; } - const version = multiscale.version; + + const version = ome == undefined ? multiscale.version : ome.version; // >0.4 + if (version === undefined) return undefined; if (!SUPPORTED_OME_MULTISCALE_VERSIONS.has(version)) { errors.push( @@ -288,6 +293,14 @@ export function parseOmeMetadata( ); continue; } + if (version === "0.5" && zarrVersion !== 3) { + errors.push( + `OME multiscale metadata version ${JSON.stringify( + version, + )} is not supported for zarr v${zarrVersion}`, + ); + continue; + } return parseOmeMultiscale(url, multiscale); } if (errors.length !== 0) { diff --git a/src/datasource/zarr/register_default.ts b/src/datasource/zarr/register_default.ts index 7046d2bc82..a1813881b7 100644 --- a/src/datasource/zarr/register_default.ts +++ b/src/datasource/zarr/register_default.ts @@ -14,9 +14,25 @@ * limitations under the License. */ -import { registerProvider } from "#src/datasource/default_provider.js"; -import { ZarrDataSource } from "#src/datasource/zarr/frontend.js"; +import { + registerKvStoreBasedDataProvider, + dataSourceAutoDetectRegistry, + registerProvider, +} from "#src/datasource/default_provider.js"; +import { KvStoreBasedDataSourceLegacyUrlAdapter } from "#src/datasource/index.js"; +import { + ZarrDataSource, + registerAutoDetectV2, + registerAutoDetectV3, +} from "#src/datasource/zarr/frontend.js"; -registerProvider("zarr", () => new ZarrDataSource()); -registerProvider("zarr2", () => new ZarrDataSource(2)); -registerProvider("zarr3", () => new ZarrDataSource(3)); +for (const provider of [ + new ZarrDataSource(), + new ZarrDataSource(2), + new ZarrDataSource(3), +]) { + registerKvStoreBasedDataProvider(provider); + registerProvider(new KvStoreBasedDataSourceLegacyUrlAdapter(provider)); +} +registerAutoDetectV2(dataSourceAutoDetectRegistry); +registerAutoDetectV3(dataSourceAutoDetectRegistry); diff --git a/src/display_context.ts b/src/display_context.ts index 0438391f57..f3c90ecddc 100644 --- a/src/display_context.ts +++ b/src/display_context.ts @@ -115,7 +115,7 @@ export abstract class RenderedPanel extends RefCounted { renderViewport = new RenderViewport(); - private monitorState: PanelMonitorState = {}; + private monitorState: PanelMonitorState = { isIntersecting: true }; constructor( public context: Borrowed, @@ -386,6 +386,13 @@ interface PanelMonitorState { // detections due to normalization that the browser may do. intersectionObserverMargin?: string; + // Indicates that the element is intersecting the viewport at all. If `true`, + // then the intersection observer margin is set normally to detect any + // changes. If `false`, then the intersection observer margin is set to cover + // the entire viewport in order to detect when the panel becomes visible + // again. + isIntersecting: boolean; + // Indicates that the panel element was added to the resize observer. addedToResizeObserver?: boolean; } @@ -430,21 +437,37 @@ export class DisplayContext extends RefCounted implements FrameNumberCounter { this.resizeObserver.observe(element); state.addedToResizeObserver = true; } - const rootRect = this.rootRect!; - const marginTop = rootRect.top - elementClientRect.top; - const marginLeft = rootRect.left - elementClientRect.left; - const marginRight = elementClientRect.right - rootRect.right; - const marginBottom = elementClientRect.bottom - rootRect.bottom; - const margin = `${marginTop}px ${marginRight}px ${marginBottom}px ${marginLeft}px`; + let margin: string; + if (state.isIntersecting) { + const rootRect = this.rootRect!; + const marginTop = rootRect.top - elementClientRect.top; + const marginLeft = rootRect.left - elementClientRect.left; + const marginRight = elementClientRect.right - rootRect.right; + const marginBottom = elementClientRect.bottom - rootRect.bottom; + margin = `${marginTop}px ${marginRight}px ${marginBottom}px ${marginLeft}px`; + } else { + margin = ""; + } if (state.intersectionObserverMargin !== margin) { state.intersectionObserverMargin = margin; state.intersectionObserver?.disconnect(); + const thresholds = new Array(101); + for (let i = 0; i <= 100; ++i) { + thresholds[i] = 0.01 * i; + } const intersectionObserver = (state.intersectionObserver = - new IntersectionObserver(this.resizeCallback, { - root: this.container, - rootMargin: margin, - threshold: [0.93, 0.94, 0.95, 0.96, 0.97, 0.98, 0.99, 1], - })); + new IntersectionObserver( + (entries) => { + const lastEntry = entries[entries.length - 1]; + state.isIntersecting = lastEntry.isIntersecting; + this.resizeCallback(); + }, + { + root: this.container, + rootMargin: margin, + threshold: thresholds, + }, + )); intersectionObserver.observe(element); } } diff --git a/src/gpu_hash/hash_table.ts b/src/gpu_hash/hash_table.ts index e80c41f536..122de83e86 100644 --- a/src/gpu_hash/hash_table.ts +++ b/src/gpu_hash/hash_table.ts @@ -47,7 +47,7 @@ export abstract class HashTableBase { /** * Number of uint32 elements per entry in hash table. */ - entryStride: number; + declare entryStride: number; generation = 0; diff --git a/src/gpu_hash/shader.ts b/src/gpu_hash/shader.ts index 39dbd75681..af44a0b97b 100644 --- a/src/gpu_hash/shader.ts +++ b/src/gpu_hash/shader.ts @@ -98,19 +98,26 @@ export class GPUHashTable extends RefCounted { } export class HashSetShaderManager { - textureUnitSymbol = Symbol.for(`gpuhashtable:${this.prefix}`); - private accessHelper = new OneDimensionalTextureAccessHelper( - `gpuhashtable_${this.prefix}`, - ); - samplerName = this.prefix + "_sampler"; - hashSeedsName = this.prefix + "_seeds"; - hashKeyMask = this.prefix + "_keyMask"; - readTable = this.prefix + "_readTable"; + textureUnitSymbol: symbol; + private accessHelper: OneDimensionalTextureAccessHelper; + samplerName: string; + hashSeedsName: string; + hashKeyMask: string; + readTable: string; constructor( public prefix: string, public numAlternatives = NUM_ALTERNATIVES, - ) {} + ) { + this.textureUnitSymbol = Symbol.for(`gpuhashtable:${this.prefix}`); + this.accessHelper = new OneDimensionalTextureAccessHelper( + `gpuhashtable_${this.prefix}`, + ); + this.samplerName = prefix + "_sampler"; + this.hashSeedsName = prefix + "_seeds"; + this.hashKeyMask = prefix + "_keyMask"; + this.readTable = prefix + "_readTable"; + } defineShader(builder: ShaderBuilder) { const { hashSeedsName, samplerName, numAlternatives, hashKeyMask } = this; diff --git a/src/kvstore/auto_detect.ts b/src/kvstore/auto_detect.ts new file mode 100644 index 0000000000..d13f19482d --- /dev/null +++ b/src/kvstore/auto_detect.ts @@ -0,0 +1,332 @@ +/** + * @license + * Copyright 2025 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { KvStoreContext } from "#src/kvstore/context.js"; +import { readKvStore } from "#src/kvstore/index.js"; +import { pathIsDirectory } from "#src/kvstore/url.js"; +import { isGzipFormat } from "#src/util/gzip.js"; +import type { ProgressOptions } from "#src/util/progress_listener.js"; +import { ProgressSpan } from "#src/util/progress_listener.js"; + +export interface AutoDetectDirectoryOptions { + url: string; + fileNames: Set; + signal?: AbortSignal; +} + +export interface AutoDetectMatch { + suffix: string; + description: string; +} + +export interface AutoDetectDirectorySpec { + fileNames: Set; + match: (options: AutoDetectDirectoryOptions) => Promise; +} + +export function simpleFilePresenceAutoDetectDirectorySpec( + fileNames: Set, + match: AutoDetectMatch, +): AutoDetectDirectorySpec { + return { + fileNames, + match: async (options) => { + const detectedFileNames = options.fileNames; + for (const fileName of fileNames) { + if (detectedFileNames.has(fileName)) { + return [match]; + } + } + return []; + }, + }; +} + +export interface AutoDetectFileOptions { + url: string; + prefix: Uint8Array; + suffix?: Uint8Array; + totalSize: number | undefined; + signal?: AbortSignal; +} + +export interface AutoDetectFileSpec { + prefixLength: number; + suffixLength: number; + match: (options: AutoDetectFileOptions) => Promise; +} + +function composeMatchFunctions( + specs: { + match: (options: Options) => Promise; + }[], +): (options: Options) => Promise { + return async (options: Options) => { + const matches: AutoDetectMatch[] = []; + const results = await Promise.allSettled( + specs.map((spec) => spec.match(options)), + ); + for (const result of results) { + if (result.status !== "fulfilled") continue; + matches.push(...result.value); + } + return matches; + }; +} + +export function composeAutoDetectDirectorySpecs( + specs: AutoDetectDirectorySpec[], +): AutoDetectDirectorySpec { + const fileNames = new Set(); + for (const spec of specs) { + for (const fileName of spec.fileNames) { + fileNames.add(fileName); + } + } + return { fileNames, match: composeMatchFunctions(specs) }; +} + +export function composeAutoDetectFileSpecs( + specs: AutoDetectFileSpec[], +): AutoDetectFileSpec { + let prefixLength = 0; + let suffixLength = 0; + for (const spec of specs) { + prefixLength = Math.max(prefixLength, spec.prefixLength); + suffixLength = Math.max(suffixLength, spec.suffixLength); + } + return { prefixLength, suffixLength, match: composeMatchFunctions(specs) }; +} + +export class AutoDetectRegistry { + directorySpecs: AutoDetectDirectorySpec[] = []; + fileSpecs: AutoDetectFileSpec[] = []; + gzipFileSpecs: AutoDetectFileSpec[] = []; + private _directorySpec: AutoDetectDirectorySpec | undefined; + private _fileSpec: AutoDetectFileSpec | undefined; + + registerDirectoryFormat(spec: AutoDetectDirectorySpec) { + this.directorySpecs.push(spec); + this._directorySpec = undefined; + } + + registerFileFormat( + spec: AutoDetectFileSpec, + supportedEncodings?: { gzip?: boolean }, + ) { + this.fileSpecs.push(spec); + if (supportedEncodings?.gzip) { + this.gzipFileSpecs.push(spec); + } + this._fileSpec = undefined; + } + + copyTo(registry: AutoDetectRegistry) { + registry.directorySpecs.push(...this.directorySpecs); + registry.fileSpecs.push(...this.fileSpecs); + registry.gzipFileSpecs.push(...this.gzipFileSpecs); + registry._fileSpec = undefined; + registry._directorySpec = undefined; + } + + get directorySpec() { + return ( + this._directorySpec ?? (this._directorySpec = this.getDirectorySpec()) + ); + } + + private getDirectorySpec() { + return composeAutoDetectDirectorySpecs(this.directorySpecs); + } + + get fileSpec() { + return this._fileSpec ?? (this._fileSpec = this.getFileSpec()); + } + + private getFileSpec() { + const { fileSpecs, gzipFileSpecs } = this; + const specs = [...fileSpecs]; + if (gzipFileSpecs.length > 0) { + specs.push(getGzipFileSpec(composeAutoDetectFileSpecs(gzipFileSpecs))); + } + return composeAutoDetectFileSpecs(specs); + } +} + +export interface AutoDetectFormatOptions extends Partial { + kvStoreContext: KvStoreContext; + url: string; + autoDetectDirectory: () => AutoDetectDirectorySpec; + autoDetectFile: () => AutoDetectFileSpec; +} + +export async function autoDetectFormat( + options: AutoDetectFormatOptions, +): Promise<{ matches: AutoDetectMatch[]; url: string }> { + const kvStore = options.kvStoreContext.getKvStore(options.url); + const { progressListener } = options; + using _span = + progressListener && + new ProgressSpan(progressListener, { + message: `Auto-detecting data format at ${options.url}`, + }); + if (!pathIsDirectory(kvStore.path) || kvStore.store.singleKey === true) { + const statResponse = await kvStore.store.stat(kvStore.path, { + signal: options.signal, + progressListener: options.progressListener, + }); + if (statResponse !== undefined) { + // Match as file. + const autoDetectFile = options.autoDetectFile(); + const { totalSize } = statResponse; + let prefix: Uint8Array; + let suffix: Uint8Array | undefined; + if (totalSize !== undefined && autoDetectFile.suffixLength > 0) { + if ( + totalSize <= + autoDetectFile.prefixLength + autoDetectFile.suffixLength + ) { + // Perform a single read + const readResponse = await readKvStore(kvStore.store, kvStore.path, { + signal: options.signal, + progressListener: options.progressListener, + throwIfMissing: true, + }); + prefix = suffix = new Uint8Array( + await readResponse.response.arrayBuffer(), + ); + } else { + [prefix, suffix] = await Promise.all( + [ + { offset: 0, length: autoDetectFile.prefixLength }, + { + offset: totalSize - autoDetectFile.suffixLength, + length: autoDetectFile.suffixLength, + }, + ].map((byteRange) => + readKvStore(kvStore.store, kvStore.path, { + signal: options.signal, + progressListener: options.progressListener, + throwIfMissing: true, + byteRange, + }) + .then((readResponse) => readResponse.response.arrayBuffer()) + .then((arrayBuffer) => new Uint8Array(arrayBuffer)), + ), + ); + } + } else { + prefix = new Uint8Array( + await ( + await readKvStore(kvStore.store, kvStore.path, { + signal: options.signal, + progressListener: options.progressListener, + throwIfMissing: true, + byteRange: { offset: 0, length: autoDetectFile.prefixLength }, + }) + ).response.arrayBuffer(), + ); + } + return { + matches: await autoDetectFile.match({ + url: options.url, + prefix, + suffix, + totalSize, + signal: options.signal, + }), + url: options.url, + }; + } + + if (kvStore.store.singleKey === true) { + return { matches: [], url: options.url }; + } + kvStore.path += "/"; + } + + const autoDetectDirectory = options.autoDetectDirectory(); + const detectedFileNames = new Set(); + await Promise.all( + Array.from(autoDetectDirectory.fileNames, async (fileName) => { + const response = await kvStore.store.stat(kvStore.path + fileName, { + signal: options.signal, + progressListener: options.progressListener, + }); + if (response !== undefined) { + detectedFileNames.add(fileName); + } + }), + ); + const url = kvStore.store.getUrl(kvStore.path); + const matches = await autoDetectDirectory.match({ + url, + fileNames: detectedFileNames, + signal: options.signal, + }); + return { matches, url }; +} + +function getGzipFileSpec(decodedSpec: AutoDetectFileSpec): AutoDetectFileSpec { + // Heuristic, assume gzip adds at most 100 bytes of overhead. + const prefixLength = decodedSpec.prefixLength + 100; + + async function detect( + options: AutoDetectFileOptions, + ): Promise { + if (!isGzipFormat(options.prefix)) return []; + const decompressedStream = new Response(options.prefix).body!.pipeThrough( + new DecompressionStream("gzip"), + { signal: options.signal }, + ); + let decodedPrefix = new Uint8Array(decodedSpec.prefixLength); + // Decode as much as possible. + let totalLength = 0; + + try { + const reader = decompressedStream.getReader(); + while (true) { + let { value } = await reader.read(); + if (value === undefined) break; + const remainingLength = decodedPrefix.length - totalLength; + if (value.length > remainingLength) { + value = value.subarray(0, remainingLength); + } + decodedPrefix.set(value, totalLength); + totalLength += value.length; + if (totalLength === decodedPrefix.length) { + break; + } + } + } catch { + // Ignore failure, likely due to truncated input. + } + decodedPrefix = decodedPrefix.subarray(0, totalLength); + + const matches = await decodedSpec.match({ + url: options.url, + signal: options.signal, + prefix: decodedPrefix, + totalSize: undefined, + }); + return matches.map(({ suffix, description }) => ({ + suffix, + description: `${description} (gzip-compressed)`, + })); + } + + return { prefixLength, suffixLength: 0, match: detect }; +} diff --git a/src/kvstore/backend.ts b/src/kvstore/backend.ts new file mode 100644 index 0000000000..96748c9d13 --- /dev/null +++ b/src/kvstore/backend.ts @@ -0,0 +1,147 @@ +/** + * @license + * Copyright 2024 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ChunkManager } from "#src/chunk_manager/backend.js"; +import type { SharedCredentialsManagerCounterpart } from "#src/credentials_provider/shared_counterpart.js"; +import { KvStoreContext } from "#src/kvstore/context.js"; +import { + frontendBackendIsomorphicKvStoreProviderRegistry, + KvStoreProviderRegistry, +} from "#src/kvstore/register.js"; +import { + LIST_RPC_ID, + READ_RPC_ID, + SHARED_KVSTORE_CONTEXT_RPC_ID, + STAT_RPC_ID, +} from "#src/kvstore/shared_common.js"; +import type { RPC } from "#src/worker_rpc.js"; +import { + registerPromiseRPC, + registerSharedObject, + SharedObjectCounterpart, +} from "#src/worker_rpc.js"; +import type { ByteRange } from "."; + +@registerSharedObject(SHARED_KVSTORE_CONTEXT_RPC_ID) +export class SharedKvStoreContextCounterpart extends SharedObjectCounterpart { + kvStoreContext: KvStoreContext; + + chunkManager: ChunkManager; + credentialsManager: SharedCredentialsManagerCounterpart; + + constructor(rpc: RPC, options: any) { + super(rpc, options); + this.chunkManager = rpc.get(options.chunkManager) as ChunkManager; + this.credentialsManager = rpc.get( + options.credentialsManager, + ) as SharedCredentialsManagerCounterpart; + this.kvStoreContext = new KvStoreContext(); + frontendBackendIsomorphicKvStoreProviderRegistry.applyToContext(this); + backendOnlyKvStoreProviderRegistry.applyToContext(this); + } +} + +export const backendOnlyKvStoreProviderRegistry = + new KvStoreProviderRegistry(); + +export function WithSharedKvStoreContextCounterpart< + TBase extends { new (...args: any[]): SharedObjectCounterpart }, +>(Base: TBase) { + return class extends Base { + sharedKvStoreContext: SharedKvStoreContextCounterpart; + constructor(...args: any[]) { + super(...args); + const options = args[1]; + this.sharedKvStoreContext = this.rpc!.get(options.sharedKvStoreContext); + } + }; +} + +registerPromiseRPC( + STAT_RPC_ID, + async function ( + this: RPC, + options: { sharedKvStoreContext: number; url: string }, + progressOptions, + ) { + const sharedKvStoreContext: SharedKvStoreContextCounterpart = this.get( + options.sharedKvStoreContext, + ); + return { + value: await sharedKvStoreContext.kvStoreContext.stat( + options.url, + progressOptions, + ), + }; + }, +); + +registerPromiseRPC( + READ_RPC_ID, + async function ( + this: RPC, + options: { + sharedKvStoreContext: number; + url: string; + byteRange?: ByteRange; + throwIfMissing?: boolean; + }, + progressOptions, + ) { + const sharedKvStoreContext: SharedKvStoreContextCounterpart = this.get( + options.sharedKvStoreContext, + ); + const readResponse = await sharedKvStoreContext.kvStoreContext.read( + options.url, + { + ...progressOptions, + byteRange: options.byteRange, + throwIfMissing: options.throwIfMissing, + }, + ); + if (readResponse === undefined) { + return { value: undefined }; + } + const arrayBuffer = await readResponse.response.arrayBuffer(); + return { + value: { + data: arrayBuffer, + offset: readResponse.offset, + totalSize: readResponse.totalSize, + }, + transfers: [arrayBuffer], + }; + }, +); + +registerPromiseRPC( + LIST_RPC_ID, + async function ( + this: RPC, + options: { sharedKvStoreContext: number; url: string }, + progressOptions, + ) { + const sharedKvStoreContext: SharedKvStoreContextCounterpart = this.get( + options.sharedKvStoreContext, + ); + const { store, path } = sharedKvStoreContext.kvStoreContext.getKvStore( + options.url, + ); + return { + value: await store.list!(path, progressOptions), + }; + }, +); diff --git a/src/kvstore/byte_range/file_handle.ts b/src/kvstore/byte_range/file_handle.ts new file mode 100644 index 0000000000..865ac9068e --- /dev/null +++ b/src/kvstore/byte_range/file_handle.ts @@ -0,0 +1,94 @@ +/** + * @license + * Copyright 2023 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { + ByteRange, + ByteRangeRequest, + DriverReadOptions, + FileHandle, + ReadResponse, + StatOptions, + StatResponse, +} from "#src/kvstore/index.js"; +import { readFileHandle } from "#src/kvstore/index.js"; + +export function composeByteRangeRequest( + outer: ByteRange, + inner: ByteRangeRequest | undefined, +): { outer: ByteRange; inner: ByteRange } { + if (inner === undefined) { + return { outer, inner: { offset: 0, length: outer.length } }; + } + if ("suffixLength" in inner) { + const length = Math.min(outer.length, inner.suffixLength); + return { + outer: { offset: outer.offset + (outer.length - length), length }, + inner: { offset: outer.length - length, length }, + }; + } + if (inner.offset + inner.length > outer.length) { + throw new Error( + `Requested byte range ${JSON.stringify( + inner, + )} not valid for value of length ${outer.length}`, + ); + } + return { + outer: { offset: outer.offset + inner.offset, length: inner.length }, + inner, + }; +} + +export class FileByteRangeHandle implements FileHandle { + constructor( + public base: FileHandle, + public byteRange: ByteRange, + ) {} + + async stat(options: StatOptions): Promise { + options; + return { totalSize: this.byteRange.length }; + } + + async read(options: DriverReadOptions): Promise { + const { byteRange } = this; + const { outer: outerByteRange, inner: innerByteRange } = + composeByteRangeRequest(byteRange, options.byteRange); + if (outerByteRange.length === 0) { + return { + response: new Response(new Uint8Array(0)), + totalSize: byteRange.length, + ...innerByteRange, + }; + } + const response = await readFileHandle(this.base, { + signal: options.signal, + byteRange: outerByteRange, + strictByteRange: true, + throwIfMissing: true, + }); + return { + response: response.response, + totalSize: byteRange.length, + ...innerByteRange, + }; + } + + getUrl() { + const { offset, length } = this.byteRange; + return `${this.base.getUrl()}|range:${offset}-${offset + length}`; + } +} diff --git a/src/kvstore/byte_range/index.ts b/src/kvstore/byte_range/index.ts new file mode 100644 index 0000000000..93c9ae606e --- /dev/null +++ b/src/kvstore/byte_range/index.ts @@ -0,0 +1,75 @@ +/** + * @license + * Copyright 2025 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { FileByteRangeHandle } from "#src/kvstore/byte_range/file_handle.js"; +import type { + DriverReadOptions, + KvStore, + ReadResponse, + StatOptions, + StatResponse, + FileHandle, + ByteRange, +} from "#src/kvstore/index.js"; + +function parseKey(key: string): ByteRange { + const m = key.match(/^([0-9]+)-([0-9]+)$/); + if (m !== null) { + const begin = Number(m[1]); + const end = Number(m[2]); + if (end >= begin) { + return { offset: begin, length: end - begin }; + } + } + throw new Error( + `Invalid key ${JSON.stringify(key)} for "byte-range:", expected "-"`, + ); +} + +export class ByteRangeKvStore implements KvStore { + constructor(public base: FileHandle) {} + + getUrl(key: string) { + return this.base.getUrl() + `|byte-range:${key}`; + } + + async stat( + key: string, + options: StatOptions, + ): Promise { + const { length } = parseKey(key); + options; + return { totalSize: length }; + } + + async read( + key: string, + options: DriverReadOptions, + ): Promise { + const byteRange = parseKey(key); + return new FileByteRangeHandle(this.base, byteRange).read(options); + } + + get supportsOffsetReads() { + return true; + } + get supportsSuffixReads() { + return true; + } + get singleKey() { + return true; + } +} diff --git a/src/kvstore/byte_range/register.ts b/src/kvstore/byte_range/register.ts new file mode 100644 index 0000000000..4bdacc9f70 --- /dev/null +++ b/src/kvstore/byte_range/register.ts @@ -0,0 +1,41 @@ +/** + * @license + * Copyright 2025 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ByteRangeKvStore } from "#src/kvstore/byte_range/index.js"; +import type { KvStoreAdapterProvider } from "#src/kvstore/context.js"; +import { KvStoreFileHandle } from "#src/kvstore/index.js"; +import { frontendBackendIsomorphicKvStoreProviderRegistry } from "#src/kvstore/register.js"; +import { ensureNoQueryOrFragmentParameters } from "#src/kvstore/url.js"; + +function byteRangeProvider(): KvStoreAdapterProvider { + return { + scheme: "byte-range", + description: `byte range slicing`, + getKvStore(url, base) { + ensureNoQueryOrFragmentParameters(url); + return { + store: new ByteRangeKvStore( + new KvStoreFileHandle(base.store, base.path), + ), + path: url.suffix ?? "", + }; + }, + }; +} + +frontendBackendIsomorphicKvStoreProviderRegistry.registerKvStoreAdapterProvider( + byteRangeProvider, +); diff --git a/src/kvstore/chunk_source_frontend.ts b/src/kvstore/chunk_source_frontend.ts new file mode 100644 index 0000000000..a626923c12 --- /dev/null +++ b/src/kvstore/chunk_source_frontend.ts @@ -0,0 +1,55 @@ +/** + * @license + * Copyright 2017 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file Facilities to simplify defining subclasses of ChunkSource that use a CredentialsProvider. + */ + +import type { + ChunkManager, + ChunkSourceConstructor, + GettableChunkSource, +} from "#src/chunk_manager/frontend.js"; +import type { SharedKvStoreContext } from "#src/kvstore/frontend.js"; +import type { RPC } from "#src/worker_rpc.js"; + +/** + * Mixin for adding a credentialsProvider member to a ChunkSource. + */ +export function WithSharedKvStoreContext< + TBase extends ChunkSourceConstructor< + GettableChunkSource & { chunkManager: ChunkManager } + >, +>(Base: TBase) { + type WithSharedKvStoreContextOptions = InstanceType["OPTIONS"] & { + sharedKvStoreContext: SharedKvStoreContext; + }; + class C extends Base { + sharedKvStoreContext: SharedKvStoreContext; + declare OPTIONS: WithSharedKvStoreContextOptions; + constructor(...args: any[]) { + super(...args); + const options: WithSharedKvStoreContextOptions = args[1]; + this.sharedKvStoreContext = options.sharedKvStoreContext.addRef(); + } + initializeCounterpart(rpc: RPC, options: any) { + const { sharedKvStoreContext } = this; + options.sharedKvStoreContext = sharedKvStoreContext.rpcId; + super.initializeCounterpart(rpc, options); + } + } + return C; +} diff --git a/src/kvstore/context.ts b/src/kvstore/context.ts new file mode 100644 index 0000000000..564574c027 --- /dev/null +++ b/src/kvstore/context.ts @@ -0,0 +1,138 @@ +/** + * @license + * Copyright 2024 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { AutoDetectRegistry } from "#src/kvstore/auto_detect.js"; +import type { + KvStoreWithPath, + ListResponse, + ReadResponse, + ReadOptions, + ListOptions, + StatOptions, + StatResponse, +} from "#src/kvstore/index.js"; +import { listKvStore, readKvStore } from "#src/kvstore/index.js"; +import type { UrlWithParsedScheme } from "#src/kvstore/url.js"; +import { resolveRelativePath, splitPipelineUrl } from "#src/kvstore/url.js"; +import type { + BasicCompletionResult, + CompletionWithDescription, +} from "#src/util/completion.js"; + +export type CompletionResult = BasicCompletionResult; + +export interface BaseKvStoreProvider { + scheme: string; + hidden?: boolean; + description?: string; + getKvStore(parsedUrl: UrlWithParsedScheme): KvStoreWithPath; +} + +export interface KvStoreAdapterProvider { + scheme: string; + hidden?: boolean; + description?: string; + getKvStore( + parsedUrl: UrlWithParsedScheme, + base: KvStoreWithPath, + ): KvStoreWithPath; +} + +export class KvStoreContext { + baseKvStoreProviders = new Map(); + kvStoreAdapterProviders = new Map(); + autoDetectRegistry = new AutoDetectRegistry(); + + getKvStore(url: string): KvStoreWithPath { + const pipeline = splitPipelineUrl(url); + let kvStore: KvStoreWithPath; + { + const basePart = pipeline[0]; + const provider = this.baseKvStoreProviders.get(basePart.scheme); + if (provider === undefined) { + const usage = this.describeProtocolUsage(basePart.scheme); + let message = `Invalid base kvstore protocol "${basePart.scheme}:"`; + if (usage !== undefined) { + message += `; ${usage}`; + } + throw new Error(message); + } + kvStore = provider.getKvStore(basePart); + } + + for (let i = 1; i < pipeline.length; ++i) { + const part = pipeline[i]; + const provider = this.kvStoreAdapterProviders.get(part.scheme); + if (provider === undefined) { + const usage = this.describeProtocolUsage(part.scheme); + let message = `Invalid kvstore adapter protocol "${part.scheme}:" in ${JSON.stringify(url)}`; + if (usage !== undefined) { + message += `; ${usage}`; + } + throw new Error(message); + } + kvStore = provider.getKvStore(part, kvStore); + } + return kvStore; + } + + // Describes valid uses of `protocol`, for error messages indicating an + // invalid protocol. If the protocol is unknown, returns `undefined`. + describeProtocolUsage(protocol: string): string | undefined { + if (this.baseKvStoreProviders.has(protocol)) { + return `"${protocol}:" may only be used as a base kvstore protocol`; + } + if (this.kvStoreAdapterProviders.has(protocol)) { + return `"${protocol}:" may only be used as a kvstore adapter protocol`; + } + return undefined; + } + + stat( + url: string, + options: StatOptions = {}, + ): Promise { + const kvStore = this.getKvStore(url); + return kvStore.store.stat(kvStore.path, options); + } + + read( + url: string, + options: ReadOptions & { throwIfMissing: true }, + ): Promise; + + read(url: string, options?: ReadOptions): Promise; + + read( + url: string, + options: ReadOptions = {}, + ): Promise { + const kvStore = this.getKvStore(url); + return readKvStore(kvStore.store, kvStore.path, options); + } + + list(urlPrefix: string, options: ListOptions = {}): Promise { + const kvStore = this.getKvStore(urlPrefix); + return listKvStore(kvStore.store, kvStore.path, options); + } + + resolveRelativePath(baseUrl: string, relativePath: string): string { + const kvStore = this.getKvStore(baseUrl); + return kvStore.store.getUrl( + resolveRelativePath(kvStore.path, relativePath), + ); + } +} diff --git a/src/kvstore/enabled_backend_modules.ts b/src/kvstore/enabled_backend_modules.ts new file mode 100644 index 0000000000..873feeb4be --- /dev/null +++ b/src/kvstore/enabled_backend_modules.ts @@ -0,0 +1,9 @@ +// DO NOT EDIT: Generated by config/update_conditions.ts +import "#kvstore/byte_range/register"; +import "#kvstore/gcs/register"; +import "#kvstore/gzip/register"; +import "#kvstore/http/register"; +import "#kvstore/middleauth/register"; +import "#kvstore/ngauth/register"; +import "#kvstore/s3/register"; +import "#kvstore/zip/register_backend"; diff --git a/src/kvstore/enabled_frontend_modules.ts b/src/kvstore/enabled_frontend_modules.ts new file mode 100644 index 0000000000..051976e929 --- /dev/null +++ b/src/kvstore/enabled_frontend_modules.ts @@ -0,0 +1,11 @@ +// DO NOT EDIT: Generated by config/update_conditions.ts +import "#kvstore/byte_range/register"; +import "#kvstore/gcs/register"; +import "#kvstore/gzip/register"; +import "#kvstore/http/register"; +import "#kvstore/middleauth/register"; +import "#kvstore/middleauth/register_credentials_provider"; +import "#kvstore/ngauth/register"; +import "#kvstore/ngauth/register_credentials_provider"; +import "#kvstore/s3/register"; +import "#kvstore/zip/register_frontend"; diff --git a/src/kvstore/frontend.ts b/src/kvstore/frontend.ts new file mode 100644 index 0000000000..4de55f8519 --- /dev/null +++ b/src/kvstore/frontend.ts @@ -0,0 +1,151 @@ +/** + * @license + * Copyright 2024 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ChunkManager } from "#src/chunk_manager/frontend.js"; +import type { SharedCredentialsManager } from "#src/credentials_provider/shared.js"; +import { KvStoreContext } from "#src/kvstore/context.js"; +import type { + DriverListOptions, + DriverReadOptions, + ListResponse, + ReadResponse, + StatOptions, + StatResponse, +} from "#src/kvstore/index.js"; +import type { SharedKvStoreContextBase } from "#src/kvstore/register.js"; +import { + frontendBackendIsomorphicKvStoreProviderRegistry, + KvStoreProviderRegistry, +} from "#src/kvstore/register.js"; +import { + LIST_RPC_ID, + READ_RPC_ID, + SHARED_KVSTORE_CONTEXT_RPC_ID, + STAT_RPC_ID, +} from "#src/kvstore/shared_common.js"; +import { registerSharedObjectOwner, SharedObject } from "#src/worker_rpc.js"; + +@registerSharedObjectOwner(SHARED_KVSTORE_CONTEXT_RPC_ID) +export class SharedKvStoreContext + extends SharedObject + implements SharedKvStoreContextBase +{ + kvStoreContext = new KvStoreContext(); + + constructor( + public chunkManager: ChunkManager, + public credentialsManager: SharedCredentialsManager, + ) { + super(); + this.initializeCounterpart(chunkManager.rpc!, { + chunkManager: chunkManager.rpcId, + credentialsManager: credentialsManager.rpcId, + }); + frontendBackendIsomorphicKvStoreProviderRegistry.applyToContext(this); + frontendOnlyKvStoreProviderRegistry.applyToContext(this); + } +} + +export const frontendOnlyKvStoreProviderRegistry = + new KvStoreProviderRegistry(); + +export function proxyStatToBackendKvStore( + sharedKvStoreContext: SharedKvStoreContext, + url: string, + options: StatOptions, +): Promise { + return sharedKvStoreContext.rpc!.promiseInvoke( + STAT_RPC_ID, + { sharedKvStoreContext: sharedKvStoreContext.rpcId, url }, + { signal: options.signal, progressListener: options.progressListener }, + ); +} + +export async function proxyReadToBackendKvStore( + sharedKvStoreContext: SharedKvStoreContext, + url: string, + options: DriverReadOptions, +): Promise { + const response = await sharedKvStoreContext.rpc!.promiseInvoke< + | { data: ArrayBuffer; offset: number; totalSize: number | undefined } + | undefined + >( + READ_RPC_ID, + { + sharedKvStoreContext: sharedKvStoreContext.rpcId, + url, + byteRange: options.byteRange, + throwIfMissing: options.throwIfMissing, + }, + { signal: options.signal, progressListener: options.progressListener }, + ); + if (response === undefined) return undefined; + return { + response: new Response(response.data), + offset: response.offset, + length: response.data.byteLength, + totalSize: response.totalSize, + }; +} + +export function proxyListToBackendKvStore( + sharedKvStoreContext: SharedKvStoreContext, + url: string, + options: DriverListOptions, +): Promise { + return sharedKvStoreContext.rpc!.promiseInvoke( + LIST_RPC_ID, + { + sharedKvStoreContext: sharedKvStoreContext.rpcId, + url, + }, + { signal: options.signal, progressListener: options.progressListener }, + ); +} + +export abstract class ProxyReadableKvStore { + constructor(public sharedKvStoreContext: SharedKvStoreContext) {} + + abstract getUrl(key: Key): string; + + stat(key: Key, options: StatOptions): Promise { + return proxyStatToBackendKvStore( + this.sharedKvStoreContext, + this.getUrl(key), + options, + ); + } + read( + key: Key, + options: DriverReadOptions, + ): Promise { + return proxyReadToBackendKvStore( + this.sharedKvStoreContext, + this.getUrl(key), + options, + ); + } +} + +export abstract class ProxyKvStore extends ProxyReadableKvStore { + list(prefix: string, options: DriverListOptions): Promise { + return proxyListToBackendKvStore( + this.sharedKvStoreContext, + this.getUrl(prefix), + options, + ); + } +} diff --git a/src/kvstore/gcs/index.ts b/src/kvstore/gcs/index.ts new file mode 100644 index 0000000000..13e893f0d6 --- /dev/null +++ b/src/kvstore/gcs/index.ts @@ -0,0 +1,150 @@ +/** + * @license + * Copyright 2024 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { read, stat } from "#src/kvstore/http/read.js"; +import type { + KvStore, + DriverListOptions, + ListResponse, + DriverReadOptions, + ReadResponse, + StatOptions, + StatResponse, +} from "#src/kvstore/index.js"; +import { encodePathForUrl } from "#src/kvstore/url.js"; +import type { FetchOk } from "#src/util/http_request.js"; +import { fetchOk } from "#src/util/http_request.js"; +import { + parseArray, + verifyObject, + verifyObjectProperty, + verifyOptionalObjectProperty, + verifyString, + verifyStringArray, +} from "#src/util/json.js"; +import { ProgressSpan } from "#src/util/progress_listener.js"; +import { getRandomHexString } from "#src/util/random.js"; + +export class GcsKvStore implements KvStore { + constructor( + public bucket: string, + public baseUrlForDisplay: string = `gs://${bucket}/`, + private fetchOkImpl: FetchOk = fetchOk, + ) {} + + private getObjectUrl(key: string): string { + // Include random query string parameter (ignored by GCS) to bypass GCS cache + // and ensure a cached response is never used. + // + // This addresses two issues related to GCS: + // + // 1. GCS fails to send an updated `Access-Control-Allow-Origin` header in 304 + // responses to cache revalidation requests. + // + // https://bugs.chromium.org/p/chromium/issues/detail?id=1214563#c2 + // + // The random query string parameter ensures cached responses are never used. + // + // Note: This issue does not apply to gs+xml because with the XML API, the + // Access-Control-Allow-Origin response header does not vary with the Origin. + // + // 2. If the object does not prohibit caching (e.g. public bucket and default + // `cache-control` metadata value), GCS may return stale responses. + return ( + `https://storage.googleapis.com/storage/v1/b/${this.bucket}/o/` + + `${encodeURIComponent(key)}?alt=media` + + `&neuroglancer=${getRandomHexString()}` + ); + } + + stat(key: string, options: StatOptions): Promise { + return stat(this, key, this.getObjectUrl(key), options, this.fetchOkImpl); + } + + read( + key: string, + options: DriverReadOptions, + ): Promise { + return read(this, key, this.getObjectUrl(key), options, this.fetchOkImpl); + } + + async list( + prefix: string, + options: DriverListOptions, + ): Promise { + const { progressListener } = options; + using _span = + progressListener === undefined + ? undefined + : new ProgressSpan(progressListener, { + message: `Listing prefix ${this.getUrl(prefix)}`, + }); + const delimiter = "/"; + // Include `neuroglancerOrigin` query parameter that is ignored by GCS to + // workaround + // https://bugs.chromium.org/p/chromium/issues/detail?id=1214563#c2 (though + // it is not clear it would ever apply to bucket listing). + const response = await this.fetchOkImpl( + `https://storage.googleapis.com/storage/v1/b/${this.bucket}/o?` + + `delimiter=${encodeURIComponent(delimiter)}&prefix=${encodeURIComponent( + prefix, + )}&` + + `neuroglancerOrigin=${encodeURIComponent(location.origin)}`, + { + signal: options.signal, + progressListener: options.progressListener, + }, + ); + const responseJson = await response.json(); + + verifyObject(responseJson); + const directories = verifyOptionalObjectProperty( + responseJson, + "prefixes", + verifyStringArray, + [], + ).map((prefix) => prefix.substring(0, prefix.length - 1)); + + const entries = verifyOptionalObjectProperty( + responseJson, + "items", + (items) => + parseArray(items, (item) => { + verifyObject(item); + return verifyObjectProperty(item, "name", verifyString); + }), + [], + ) + .filter((name) => !name.endsWith("_$folder$")) + .map((name) => ({ key: name })); + + return { + directories, + entries, + }; + } + + getUrl(path: string) { + return this.baseUrlForDisplay + encodePathForUrl(path); + } + + get supportsOffsetReads() { + return true; + } + get supportsSuffixReads() { + return true; + } +} diff --git a/src/kvstore/gcs/register.ts b/src/kvstore/gcs/register.ts new file mode 100644 index 0000000000..4eb612bf77 --- /dev/null +++ b/src/kvstore/gcs/register.ts @@ -0,0 +1,45 @@ +/** + * @license + * Copyright 2024 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import pythonIntegration from "#python_integration_build"; +import type { BaseKvStoreProvider } from "#src/kvstore/context.js"; +import { GcsKvStore } from "#src/kvstore/gcs/index.js"; +import type { SharedKvStoreContextBase } from "#src/kvstore/register.js"; +import { frontendBackendIsomorphicKvStoreProviderRegistry } from "#src/kvstore/register.js"; + +function gcsProvider(_context: SharedKvStoreContextBase): BaseKvStoreProvider { + return { + scheme: "gs", + description: pythonIntegration + ? "Google Cloud Storage" + : "Google Cloud Storage (anonymous)", + getKvStore(url) { + const m = (url.suffix ?? "").match(/^\/\/([^/]+)(\/.*)?$/); + if (m === null) { + throw new Error("Invalid URL, expected `gs:///`"); + } + const [, bucket, path] = m; + return { + store: new GcsKvStore(bucket), + path: decodeURIComponent((path ?? "").substring(1)), + }; + }, + }; +} + +frontendBackendIsomorphicKvStoreProviderRegistry.registerBaseKvStoreProvider( + gcsProvider, +); diff --git a/src/kvstore/gzip/file_handle.ts b/src/kvstore/gzip/file_handle.ts new file mode 100644 index 0000000000..c12f83882c --- /dev/null +++ b/src/kvstore/gzip/file_handle.ts @@ -0,0 +1,235 @@ +/** + * @license + * Copyright 2025 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { + DriverReadOptions, + FileHandle, + ReadableKvStore, + ReadResponse, + StatOptions, + StatResponse, +} from "#src/kvstore/index.js"; +import { decodeGzipStream } from "#src/util/gzip.js"; + +export const EXPECTED_HEADER_OVERHEAD = 100; + +export class GzipFileHandle + implements FileHandle +{ + constructor( + public base: BaseHandle, + public format: CompressionFormat, + ) {} + + async stat(options: StatOptions): Promise { + await this.base.stat(options); + return { totalSize: undefined }; + } + + async read(options: DriverReadOptions): Promise { + const { byteRange } = options; + if (byteRange === undefined) { + const readResponse = await this.base.read(options); + if (readResponse === undefined) return undefined; + return { + response: new Response( + decodeGzipStream(readResponse.response, this.format), + ), + offset: 0, + length: undefined, + totalSize: undefined, + }; + } + if ("suffixLength" in byteRange || byteRange.offset !== 0) { + throw new Error( + `Byte range with offset not supported: ${JSON.stringify(byteRange)}`, + ); + } + + // There is no way to force a flush on a `DecompressionStream`; to ensure we + // have all available output from the input, we must close the readable + // stream, which prevents any further writes. This means if more input is + // required, we have to redo the decode. In almost all cases, though, + // `EXPECTED_HEADER_OVERHEAD` should be sufficient and it won't be necessary + // to fetch additional encoded data. + let decodedArray = new Uint8Array(byteRange.length); + const parts: Uint8Array[] = []; + let encodedBytesReceived = 0; + let expectedEncodedBytes = byteRange.length + EXPECTED_HEADER_OVERHEAD; + while (true) { + const readResponse = await this.base.read({ + ...options, + byteRange: { + offset: encodedBytesReceived, + length: expectedEncodedBytes - encodedBytesReceived, + }, + }); + if (readResponse === undefined) return undefined; + { + const part = new Uint8Array(await readResponse.response.arrayBuffer()); + parts.push(part); + encodedBytesReceived += part.length; + } + + const decompressionStream = new DecompressionStream("gzip"); + const writer = decompressionStream.writable.getWriter(); + const writePromises: Promise[] = []; + for (const part of parts) { + writePromises.push(writer.write(part)); + } + writePromises.push(writer.close()); + const reader = decompressionStream.readable.getReader(); + let decodedOffset = 0; + try { + while (decodedOffset < decodedArray.length) { + let { value } = await reader.read(); + if (value === undefined) { + // no more decoded data available + break; + } + const remainingLength = decodedArray.length - decodedOffset; + if (value.length > remainingLength) { + value = value.subarray(0, remainingLength); + } + decodedArray.set(value, decodedOffset); + decodedOffset += value.length; + } + + if ( + decodedOffset === decodedArray.length || + encodedBytesReceived === readResponse.totalSize + ) { + if (decodedOffset < decodedArray.length) { + decodedArray = decodedArray.subarray(0, decodedOffset); + } + return { + response: new Response(decodedArray), + offset: 0, + length: decodedArray.length, + totalSize: undefined, + }; + } + } finally { + await reader.cancel(); + await Promise.allSettled(writePromises); + } + + expectedEncodedBytes += Math.min( + 100, + decodedArray.length - decodedOffset, + ); + } + } + + getUrl() { + return this.base.getUrl() + "|gzip"; + } +} + +export async function gzipRead( + base: ReadableKvStore, + baseKey: Key, + format: CompressionFormat, + options: DriverReadOptions, +) { + const { byteRange } = options; + if (byteRange === undefined) { + const readResponse = await base.read(baseKey, options); + if (readResponse === undefined) return undefined; + return { + response: new Response(decodeGzipStream(readResponse.response, format)), + offset: 0, + length: undefined, + totalSize: undefined, + }; + } + if ("suffixLength" in byteRange || byteRange.offset !== 0) { + throw new Error( + `Byte range with offset not supported: ${JSON.stringify(byteRange)}`, + ); + } + + // There is no way to force a flush on a `DecompressionStream`; to ensure we + // have all available output from the input, we must close the readable + // stream, which prevents any further writes. This means if more input is + // required, we have to redo the decode. In almost all cases, though, + // `EXPECTED_HEADER_OVERHEAD` should be sufficient and it won't be necessary + // to fetch additional encoded data. + let decodedArray = new Uint8Array(byteRange.length); + const parts: Uint8Array[] = []; + let encodedBytesReceived = 0; + let expectedEncodedBytes = byteRange.length + EXPECTED_HEADER_OVERHEAD; + while (true) { + const readResponse = await base.read(baseKey, { + ...options, + byteRange: { + offset: encodedBytesReceived, + length: expectedEncodedBytes - encodedBytesReceived, + }, + }); + if (readResponse === undefined) return undefined; + { + const part = new Uint8Array(await readResponse.response.arrayBuffer()); + parts.push(part); + encodedBytesReceived += part.length; + } + + const decompressionStream = new DecompressionStream("gzip"); + const writer = decompressionStream.writable.getWriter(); + const writePromises: Promise[] = []; + for (const part of parts) { + writePromises.push(writer.write(part)); + } + writePromises.push(writer.close()); + const reader = decompressionStream.readable.getReader(); + let decodedOffset = 0; + try { + while (decodedOffset < decodedArray.length) { + let { value } = await reader.read(); + if (value === undefined) { + // no more decoded data available + break; + } + const remainingLength = decodedArray.length - decodedOffset; + if (value.length > remainingLength) { + value = value.subarray(0, remainingLength); + } + decodedArray.set(value, decodedOffset); + decodedOffset += value.length; + } + + if ( + decodedOffset === decodedArray.length || + encodedBytesReceived === readResponse.totalSize + ) { + if (decodedOffset < decodedArray.length) { + decodedArray = decodedArray.subarray(0, decodedOffset); + } + return { + response: new Response(decodedArray), + offset: 0, + length: decodedArray.length, + totalSize: undefined, + }; + } + } finally { + await reader.cancel(); + await Promise.allSettled(writePromises); + } + + expectedEncodedBytes += Math.min(100, decodedArray.length - decodedOffset); + } +} diff --git a/src/kvstore/gzip/index.ts b/src/kvstore/gzip/index.ts new file mode 100644 index 0000000000..741e67d21c --- /dev/null +++ b/src/kvstore/gzip/index.ts @@ -0,0 +1,96 @@ +/** + * @license + * Copyright 2025 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { + AutoDetectFileOptions, + AutoDetectMatch, + AutoDetectRegistry, +} from "#src/kvstore/auto_detect.js"; +import { GzipFileHandle } from "#src/kvstore/gzip/file_handle.js"; +import type { + DriverReadOptions, + KvStore, + ReadResponse, + StatOptions, + StatResponse, + FileHandle, +} from "#src/kvstore/index.js"; +import { isGzipFormat } from "#src/util/gzip.js"; + +export class GzipKvStore implements KvStore { + constructor( + public base: FileHandle, + public scheme: string, + public format: CompressionFormat, + ) {} + + getUrl(key: string) { + this.validatePath(key); + return this.base.getUrl() + `|${this.scheme}`; + } + + private validatePath(path: string) { + if (path) { + throw new Error( + `"${this.scheme}:" does not support non-empty path ${JSON.stringify(path)}`, + ); + } + } + + async stat( + key: string, + options: StatOptions, + ): Promise { + this.validatePath(key); + await this.base.stat(options); + return { totalSize: undefined }; + } + + async read( + key: string, + options: DriverReadOptions, + ): Promise { + this.validatePath(key); + return new GzipFileHandle(this.base, this.format).read(options); + } + + get supportsOffsetReads() { + return false; + } + get supportsSuffixReads() { + return false; + } + get singleKey() { + return true; + } +} + +async function detectGzip( + options: AutoDetectFileOptions, +): Promise { + if (!isGzipFormat(options.prefix)) { + return []; + } + return [{ suffix: "gzip:", description: "gzip-compressed" }]; +} + +export function registerAutoDetect(registry: AutoDetectRegistry) { + registry.registerFileFormat({ + prefixLength: 3, + suffixLength: 0, + match: detectGzip, + }); +} diff --git a/src/kvstore/gzip/register.ts b/src/kvstore/gzip/register.ts new file mode 100644 index 0000000000..2c5357ce53 --- /dev/null +++ b/src/kvstore/gzip/register.ts @@ -0,0 +1,50 @@ +/** + * @license + * Copyright 2025 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { KvStoreAdapterProvider } from "#src/kvstore/context.js"; +import { GzipKvStore, registerAutoDetect } from "#src/kvstore/gzip/index.js"; +import { KvStoreFileHandle } from "#src/kvstore/index.js"; +import { frontendBackendIsomorphicKvStoreProviderRegistry } from "#src/kvstore/register.js"; +import { ensureEmptyUrlSuffix } from "#src/kvstore/url.js"; + +function gzipProvider( + scheme: string, + format: CompressionFormat, +): KvStoreAdapterProvider { + return { + scheme, + description: `transparent ${scheme} decoding`, + getKvStore(url, base) { + ensureEmptyUrlSuffix(url); + return { + store: new GzipKvStore( + new KvStoreFileHandle(base.store, base.path), + scheme, + format, + ), + path: "", + }; + }, + }; +} + +frontendBackendIsomorphicKvStoreProviderRegistry.registerKvStoreAdapterProvider( + () => gzipProvider("gzip", "gzip"), +); + +registerAutoDetect( + frontendBackendIsomorphicKvStoreProviderRegistry.autoDetectRegistry, +); diff --git a/src/kvstore/http/html_directory_listing.ts b/src/kvstore/http/html_directory_listing.ts new file mode 100644 index 0000000000..06de731833 --- /dev/null +++ b/src/kvstore/http/html_directory_listing.ts @@ -0,0 +1,114 @@ +/** + * @license + * Copyright 2019 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { + ListEntry, + DriverListOptions, + ListResponse, +} from "#src/kvstore/index.js"; +import { extractQueryAndFragment } from "#src/kvstore/url.js"; +import type { FetchOk } from "#src/util/http_request.js"; +import { fetchOk } from "#src/util/http_request.js"; +import { + ProgressSpan, + type ProgressOptions, +} from "#src/util/progress_listener.js"; + +/** + * Obtains a directory listing from a server that supports HTML directory listings. + */ +export async function getHtmlDirectoryListing( + url: string, + options: { + fetchOkImpl?: FetchOk; + } & Partial = {}, +): Promise { + const baseUrl = extractQueryAndFragment(url).base; + const { fetchOkImpl = fetchOk, signal, progressListener } = options; + const response = await fetchOkImpl( + url, + /*init=*/ { + headers: { accept: "text/html" }, + signal: signal, + progressListener, + }, + ); + const contentType = response.headers.get("content-type"); + if (contentType === null || /\btext\/html\b/i.exec(contentType) === null) { + return []; + } + const text = await response.text(); + const doc = new DOMParser().parseFromString(text, "text/html"); + const nodes = doc.evaluate( + "//a/@href", + doc, + null, + XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, + null, + ); + const results = new Set(); + for (let i = 0, n = nodes.snapshotLength; i < n; ++i) { + const node = nodes.snapshotItem(i)!; + const href = node.textContent; + if (href === null) continue; + const withoutQuery = extractQueryAndFragment(href).base; + if (withoutQuery) { + const resolvedUrl = new URL(withoutQuery, baseUrl).toString(); + if (resolvedUrl.startsWith(baseUrl) && resolvedUrl !== baseUrl) { + results.add(resolvedUrl); + } + } + } + return Array.from(results); +} + +export async function listFromHtmlDirectoryListing( + baseUrl: string, + prefix: string, + options: DriverListOptions, +): Promise { + const { progressListener } = options; + using _span = + progressListener && + new ProgressSpan(progressListener, { + message: `Requesting HTML directory listing for ${baseUrl}`, + }); + const { base, queryAndFragment } = extractQueryAndFragment(baseUrl); + const baseAndPrefix = base + prefix; + const fullUrl = baseAndPrefix + queryAndFragment; + const m = fullUrl.match(/^([a-z]+:\/\/.*\/)([^/?#]*)$/); + if (m === null) throw null; + const [, directoryUrl] = m; + const listing = await getHtmlDirectoryListing( + directoryUrl + queryAndFragment, + { + signal: options.signal, + progressListener: options.progressListener, + }, + ); + const entries: ListEntry[] = []; + const directories: string[] = []; + for (const entry of listing) { + if (!entry.startsWith(baseAndPrefix)) continue; + const p = decodeURIComponent(entry.substring(base.length)); + if (p.endsWith("/")) { + directories.push(p.substring(0, p.length - 1)); + } else { + entries.push({ key: p }); + } + } + return { entries, directories }; +} diff --git a/src/kvstore/http/index.ts b/src/kvstore/http/index.ts new file mode 100644 index 0000000000..4d4e1caacd --- /dev/null +++ b/src/kvstore/http/index.ts @@ -0,0 +1,95 @@ +/** + * @license + * Copyright 2023 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { listFromHtmlDirectoryListing } from "#src/kvstore/http/html_directory_listing.js"; +import { read, stat } from "#src/kvstore/http/read.js"; +import type { + KvStore, + DriverListOptions, + ListResponse, + DriverReadOptions, + ReadResponse, + StatOptions, + StatResponse, +} from "#src/kvstore/index.js"; +import { extractQueryAndFragment } from "#src/kvstore/url.js"; +import type { FetchOk } from "#src/util/http_request.js"; +import { fetchOk } from "#src/util/http_request.js"; + +function joinBaseUrlAndPath(baseUrl: string, path: string) { + const { base, queryAndFragment } = extractQueryAndFragment(baseUrl); + return base + path + queryAndFragment; +} + +export class HttpKvStore implements KvStore { + constructor( + public baseUrl: string, + public baseUrlForDisplay: string = baseUrl, + public fetchOkImpl: FetchOk = fetchOk, + ) {} + + stat(key: string, options: StatOptions): Promise { + return stat( + this, + key, + joinBaseUrlAndPath(this.baseUrl, key), + options, + this.fetchOkImpl, + ); + } + + read( + key: string, + options: DriverReadOptions, + ): Promise { + return read( + this, + key, + joinBaseUrlAndPath(this.baseUrl, key), + options, + this.fetchOkImpl, + ); + } + + list(prefix: string, options: DriverListOptions): Promise { + return listFromHtmlDirectoryListing(this.baseUrl, prefix, options); + } + + getUrl(path: string) { + return joinBaseUrlAndPath(this.baseUrlForDisplay, path); + } + + get supportsOffsetReads() { + return true; + } + get supportsSuffixReads() { + return true; + } +} + +export function getBaseUrlAndPath(url: string) { + const parsed = new URL(url); + if (parsed.hash) { + throw new Error("fragment not supported"); + } + if (parsed.username || parsed.password) { + throw new Error("basic auth credentials not supported"); + } + return { + baseUrl: `${parsed.origin}/${parsed.search}`, + path: decodeURI(parsed.pathname.substring(1)), + }; +} diff --git a/src/kvstore/http/read.ts b/src/kvstore/http/read.ts new file mode 100644 index 0000000000..721dd98a5d --- /dev/null +++ b/src/kvstore/http/read.ts @@ -0,0 +1,282 @@ +/** + * @license + * Copyright 2023 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { composeByteRangeRequest } from "#src/kvstore/byte_range/file_handle.js"; +import type { + ByteRange, + DriverReadOptions, + ReadableKvStore, + ReadResponse, + StatOptions, + StatResponse, +} from "#src/kvstore/index.js"; +import { KvStoreFileHandle, NotFoundError } from "#src/kvstore/index.js"; +import type { FetchOk } from "#src/util/http_request.js"; +import { fetchOk, HttpError, isNotFoundError } from "#src/util/http_request.js"; +import type { ProgressListener } from "#src/util/progress_listener.js"; + +function getRangeHeader(request: ByteRange | undefined): string | undefined { + if (request === undefined) return undefined; + return `bytes=${request.offset}-${request.offset + request.length - 1}`; +} + +/** + * On Chromium, multiple concurrent byte range requests to the same URL are serialized unless the + * cache is disabled. Disabling the cache works around the problem. + * + * https://bugs.chromium.org/p/chromium/issues/detail?id=969828 + */ +const byteRangeCacheMode = + navigator.userAgent.indexOf("Chrome") !== -1 ? "no-store" : "default"; + +function wasRedirectedToDirectoryListing(url: string, response: Response) { + return new URL(url).pathname + "/" === new URL(response.url).pathname; +} + +function parse206ContentRangeHeader(contentRange: string) { + const m = contentRange.match(/bytes ([0-9]+)-([0-9]+)\/([0-9]+|\*)/); + if (m === null) { + throw new Error( + `Invalid content-range header: ${JSON.stringify(contentRange)}`, + ); + } + const offset = parseInt(m[1], 10); + const endPos = parseInt(m[2], 10); + let totalSize: number | undefined; + if (m[3] !== "*") { + totalSize = parseInt(m[3], 10); + } + const length = endPos - offset + 1; + return { offset, length, totalSize }; +} + +export async function read( + store: ReadableKvStore, + key: Key, + url: string, + options: DriverReadOptions, + fetchOkImpl: FetchOk = fetchOk, +): Promise { + let resolvedByteRange: ByteRange | undefined; + try { + const { byteRange: byteRangeRequest } = options; + let rangeHeader: string | undefined; + // The HTTP spec supports suffixLength requests directly via "Range: + // bytes=-N" requests, which avoids the need for a separate HEAD request. + // However, per + // https://fetch.spec.whatwg.org/#cors-safelisted-request-header a suffix + // length byte range request header will always trigger an OPTIONS preflight + // request, which would otherwise be avoided. This negates the benefit of + // using a suffixLength request directly. Additionally, some servers such as + // the npm http-server package and https://uk1s3.embassy.ebi.ac.uk/ do not + // correctly handle suffixLength requests or do not correctly handle CORS + // preflight requests. To avoid those issues, always just issue a separate + // HEAD request to determine the length. + if (byteRangeRequest !== undefined) { + if ("suffixLength" in byteRangeRequest) { + const statResponse = await stat(store, key, url, options, fetchOkImpl); + if (statResponse === undefined) return undefined; + const { totalSize } = statResponse; + if (totalSize === undefined) { + throw new Error( + `Failed to determine total size of ${store.getUrl(key)} in order to fetch suffix ${JSON.stringify(byteRangeRequest)}`, + ); + } + resolvedByteRange = composeByteRangeRequest( + { offset: 0, length: totalSize }, + byteRangeRequest, + ).outer; + if (resolvedByteRange.length === 0) { + // Skip zero-byte read, since totalSize is already known. + return { + ...resolvedByteRange, + totalSize, + response: new Response(new Uint8Array(0)), + }; + } + rangeHeader = getRangeHeader(resolvedByteRange); + } else { + resolvedByteRange = byteRangeRequest; + if (resolvedByteRange.length === 0) { + // The HTTP range header does not support zero-length byte range + // requests. + // + // Convert zero-length byte range to length-1 byte range, and then + // discard the response. If the requested offset is 0, and the file is + // empty, then this will result in a 416 Range Not Satisfiable + // response. + rangeHeader = getRangeHeader({ + offset: Math.max(resolvedByteRange.offset - 1, 0), + length: 1, + }); + } else { + rangeHeader = getRangeHeader(resolvedByteRange); + } + } + } + const requestInit: RequestInit & { progressListener?: ProgressListener } = { + signal: options.signal, + progressListener: options.progressListener, + }; + if (rangeHeader !== undefined) { + requestInit.headers = { range: rangeHeader }; + requestInit.cache = byteRangeCacheMode; + } + let response = await fetchOkImpl(url, requestInit); + if (wasRedirectedToDirectoryListing(url, response)) { + return undefined; + } + let offset: number | undefined; + let length: number | undefined; + let totalSize: number | undefined; + if (response.status === 206) { + const contentRange = response.headers.get("content-range"); + if (contentRange === null) { + // Content-range should always be sent, but some buggy servers don't + // send it. + if (resolvedByteRange !== undefined) { + offset = resolvedByteRange.offset; + } else { + throw new Error( + "Unexpected HTTP 206 response when no byte range specified.", + ); + } + } + if (contentRange !== null) { + ({ offset, length, totalSize } = + parse206ContentRangeHeader(contentRange)); + } + } else { + length = totalSize = getBodyLength(response.headers); + } + if (offset === undefined) { + offset = 0; + } + if (length === undefined) { + length = getBodyLength(response.headers); + } + if (resolvedByteRange?.length === 0) { + response = new Response(new Uint8Array(0)); + offset = resolvedByteRange.offset; + length = 0; + } + return { + response, + offset, + length, + totalSize, + }; + } catch (e) { + if ( + e instanceof HttpError && + e.status === 416 && + resolvedByteRange?.length === 0 && + resolvedByteRange.offset === 0 + ) { + return { + response: new Response(new Uint8Array(0)), + offset: 0, + length: 0, + totalSize: 0, + }; + } + return handleThrowIfMissing(store, key, options, e); + } +} + +function getBodyLength(headers: Headers): number | undefined { + const contentLength = headers.get("content-length"); + const contentEncoding = headers.get("content-encoding"); + if (contentEncoding === null && contentLength !== null) { + const size = Number(contentLength); + if (!Number.isFinite(size) || size < 0) { + throw new Error(`Invalid content-length: {contentLength}`); + } + return size; + } + return undefined; +} + +function handleThrowIfMissing( + store: ReadableKvStore, + key: Key, + options: { throwIfMissing?: boolean }, + error: unknown, +) { + if (isNotFoundError(error)) { + if (options.throwIfMissing === true) { + throw new NotFoundError(new KvStoreFileHandle(store, key), { + cause: error, + }); + } + return undefined; + } + throw error; +} + +export async function stat( + store: ReadableKvStore, + key: Key, + url: string, + options: StatOptions, + fetchOkImpl: FetchOk = fetchOk, +): Promise { + // First try HEAD request. + try { + const response = await fetchOkImpl(url, { + method: "HEAD", + signal: options.signal, + progressListener: options.progressListener, + }); + if (wasRedirectedToDirectoryListing(url, response)) return undefined; + return { totalSize: getBodyLength(response.headers) }; + } catch (e) { + if (e instanceof HttpError && e.status === 405 /* method not allowed */) { + // HEAD may not be supported, use GET with one byte range instead. + // + // For example, + // https://data-proxy.ebrains.eu/api/v1/buckets/localizoom/14122_mPPC_BDA_s186.tif/14122_mPPC_BDA_s186.dzi + // returns HTTP 405 Method Not Allowed in response to HEAD requests. + } else { + return handleThrowIfMissing(store, key, options, e); + } + } + + // Try GET with one-byte range instead. + try { + const response = await fetchOkImpl(url, { + signal: options.signal, + progressListener: options.progressListener, + headers: { range: "bytes=0-0" }, + }); + if (wasRedirectedToDirectoryListing(url, response)) return undefined; + let totalSize: number | undefined; + if (response.status === 200) { + totalSize = getBodyLength(response.headers); + } else { + const contentRange = response.headers.get("content-range"); + if (contentRange !== null) { + ({ totalSize } = parse206ContentRangeHeader(contentRange)); + } + } + return { totalSize }; + } catch (e) { + if (e instanceof HttpError && e.status === 416) { + return { totalSize: 0 }; + } + return handleThrowIfMissing(store, key, options, e); + } +} diff --git a/src/kvstore/http/register.ts b/src/kvstore/http/register.ts new file mode 100644 index 0000000000..3b593a3148 --- /dev/null +++ b/src/kvstore/http/register.ts @@ -0,0 +1,49 @@ +/** + * @license + * Copyright 2024 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { BaseKvStoreProvider } from "#src/kvstore/context.js"; +import { getBaseUrlAndPath, HttpKvStore } from "#src/kvstore/http/index.js"; +import type { SharedKvStoreContextBase } from "#src/kvstore/register.js"; +import { frontendBackendIsomorphicKvStoreProviderRegistry } from "#src/kvstore/register.js"; + +function httpProvider( + scheme: string, + _context: SharedKvStoreContextBase, +): BaseKvStoreProvider { + return { + scheme, + description: `${scheme} (unauthenticated)`, + getKvStore(url) { + try { + const { baseUrl, path } = getBaseUrlAndPath(url.url); + return { + store: new HttpKvStore(baseUrl), + path, + }; + } catch (e) { + throw new Error(`Invalid URL ${JSON.stringify(url.url)}`, { + cause: e, + }); + } + }, + }; +} + +for (const protocol of ["http", "https"]) { + frontendBackendIsomorphicKvStoreProviderRegistry.registerBaseKvStoreProvider( + (context) => httpProvider(protocol, context), + ); +} diff --git a/src/kvstore/index.ts b/src/kvstore/index.ts index 68a3c663b5..980239a303 100644 --- a/src/kvstore/index.ts +++ b/src/kvstore/index.ts @@ -14,40 +14,13 @@ * limitations under the License. */ -import type { CancellationToken } from "#src/util/cancellation.js"; +import type { ProgressOptions } from "#src/util/progress_listener.js"; export interface ByteRange { offset: number; length: number; } -export function composeByteRangeRequest( - outer: ByteRange, - inner: ByteRangeRequest | undefined, -): { outer: ByteRange; inner: ByteRange } { - if (inner === undefined) { - return { outer, inner: { offset: 0, length: outer.length } }; - } - if ("suffixLength" in inner) { - const length = Math.min(outer.length, inner.suffixLength); - return { - outer: { offset: outer.offset + (outer.length - length), length }, - inner: { offset: outer.length - length, length }, - }; - } - if (inner.offset + inner.length > outer.length) { - throw new Error( - `Requested byte range ${JSON.stringify( - inner, - )} not valid for value of length ${outer.length}`, - ); - } - return { - outer: { offset: outer.offset + inner.offset, length: inner.length }, - inner, - }; -} - export type ByteRangeRequest = | ByteRange | { @@ -55,19 +28,33 @@ export type ByteRangeRequest = }; export interface ReadResponse { - data: Uint8Array; - dataRange: ByteRange; + response: Response; + offset: number; + length: number | undefined; totalSize: number | undefined; } -export interface ReadOptions { +export interface DriverReadOptions extends Partial { byteRange?: ByteRangeRequest; - cancellationToken?: CancellationToken; + throwIfMissing?: boolean; } -export interface ListOptions { - prefix: string; - cancellationToken?: CancellationToken; +export class NotFoundError extends Error { + constructor(handle: FileHandle, options?: { cause: any }) { + super(`${handle.getUrl()} not found`, options); + } +} + +export interface ReadOptions extends DriverReadOptions { + strictByteRange?: boolean; +} + +export type DriverListOptions = Partial; + +export type ListResponseKeyKind = "path" | "suffix" | "url"; + +export interface ListOptions extends DriverListOptions { + responseKeys?: ListResponseKeyKind; } export interface ListEntry { @@ -79,12 +66,204 @@ export interface ListResponse { directories: string[]; } +export interface StatOptions extends Partial { + throwIfMissing?: boolean; +} + +export interface StatResponse { + totalSize: number | undefined; +} + export interface ReadableKvStore { - read(key: Key, options: ReadOptions): Promise; + stat(key: Key, options: StatOptions): Promise; + read(key: Key, options: DriverReadOptions): Promise; + getUrl(key: Key): string; + + // Reads with non-zero byte offset are supported. + supportsOffsetReads: boolean; + + // Reads with `suffixLength` byte range are supported. + supportsSuffixReads: boolean; } export interface ListableKvStore { - list(options: ListOptions): Promise; + list?: (prefix: string, options: DriverListOptions) => Promise; +} + +export interface KvStore extends ReadableKvStore, ListableKvStore { + // Indicates that the only valid key is the empty string. + singleKey?: boolean; +} + +export interface KvStoreWithPath { + store: KvStore; + path: string; +} + +export function getKvStoreUrl(kvstore: KvStoreWithPath): string { + return kvstore.store.getUrl(kvstore.path); +} + +export function readKvStore( + store: ReadableKvStore, + key: Key, + options: ReadOptions & { throwIfMissing: true }, +): Promise; + +export function readKvStore( + store: ReadableKvStore, + key: Key, + options?: ReadOptions, +): Promise; + +export async function readKvStore( + store: ReadableKvStore, + key: Key, + options: ReadOptions = {}, +): Promise { + return readFileHandle(new KvStoreFileHandle(store, key), options); +} + +export function readFileHandle( + handle: FileHandle, + options: ReadOptions & { throwIfMissing: true }, +): Promise; + +export function readFileHandle( + handle: FileHandle, + options?: ReadOptions, +): Promise; + +export async function readFileHandle( + handle: FileHandle, + options: ReadOptions = {}, +): Promise { + const response = await handle.read(options); + if (options?.throwIfMissing === true) { + if (response === undefined) { + throw new NotFoundError(handle); + } + } + if (options?.strictByteRange === true && response !== undefined) { + const { byteRange } = options; + const { offset, length } = response; + if (byteRange !== undefined) { + if ( + "suffixLength" in byteRange + ? length !== byteRange.suffixLength + : offset !== byteRange.offset || + (length !== undefined && length !== byteRange.length) + ) { + throw new Error( + `Received truncated response for ${handle.getUrl()}, expected ${JSON.stringify( + byteRange, + )} but received offset=${offset}, length=${length}`, + ); + } + } + } + return response; } -export interface KvStore extends ReadableKvStore, ListableKvStore {} +function transformListResponse( + response: ListResponse, + prefix: string, + kvStore: KvStore, + responseKeys?: ListResponseKeyKind, +) { + switch (responseKeys) { + case "suffix": { + const offset = prefix.length; + return { + directories: response.directories.map((key) => key.substring(offset)), + entries: response.entries.map(({ key, ...entry }) => ({ + ...entry, + key: key.substring(offset), + })), + }; + } + case "url": { + return { + directories: response.directories.map((key) => kvStore.getUrl(key)), + entries: response.entries.map(({ key, ...entry }) => ({ + ...entry, + key: kvStore.getUrl(key), + })), + }; + } + default: { + return response; + } + } +} + +export async function listKvStore( + kvStore: KvStore, + prefix: string, + options: ListOptions = {}, +): Promise { + if (!kvStore.list) { + throw new Error("Listing not supported"); + } + return transformListResponse( + await kvStore.list(prefix, options), + prefix, + kvStore, + options.responseKeys, + ); +} + +export async function listKvStoreRecursively( + kvStore: KvStore, + prefix: string, + options: ListOptions = {}, +): Promise { + if (!kvStore.list) { + throw new Error("Listing not supported"); + } + const entries: ListEntry[] = []; + async function process(path: string) { + const response = await kvStore.list!(path, options); + entries.push(...response.entries); + await Promise.all(response.directories.map((name) => process(name + "/"))); + } + await process(prefix); + return transformListResponse( + { entries, directories: [] }, + prefix, + kvStore, + options.responseKeys, + ).entries; +} + +export function kvStoreAppendPath( + kvstore: KvStoreWithPath, + suffix: string, +): KvStoreWithPath { + return { store: kvstore.store, path: kvstore.path + suffix }; +} + +export interface FileHandle { + stat(options: StatOptions): Promise; + read(options: DriverReadOptions): Promise; + getUrl(): string; +} + +export class KvStoreFileHandle implements FileHandle { + constructor( + public store: ReadableKvStore, + public key: Key, + ) {} + + stat(options: StatOptions): Promise { + return this.store.stat(this.key, options); + } + + read(options: DriverReadOptions): Promise { + return this.store.read(this.key, options); + } + + getUrl() { + return this.store.getUrl(this.key); + } +} diff --git a/src/datasource/middleauth/credentials_provider.ts b/src/kvstore/middleauth/credentials_provider.ts similarity index 54% rename from src/datasource/middleauth/credentials_provider.ts rename to src/kvstore/middleauth/credentials_provider.ts index c5a6ab9995..554ce79933 100644 --- a/src/datasource/middleauth/credentials_provider.ts +++ b/src/kvstore/middleauth/credentials_provider.ts @@ -22,13 +22,19 @@ import { CredentialsProvider, makeCredentialsGetter, } from "#src/credentials_provider/index.js"; +import { + getCredentialsWithStatus, + monitorAuthPopupWindow, +} from "#src/credentials_provider/interactive_credentials_provider.js"; import { StatusMessage } from "#src/status.js"; +import { raceWithAbort } from "#src/util/abort.js"; import { verifyObject, verifyObjectProperty, verifyString, verifyStringArray, } from "#src/util/json.js"; +import { ProgressSpan } from "#src/util/progress_listener.js"; export type MiddleAuthToken = { tokenType: string; @@ -51,83 +57,68 @@ function openPopupCenter(url: string, width: number, height: number) { ); } -async function waitForLogin(serverUrl: string): Promise { - const status = new StatusMessage(/*delay=*/ false, /*modal=*/ true); - - const res: Promise = new Promise((f) => { - function writeLoginStatus(message: string, buttonMessage: string) { - status.element.textContent = message + " "; - const button = document.createElement("button"); - button.textContent = buttonMessage; - status.element.appendChild(button); - - button.addEventListener("click", () => { - writeLoginStatus( - `Waiting for login to middleauth server ${serverUrl}...`, - "Retry", - ); - - const auth_popup = openPopupCenter( - `${serverUrl}/api/v1/authorize`, - 400, - 650, - ); - - const closeAuthPopup = () => { - auth_popup?.close(); - }; - - window.addEventListener("beforeunload", closeAuthPopup); - const checkClosed = setInterval(() => { - if (auth_popup?.closed) { - clearInterval(checkClosed); - writeLoginStatus( - `Login window closed for middleauth server ${serverUrl}.`, - "Retry", - ); - } - }, 1000); - - const tokenListener = async (ev: MessageEvent) => { - if (ev.source === auth_popup) { - clearInterval(checkClosed); - window.removeEventListener("message", tokenListener); - window.removeEventListener("beforeunload", closeAuthPopup); - closeAuthPopup(); - - verifyObject(ev.data); - const accessToken = verifyObjectProperty( - ev.data, - "token", - verifyString, - ); - const appUrls = verifyObjectProperty( - ev.data, - "app_urls", - verifyStringArray, - ); - - const token: MiddleAuthToken = { - tokenType: "Bearer", - accessToken, - url: serverUrl, - appUrls, - }; - f(token); - } - }; - - window.addEventListener("message", tokenListener); - }); - } - - writeLoginStatus(`middleauth server ${serverUrl} login required.`, "Login"); +function waitForAuthResponseMessage( + serverUrl: string, + source: Window, + signal: AbortSignal, +): Promise { + return new Promise((resolve, reject) => { + window.addEventListener( + "message", + (event) => { + if (event.source !== source) return; + try { + const obj = verifyObject(event.data); + const accessToken = verifyObjectProperty(obj, "token", verifyString); + const appUrls = verifyObjectProperty( + obj, + "app_urls", + verifyStringArray, + ); + + const token: MiddleAuthToken = { + tokenType: "Bearer", + accessToken, + url: serverUrl, + appUrls, + }; + resolve(token); + } catch (parseError) { + reject( + new Error( + `Received unexpected authentication response: ${parseError.message}`, + ), + ); + console.error("Response received: ", event.data); + } + }, + { signal: signal }, + ); }); +} +async function waitForLogin( + serverUrl: string, + signal: AbortSignal, +): Promise { + const abortController = new AbortController(); + signal = AbortSignal.any([abortController.signal, signal]); try { - return await res; + const newWindow = openPopupCenter( + `${serverUrl}/api/v1/authorize`, + 400, + 650, + ); + if (newWindow === null) { + throw new Error("Failed to create authentication popup window"); + } + monitorAuthPopupWindow(newWindow, abortController); + return await raceWithAbort( + waitForAuthResponseMessage(serverUrl, newWindow, abortController.signal), + signal, + ); } finally { - status.dispose(); + abortController.abort(); } } @@ -154,7 +145,7 @@ export class MiddleAuthCredentialsProvider extends CredentialsProvider { + get = makeCredentialsGetter(async (options) => { let token = undefined; if (!this.alreadyTriedLocalStorage) { @@ -163,7 +154,17 @@ export class MiddleAuthCredentialsProvider extends CredentialsProvider waitForLogin(this.serverUrl, signal), + }, + options.signal, + ); saveAuthTokenToLocalStorage(this.serverUrl, token); } @@ -191,16 +192,23 @@ export class MiddleAuthAppCredentialsProvider extends CredentialsProvider { - const authInfo = await fetch(`${this.serverUrl}/auth_info`).then((res) => - res.json(), - ); + get = makeCredentialsGetter(async (options) => { + let authInfo: any; + { + using _span = new ProgressSpan(options.progressListener, { + message: `Determining authentication server for ${this.serverUrl}`, + }); + const response = await fetch(`${this.serverUrl}/auth_info`, { + signal: options.signal, + }); + authInfo = await response.json(); + } const provider = this.credentialsManager.getCredentialsProvider( "middleauth", authInfo.login_url, ) as MiddleAuthCredentialsProvider; - this.credentials = await provider.get(this.credentials); + this.credentials = await provider.get(this.credentials, options); if (this.credentials.credentials.appUrls.includes(this.serverUrl)) { return this.credentials.credentials; diff --git a/src/kvstore/middleauth/register.ts b/src/kvstore/middleauth/register.ts new file mode 100644 index 0000000000..e772a05bb8 --- /dev/null +++ b/src/kvstore/middleauth/register.ts @@ -0,0 +1,74 @@ +/** + * @license + * Copyright 2024 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { + CredentialsManager, + CredentialsProvider, +} from "#src/credentials_provider/index.js"; +import type { OAuth2Credentials } from "#src/credentials_provider/oauth2.js"; +import { fetchOkWithOAuth2CredentialsAdapter } from "#src/credentials_provider/oauth2.js"; +import type { BaseKvStoreProvider } from "#src/kvstore/context.js"; +import { getBaseUrlAndPath, HttpKvStore } from "#src/kvstore/http/index.js"; +import type { SharedKvStoreContextBase } from "#src/kvstore/register.js"; +import { frontendBackendIsomorphicKvStoreProviderRegistry } from "#src/kvstore/register.js"; + +const SCHEME_PREFIX = "middleauth+"; + +function getMiddleAuthCredentialsProvider( + credentialsManager: CredentialsManager, + url: string, +): CredentialsProvider { + return credentialsManager.getCredentialsProvider( + "middleauthapp", + new URL(url).origin, + ); +} + +function middleauthProvider( + scheme: string, + context: SharedKvStoreContextBase, +): BaseKvStoreProvider { + return { + scheme: SCHEME_PREFIX + scheme, + description: `${scheme} with middleauth`, + getKvStore(url) { + const httpUrl = url.url.substring(SCHEME_PREFIX.length); + const credentialsProvider = getMiddleAuthCredentialsProvider( + context.credentialsManager, + httpUrl, + ); + try { + const { baseUrl, path } = getBaseUrlAndPath(httpUrl); + return { + store: new HttpKvStore( + baseUrl, + SCHEME_PREFIX + baseUrl, + fetchOkWithOAuth2CredentialsAdapter(credentialsProvider), + ), + path, + }; + } catch (e) { + throw new Error(`Invalid URL ${JSON.stringify(url.url)}`, { + cause: e, + }); + } + }, + }; +} + +frontendBackendIsomorphicKvStoreProviderRegistry.registerBaseKvStoreProvider( + (context) => middleauthProvider("https", context), +); diff --git a/src/datasource/middleauth/register_credentials_provider.ts b/src/kvstore/middleauth/register_credentials_provider.ts similarity index 75% rename from src/datasource/middleauth/register_credentials_provider.ts rename to src/kvstore/middleauth/register_credentials_provider.ts index 90f6a3b634..42ad01323e 100644 --- a/src/datasource/middleauth/register_credentials_provider.ts +++ b/src/kvstore/middleauth/register_credentials_provider.ts @@ -14,19 +14,19 @@ * limitations under the License. */ -import { defaultCredentialsManager } from "#src/credentials_provider/default_manager.js"; +import { registerDefaultCredentialsProvider } from "#src/credentials_provider/default_manager.js"; import type { CredentialsManager } from "#src/credentials_provider/index.js"; import { MiddleAuthCredentialsProvider, MiddleAuthAppCredentialsProvider, -} from "#src/datasource/middleauth/credentials_provider.js"; +} from "#src/kvstore/middleauth/credentials_provider.js"; -defaultCredentialsManager.register( +registerDefaultCredentialsProvider( "middleauth", - (serverUrl) => new MiddleAuthCredentialsProvider(serverUrl), + (serverUrl: string) => new MiddleAuthCredentialsProvider(serverUrl), ); -defaultCredentialsManager.register( +registerDefaultCredentialsProvider( "middleauthapp", (serverUrl: string, credentialsManager: CredentialsManager) => new MiddleAuthAppCredentialsProvider(serverUrl, credentialsManager), diff --git a/src/datasource/ngauth/README.md b/src/kvstore/ngauth/README.md similarity index 100% rename from src/datasource/ngauth/README.md rename to src/kvstore/ngauth/README.md diff --git a/src/kvstore/ngauth/credentials_provider.ts b/src/kvstore/ngauth/credentials_provider.ts new file mode 100644 index 0000000000..7d2208f0ee --- /dev/null +++ b/src/kvstore/ngauth/credentials_provider.ts @@ -0,0 +1,182 @@ +/** + * @license + * Copyright 2020 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { fetchOkWithCredentials } from "#src/credentials_provider/http_request.js"; +import { + CredentialsProvider, + makeCredentialsGetter, +} from "#src/credentials_provider/index.js"; +import { + getCredentialsWithStatus, + monitorAuthPopupWindow, +} from "#src/credentials_provider/interactive_credentials_provider.js"; +import type { OAuth2Credentials } from "#src/credentials_provider/oauth2.js"; +import { raceWithAbort } from "#src/util/abort.js"; +import { fetchOk, HttpError } from "#src/util/http_request.js"; +import { + verifyObject, + verifyObjectProperty, + verifyString, +} from "#src/util/json.js"; +import { ProgressSpan } from "#src/util/progress_listener.js"; + +function makeOriginError(serverUrl: string): Error { + return new Error( + `ngauth server ${serverUrl} ` + + `does not allow requests from Neuroglancer instance ${self.origin}`, + ); +} + +export interface Credentials { + token: string; +} + +async function waitForLogin( + serverUrl: string, + signal: AbortSignal, +): Promise { + const abortController = new AbortController(); + signal = AbortSignal.any([abortController.signal, signal]); + try { + const newWindow = window.open( + `${serverUrl}/login?origin=${encodeURIComponent(self.origin)}`, + ); + if (newWindow === null) { + throw new Error("Failed to create authentication popup window"); + } + monitorAuthPopupWindow(newWindow, abortController); + return await raceWithAbort( + waitForAuthResponseMessage(serverUrl, newWindow, abortController.signal), + signal, + ); + } finally { + abortController.abort(); + } +} + +function waitForAuthResponseMessage( + serverUrl: string, + source: Window, + signal: AbortSignal, +): Promise { + return new Promise((resolve, reject) => { + window.addEventListener( + "message", + (event: MessageEvent) => { + if (event.source !== source) return; + const eventOrigin = + event.origin || ((event).originalEvent).origin; + if (eventOrigin !== serverUrl) { + return; + } + const { data } = event; + if (event.data === "badorigin") { + reject(makeOriginError(serverUrl)); + return; + } + try { + verifyObject(data); + const token = verifyObjectProperty(data, "token", verifyString); + resolve({ token }); + } catch (e) { + reject( + new Error( + `Received unexpected authentication response: ${e.message}`, + ), + ); + console.error( + "ngauth: Received unexpected message from ${serverUrl}", + event, + ); + } + }, + { signal: signal }, + ); + }); +} + +export class NgauthCredentialsProvider extends CredentialsProvider { + constructor(public serverUrl: string) { + super(); + } + get = makeCredentialsGetter(async (options) => { + using _span = new ProgressSpan(options.progressListener, { + message: `Requesting ngauth login token from ${this.serverUrl}`, + }); + try { + const response = await fetchOk(`${this.serverUrl}/token`, { + method: "POST", + credentials: "include", + signal: options.signal, + }); + return { token: await response.text() }; + } catch (e) { + if (e instanceof HttpError) { + switch (e.status) { + case 401: + return await getCredentialsWithStatus( + { + description: `ngauth server ${this.serverUrl}`, + requestDescription: "login", + get: (signal) => waitForLogin(this.serverUrl, signal), + }, + options.signal, + ); + case 403: + throw makeOriginError(this.serverUrl); + } + } + throw e; + } + }); +} + +export class NgauthGcsCredentialsProvider extends CredentialsProvider { + constructor( + public ngauthCredentialsProvider: CredentialsProvider, + public serverUrl: string, + public bucket: string, + ) { + super(); + } + get = makeCredentialsGetter(async (options) => { + using _span = new ProgressSpan(options.progressListener, { + message: `Requesting access token for gs://${this.bucket} from ${this.serverUrl}`, + }); + const response = await fetchOkWithCredentials( + this.ngauthCredentialsProvider, + `${this.serverUrl}/gcs_token`, + { method: "POST", signal: options.signal }, + (credentials, init) => { + return { + ...init, + body: JSON.stringify({ + token: credentials.token, + bucket: this.bucket, + }), + }; + }, + (error) => { + const { status } = error; + if (status === 401) { + return "refresh"; + } + throw error; + }, + ); + return { tokenType: "Bearer", accessToken: (await response.json()).token }; + }); +} diff --git a/src/kvstore/ngauth/register.ts b/src/kvstore/ngauth/register.ts new file mode 100644 index 0000000000..a7ef1067cf --- /dev/null +++ b/src/kvstore/ngauth/register.ts @@ -0,0 +1,84 @@ +/** + * @license + * Copyright 2024 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import pythonIntegration from "#python_integration_build"; +import type { + CredentialsManager, + CredentialsProvider, +} from "#src/credentials_provider/index.js"; +import type { OAuth2Credentials } from "#src/credentials_provider/oauth2.js"; +import { fetchOkWithOAuth2CredentialsAdapter } from "#src/credentials_provider/oauth2.js"; +import type { BaseKvStoreProvider } from "#src/kvstore/context.js"; +import { GcsKvStore } from "#src/kvstore/gcs/index.js"; +import type { SharedKvStoreContextBase } from "#src/kvstore/register.js"; +import { frontendBackendIsomorphicKvStoreProviderRegistry } from "#src/kvstore/register.js"; + +function getNgauthCredentialsProvider( + credentialsManager: CredentialsManager, + authServer: string, + bucket: string, +): CredentialsProvider { + return pythonIntegration + ? credentialsManager.getCredentialsProvider("gcs", { bucket }) + : credentialsManager.getCredentialsProvider("ngauth_gcs", { + authServer: authServer, + bucket, + }); +} + +const SCHEME_PREFIX = "gs+ngauth+"; + +function gcsNgauthProvider( + scheme: string, + context: SharedKvStoreContextBase, +): BaseKvStoreProvider { + return { + scheme, + description: pythonIntegration + ? "Google Cloud Storage" + : "Google Cloud Storage (ngauth)", + getKvStore(url) { + const m = (url.suffix ?? "").match(/^\/\/([^/]+)\/([^/]+)(\/.*)?$/); + if (m === null) { + throw new Error( + `Invalid URL, expected ${url.scheme}:////`, + ); + } + const [, authHost, bucket, path] = m; + const authUrl = + url.scheme.substring(SCHEME_PREFIX.length) + "://" + authHost; + const credentialsProvider = getNgauthCredentialsProvider( + context.credentialsManager, + authUrl, + bucket, + ); + return { + store: new GcsKvStore( + bucket, + `${url.scheme}://${authHost}/${bucket}/`, + fetchOkWithOAuth2CredentialsAdapter(credentialsProvider), + ), + path: decodeURIComponent((path ?? "").substring(1)), + }; + }, + }; +} + +for (const scheme of ["http", "https"]) { + frontendBackendIsomorphicKvStoreProviderRegistry.registerBaseKvStoreProvider( + (context) => gcsNgauthProvider(`${SCHEME_PREFIX}${scheme}`, context), + ); +} diff --git a/src/datasource/ngauth/register_credentials_provider.ts b/src/kvstore/ngauth/register_credentials_provider.ts similarity index 83% rename from src/datasource/ngauth/register_credentials_provider.ts rename to src/kvstore/ngauth/register_credentials_provider.ts index d500e1ee54..ff7ce554f7 100644 --- a/src/datasource/ngauth/register_credentials_provider.ts +++ b/src/kvstore/ngauth/register_credentials_provider.ts @@ -14,18 +14,18 @@ * limitations under the License. */ -import { defaultCredentialsManager } from "#src/credentials_provider/default_manager.js"; +import { registerDefaultCredentialsProvider } from "#src/credentials_provider/default_manager.js"; import type { CredentialsManager } from "#src/credentials_provider/index.js"; import { NgauthCredentialsProvider, NgauthGcsCredentialsProvider, -} from "#src/datasource/ngauth/credentials_provider.js"; +} from "#src/kvstore/ngauth/credentials_provider.js"; -defaultCredentialsManager.register( +registerDefaultCredentialsProvider( "ngauth", (serverUrl) => new NgauthCredentialsProvider(serverUrl), ); -defaultCredentialsManager.register( +registerDefaultCredentialsProvider( "ngauth_gcs", ( parameters: { authServer: string; bucket: string }, diff --git a/src/kvstore/register.ts b/src/kvstore/register.ts new file mode 100644 index 0000000000..86f316b61d --- /dev/null +++ b/src/kvstore/register.ts @@ -0,0 +1,74 @@ +/** + * @license + * Copyright 2024 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { CredentialsManager } from "#src/credentials_provider/index.js"; +import { AutoDetectRegistry } from "#src/kvstore/auto_detect.js"; +import type { + BaseKvStoreProvider, + KvStoreAdapterProvider, + KvStoreContext, +} from "#src/kvstore/context.js"; + +export interface SharedKvStoreContextBase { + kvStoreContext: KvStoreContext; + credentialsManager: CredentialsManager; +} + +export class KvStoreProviderRegistry< + SharedKvStoreContext extends SharedKvStoreContextBase, +> { + baseKvStoreProviders: Array< + (context: SharedKvStoreContext) => BaseKvStoreProvider + > = []; + kvStoreAdapterProviders: Array< + (context: SharedKvStoreContext) => KvStoreAdapterProvider + > = []; + autoDetectRegistry = new AutoDetectRegistry(); + + registerBaseKvStoreProvider( + provider: (context: SharedKvStoreContext) => BaseKvStoreProvider, + ) { + this.baseKvStoreProviders.push(provider); + } + + registerKvStoreAdapterProvider( + provider: (context: SharedKvStoreContext) => KvStoreAdapterProvider, + ) { + this.kvStoreAdapterProviders.push(provider); + } + + applyToContext(context: SharedKvStoreContext) { + const { kvStoreContext } = context; + for (const key of [ + "baseKvStoreProviders", + "kvStoreAdapterProviders", + ] as const) { + const map = kvStoreContext[key]; + for (const providerFactory of this[key]) { + const provider = providerFactory(context); + const { scheme } = provider; + if (map.has(scheme)) { + throw new Error(`Duplicate kvstore scheme ${scheme}`); + } + map.set(scheme, provider as any); + } + } + this.autoDetectRegistry.copyTo(context.kvStoreContext.autoDetectRegistry); + } +} + +export const frontendBackendIsomorphicKvStoreProviderRegistry = + new KvStoreProviderRegistry(); diff --git a/src/kvstore/s3/index.ts b/src/kvstore/s3/index.ts new file mode 100644 index 0000000000..d412406174 --- /dev/null +++ b/src/kvstore/s3/index.ts @@ -0,0 +1,78 @@ +/** + * @license + * Copyright 2024 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { read, stat } from "#src/kvstore/http/read.js"; +import type { + KvStore, + DriverListOptions, + ListResponse, + DriverReadOptions, + ReadResponse, + StatOptions, + StatResponse, +} from "#src/kvstore/index.js"; +import { getS3BucketListing } from "#src/kvstore/s3/list.js"; +import { encodePathForUrl } from "#src/kvstore/url.js"; +import type { FetchOk } from "#src/util/http_request.js"; +import { fetchOk } from "#src/util/http_request.js"; +import { ProgressSpan } from "#src/util/progress_listener.js"; + +export class S3KvStore implements KvStore { + constructor( + public baseUrl: string, + public baseUrlForDisplay: string, + private fetchOkImpl: FetchOk = fetchOk, + ) {} + + stat(key: string, options: StatOptions): Promise { + const url = `${this.baseUrl}${key}`; + return stat(this, key, url, options, this.fetchOkImpl); + } + + read( + key: string, + options: DriverReadOptions, + ): Promise { + const url = `${this.baseUrl}${key}`; + return read(this, key, url, options, this.fetchOkImpl); + } + + list(prefix: string, options: DriverListOptions): Promise { + const { progressListener } = options; + using _span = + progressListener === undefined + ? undefined + : new ProgressSpan(progressListener, { + message: `Listing prefix ${this.getUrl(prefix)}`, + }); + return getS3BucketListing(this.baseUrl, prefix, { + fetchOkImpl: this.fetchOkImpl, + signal: options.signal, + progressListener, + }); + } + + getUrl(path: string) { + return this.baseUrlForDisplay + encodePathForUrl(path); + } + + get supportsOffsetReads() { + return true; + } + get supportsSuffixReads() { + return true; + } +} diff --git a/src/kvstore/s3/list.ts b/src/kvstore/s3/list.ts new file mode 100644 index 0000000000..3580689ddd --- /dev/null +++ b/src/kvstore/s3/list.ts @@ -0,0 +1,77 @@ +/** + * @license + * Copyright 2019 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ListEntry, ListResponse } from "#src/kvstore/index.js"; +import type { FetchOk } from "#src/util/http_request.js"; +import { fetchOk } from "#src/util/http_request.js"; +import type { ProgressOptions } from "#src/util/progress_listener.js"; + +export async function getS3BucketListing( + bucketUrl: string, + prefix: string, + options: { + delimiter?: string; + fetchOkImpl?: FetchOk; + } & Partial = {}, +): Promise { + const { + delimiter = "/", + fetchOkImpl = fetchOk, + signal, + progressListener, + } = options; + const response = await fetchOkImpl( + `${bucketUrl}?prefix=${encodeURIComponent(prefix)}` + + `&delimiter=${encodeURIComponent(delimiter)}`, + /*init=*/ { + signal: signal, + progressListener, + }, + ); + const text = await response.text(); + const doc = new DOMParser().parseFromString(text, "application/xml"); + const namespaceResolver: XPathNSResolver = () => + "http://doc.s3.amazonaws.com/2006-03-01/"; + const commonPrefixNodes = doc.evaluate( + "//CommonPrefixes/Prefix", + doc, + namespaceResolver, + XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, + null, + ); + const directories: string[] = []; + for (let i = 0, n = commonPrefixNodes.snapshotLength; i < n; ++i) { + const name = commonPrefixNodes.snapshotItem(i)!.textContent; + if (name === null) continue; + // Exclude delimiter from end of `name`. + directories.push(name.substring(0, name.length - delimiter.length)); + } + + const entries: ListEntry[] = []; + const contents = doc.evaluate( + "//Contents/Key", + doc, + namespaceResolver, + XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, + null, + ); + for (let i = 0, n = contents.snapshotLength; i < n; ++i) { + const name = contents.snapshotItem(i)!.textContent; + if (name === null) continue; + entries.push({ key: name }); + } + return { directories, entries }; +} diff --git a/src/kvstore/s3/register.ts b/src/kvstore/s3/register.ts new file mode 100644 index 0000000000..b6545d5a01 --- /dev/null +++ b/src/kvstore/s3/register.ts @@ -0,0 +1,46 @@ +/** + * @license + * Copyright 2024 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { BaseKvStoreProvider } from "#src/kvstore/context.js"; +import type { SharedKvStoreContextBase } from "#src/kvstore/register.js"; +import { frontendBackendIsomorphicKvStoreProviderRegistry } from "#src/kvstore/register.js"; + +import { S3KvStore } from "#src/kvstore/s3/index.js"; + +function s3Provider(_context: SharedKvStoreContextBase): BaseKvStoreProvider { + return { + scheme: "s3", + description: "S3 (anonymous)", + getKvStore(url) { + const m = (url.suffix ?? "").match(/^\/\/([^/]+)(\/.*)?$/); + if (m === null) { + throw new Error("Invalid URL, expected `s3:///`"); + } + const [, bucket, path] = m; + return { + store: new S3KvStore( + `https://${bucket}.s3.amazonaws.com/`, + `s3://${bucket}/`, + ), + path: decodeURIComponent((path ?? "").substring(1)), + }; + }, + }; +} + +frontendBackendIsomorphicKvStoreProviderRegistry.registerBaseKvStoreProvider( + s3Provider, +); diff --git a/typings/glsl-editor.d.ts b/src/kvstore/shared_common.ts similarity index 68% rename from typings/glsl-editor.d.ts rename to src/kvstore/shared_common.ts index c32e7ba06d..a3bfb367ce 100644 --- a/typings/glsl-editor.d.ts +++ b/src/kvstore/shared_common.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2020 Google Inc. + * Copyright 2024 Google Inc. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -14,11 +14,8 @@ * limitations under the License. */ -/** - * Basic typings for glsl-editor package. - */ -declare module "glsl-editor/glsl.js" { - import CodeMirror from "codemirror"; - const f: (codeMirror: typeof CodeMirror) => void; - export default f; -} +export const SHARED_KVSTORE_CONTEXT_RPC_ID = "SharedKvStoreContext"; + +export const STAT_RPC_ID = "SharedKvStoreContext.stat"; +export const READ_RPC_ID = "SharedKvStoreContext.read"; +export const LIST_RPC_ID = "SharedKvStoreContext.list"; diff --git a/src/kvstore/special/index.ts b/src/kvstore/special/index.ts deleted file mode 100644 index 22423b00e6..0000000000 --- a/src/kvstore/special/index.ts +++ /dev/null @@ -1,187 +0,0 @@ -/** - * @license - * Copyright 2023 Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import type { - ByteRange, - ByteRangeRequest, - ReadableKvStore, - ReadOptions, - ReadResponse, -} from "#src/kvstore/index.js"; -import { composeByteRangeRequest } from "#src/kvstore/index.js"; -import { uncancelableToken } from "#src/util/cancellation.js"; -import { HttpError, isNotFoundError } from "#src/util/http_request.js"; -import type { SpecialProtocolCredentialsProvider } from "#src/util/special_protocol_request.js"; -import { cancellableFetchSpecialOk } from "#src/util/special_protocol_request.js"; - -function getRangeHeader( - request: ByteRangeRequest | undefined, -): string | undefined { - if (request === undefined) return undefined; - if ("suffixLength" in request) { - return `bytes=-${request.suffixLength}`; - } - return `bytes=${request.offset}-${request.offset + request.length - 1}`; -} - -/** - * On Chromium, multiple concurrent byte range requests to the same URL are serialized unless the - * cache is disabled. Disabling the cache works around the problem. - * - * https://bugs.chromium.org/p/chromium/issues/detail?id=969828 - */ -const byteRangeCacheMode = - navigator.userAgent.indexOf("Chrome") !== -1 ? "no-store" : "default"; - -class SpecialProtocolKvStore implements ReadableKvStore { - constructor( - public credentialsProvider: SpecialProtocolCredentialsProvider, - public baseUrl: string, - ) {} - - async getObjectLength(url: string, options: ReadOptions) { - // Use a HEAD request to get the length of an object - const { cancellationToken = uncancelableToken } = options; - const headResponse = await cancellableFetchSpecialOk( - this.credentialsProvider, - url, - { method: "HEAD" }, - async (response) => response, - cancellationToken, - ); - - if (headResponse.status !== 200) { - throw new Error( - "Failed to determine total size in order to fetch suffix", - ); - } - const contentLength = headResponse.headers.get("content-length"); - if (contentLength === undefined) { - throw new Error( - "Failed to determine total size in order to fetch suffix", - ); - } - const contentLengthNumber = Number(contentLength); - return contentLengthNumber; - } - - async read( - key: string, - options: ReadOptions, - ): Promise { - const { cancellationToken = uncancelableToken } = options; - let { byteRange: byteRangeRequest } = options; - const url = this.baseUrl + key; - for (let attempt = 0; ; ++attempt) { - try { - const requestInit: RequestInit = {}; - const rangeHeader = getRangeHeader(byteRangeRequest); - if (rangeHeader !== undefined) { - requestInit.headers = { range: rangeHeader }; - requestInit.cache = byteRangeCacheMode; - } - const { response, data } = await cancellableFetchSpecialOk( - this.credentialsProvider, - url, - requestInit, - async (response) => ({ - response, - data: await response.arrayBuffer(), - }), - cancellationToken, - ); - let byteRange: ByteRange | undefined; - let totalSize: number | undefined; - if (response.status === 206) { - const contentRange = response.headers.get("content-range"); - if (contentRange === null) { - if (byteRangeRequest !== undefined) { - if ("suffixLength" in byteRangeRequest) { - const objectSize = await this.getObjectLength(url, options); - byteRange = { - offset: objectSize - byteRangeRequest.suffixLength, - length: Number(response.headers.get("content-length")), - }; - } else { - byteRange = { - offset: byteRangeRequest.offset, - length: data.byteLength, - }; - } - } else { - throw new Error( - "Unexpected HTTP 206 response when no byte range specified.", - ); - } - } - if (contentRange !== null) { - const m = contentRange.match( - /bytes ([0-9]+)-([0-9]+)\/([0-9]+|\*)/, - ); - if (m === null) { - throw new Error( - `Invalid content-range header: ${JSON.stringify(contentRange)}`, - ); - } - const beginPos = parseInt(m[1], 10); - const endPos = parseInt(m[2], 10); - if (endPos !== beginPos + data.byteLength - 1) { - throw new Error( - `Length in content-range header ${JSON.stringify( - contentRange, - )} does not match content length ${data.byteLength}`, - ); - } - totalSize = m[3] === "*" ? undefined : parseInt(m[3], 10); - byteRange = { offset: beginPos, length: data.byteLength }; - } - } - if (byteRange === undefined) { - byteRange = { offset: 0, length: data.byteLength }; - totalSize = data.byteLength; - } - return { data: new Uint8Array(data), dataRange: byteRange, totalSize }; - } catch (e) { - if ( - attempt === 0 && - e instanceof HttpError && - e.status === 416 && - options.byteRange !== undefined && - "suffixLength" in options.byteRange - ) { - // Some servers, such as the npm http-server package, do not support suffixLength - // byte-range requests. - const contentLengthNumber = await this.getObjectLength(url, options); - byteRangeRequest = composeByteRangeRequest( - { offset: 0, length: contentLengthNumber }, - byteRangeRequest, - ).outer; - continue; - } - if (isNotFoundError(e)) { - return undefined; - } - throw e; - } - } - } -} -export function getSpecialProtocolKvStore( - credentialsProvider: SpecialProtocolCredentialsProvider, - baseUrl: string, -): ReadableKvStore { - return new SpecialProtocolKvStore(credentialsProvider, baseUrl); -} diff --git a/src/kvstore/url.ts b/src/kvstore/url.ts new file mode 100644 index 0000000000..83fdd78a00 --- /dev/null +++ b/src/kvstore/url.ts @@ -0,0 +1,202 @@ +/** + * @license + * Copyright 2024 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export function kvstoreEnsureDirectoryPipelineUrl(url: string): string { + const m = url.match( + /^((?:.*?\|)?)([a-zA-Z][a-zA-Z0-9-+.]*)(?:(:[^?#|]*)((?:[?#][^|]*)?))?$/, + ); + if (m === null) { + throw new Error(`Invalid URL: ${url}`); + } + const [, pipelinePrefix, scheme, path, queryAndFragment] = m; + if (path === undefined) { + return `${pipelinePrefix}${scheme}:`; + } + if (path === ":" || path.endsWith("/")) return url; + return `${pipelinePrefix}${scheme}${path}/${queryAndFragment ?? ""}`; +} + +export function finalPipelineUrlComponent(url: string) { + // match is infallible + const m = url.match(/.*?([^|]*)$/)!; + return m[1]; +} + +export const schemePattern = /^(?:([a-zA-Z][a-zA-Z0-9-+.]*):)?(.*)$/; + +export function parsePipelineUrlComponent(url: string): UrlWithParsedScheme { + // schemePattern always matches + const m = url.match(schemePattern)!; + const scheme = m[1]; + const suffix = m[2]; + if (scheme === undefined) { + return { url, scheme: url, suffix: undefined }; + } else { + return { url, scheme: scheme, suffix }; + } +} + +export const urlComponentPattern = + /^(?:([a-zA-Z][a-zA-Z0-9-+.]*):)?([^?#]*)(?:\?([^#]*))?(?:#(.*))?$/; + +export function parseUrlSuffix(suffix: string | undefined): { + authorityAndPath: string | undefined; + query: string | undefined; + fragment: string | undefined; +} { + if (suffix === undefined) { + return { + authorityAndPath: undefined, + query: undefined, + fragment: undefined, + }; + } + // Infallible pattern. + const [, authorityAndPath, query, fragment] = suffix.match( + /^([^?#]*)(?:\?([^#]*))?(?:#(.*))?$/, + )!; + return { + authorityAndPath, + query: query ?? undefined, + fragment: fragment ?? undefined, + }; +} + +export interface UrlWithParsedScheme { + // Full original URL. + url: string; + + // Scheme (excluding ":"). + scheme: string; + + // Suffix following ":", including initial "//" if present. + suffix: string | undefined; +} + +// Splits a URL containing multiple "|"-separate parts. +export function splitPipelineUrl(url: string): UrlWithParsedScheme[] { + return url.split("|").map(parsePipelineUrlComponent); +} + +export function pipelineUrlJoin( + baseUrl: string, + ...additionalParts: string[] +): string { + // Strip off any ? or # parameters, since they are not part of the path. + // Infallible pattern + let [, base, queryAndFragment] = baseUrl.match(/^(.*?[^|?#]*)([^|]*)$/)!; + for (let part of additionalParts) { + if (part.startsWith("/")) { + part = part.substring(1); + } + if (part === "") continue; + base = kvstoreEnsureDirectoryPipelineUrl(base); + base += part; + } + return base + queryAndFragment; +} + +export function joinPath(base: string, ...additionalParts: string[]) { + for (let part of additionalParts) { + if (part.startsWith("/")) { + part = part.substring(1); + } + if (part === "") continue; + base = ensurePathIsDirectory(base); + base += part; + } + return base; +} + +export function ensurePathIsDirectory(path: string) { + if (!pathIsDirectory(path)) { + path += "/"; + } + return path; +} + +export function ensureNoQueryOrFragmentParameters(url: UrlWithParsedScheme) { + const { suffix } = url; + if (suffix === undefined) return; + if (suffix.match(/[#?]/)) { + throw new Error( + `Invalid URL ${url.url}: query parameters and/or fragment not supported`, + ); + } +} + +export function ensureEmptyUrlSuffix(url: UrlWithParsedScheme) { + if (url.suffix) { + throw new Error( + `Invalid URL syntax ${JSON.stringify(url.url)}, expected "${url.scheme}:"`, + ); + } +} + +export function extractQueryAndFragment(url: string): { + base: string; + queryAndFragment: string; +} { + const [, base, queryAndFragment] = url.match(/^(.*?[^|?#]*)([^|]*)$/)!; + return { base, queryAndFragment }; +} + +// Resolves `relativePath` relative to `basePath`. +// +// Note that the parameters are both expected to be plain paths, not full URLs +// or URL pipelines. +export function resolveRelativePath(basePath: string, relativePath: string) { + const origBasePath = basePath; + if (basePath.endsWith("/")) { + basePath = basePath.substring(0, basePath.length - 1); + } + for (const component of relativePath.split("/")) { + if (component === "" || component === ".") { + continue; + } + if (component === "..") { + const prevSlash = basePath.lastIndexOf("/"); + if (prevSlash <= 0) { + throw new Error( + `Invalid relative path ${JSON.stringify(relativePath)} from base path ${JSON.stringify(origBasePath)}`, + ); + } + basePath = basePath.substring(0, prevSlash); + continue; + } + if (basePath !== "") { + basePath += "/"; + } + basePath += component; + } + if (relativePath.endsWith("/")) { + basePath += "/"; + } + return basePath; +} + +export function pathIsDirectory(path: string) { + return path === "" || path.endsWith("/"); +} + +// Plain paths can have arbitrary characters, but to be included in a URL +// pipeline, special characters must be percent encoded. +export function encodePathForUrl(path: string) { + return encodeURI(path).replace( + /[?#]/g, + (c) => `%${c.charCodeAt(0).toString(16).toUpperCase()}`, + ); +} diff --git a/src/kvstore/zip/auto_detect.ts b/src/kvstore/zip/auto_detect.ts new file mode 100644 index 0000000000..521002f6f7 --- /dev/null +++ b/src/kvstore/zip/auto_detect.ts @@ -0,0 +1,46 @@ +/** + * @license + * Copyright 2025 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { + AutoDetectFileOptions, + AutoDetectMatch, + AutoDetectRegistry, +} from "#src/kvstore/auto_detect.js"; +import { + EOCDR_WITHOUT_COMMENT_SIZE, + parseEndOfCentralDirectoryRecord, +} from "#src/kvstore/zip/metadata.js"; + +async function detectZip( + options: AutoDetectFileOptions, +): Promise { + const { suffix } = options; + if (suffix === undefined) return []; + if (parseEndOfCentralDirectoryRecord(suffix) === undefined) return []; + return [{ suffix: "zip:", description: "ZIP archive" }]; +} + +export function registerAutoDetect(registry: AutoDetectRegistry) { + registry.registerFileFormat({ + prefixLength: 0, + // To ensure all valid zip file are detected, this should be set to + // `EOCDR_WITHOUT_COMMENT_SIZE + MAX_COMMENT_SIZE`. In practice, though, zip + // files with comments are rare and 4096 should be sufficient for most + // cases while avoiding reading an excessive amount for auto-detection. + suffixLength: EOCDR_WITHOUT_COMMENT_SIZE + 4096, + match: detectZip, + }); +} diff --git a/src/kvstore/zip/backend.ts b/src/kvstore/zip/backend.ts new file mode 100644 index 0000000000..00d021fe98 --- /dev/null +++ b/src/kvstore/zip/backend.ts @@ -0,0 +1,255 @@ +/** + * @license + * Copyright 2025 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { ChunkManager } from "#src/chunk_manager/backend.js"; +import { makeSimpleAsyncCache } from "#src/chunk_manager/generic_file_source.js"; +import { FileByteRangeHandle } from "#src/kvstore/byte_range/file_handle.js"; +import { GzipFileHandle } from "#src/kvstore/gzip/file_handle.js"; +import type { + DriverListOptions, + DriverReadOptions, + FileHandle, + KvStore, + ListEntry, + ListResponse, + ReadResponse, + StatOptions, + StatResponse, +} from "#src/kvstore/index.js"; +import { readFileHandle } from "#src/kvstore/index.js"; +import { encodePathForUrl } from "#src/kvstore/url.js"; +import type { + ZipMetadata, + Reader, + ZipEntry, +} from "#src/kvstore/zip/metadata.js"; +import { + readZipMetadata, + readEntryDataHeader, + ZipCompressionMethod, +} from "#src/kvstore/zip/metadata.js"; +import { + binarySearch, + binarySearchLowerBound, + filterArrayInplace, +} from "#src/util/array.js"; +import { + ProgressSpan, + type ProgressOptions, +} from "#src/util/progress_listener.js"; +import { defaultStringCompare } from "#src/util/string.js"; + +function makeZipReader(base: FileHandle): Reader { + return async ( + offset: number, + length: number, + options: Partial, + ) => { + const readResponse = await readFileHandle(base, { + throwIfMissing: true, + byteRange: { offset, length }, + strictByteRange: true, + signal: options.signal, + progressListener: options.progressListener, + }); + return new Uint8Array(await readResponse.response.arrayBuffer()); + }; +} + +interface CachedZipEntry extends ZipEntry { + fileDataStart?: number; +} + +interface CachedZipMetadata extends ZipMetadata { + entries: CachedZipEntry[]; +} + +function getZipMetadataCache(chunkManager: ChunkManager, base: FileHandle) { + const url = base.getUrl(); + return makeSimpleAsyncCache(chunkManager, `zipMetadata:${url}`, { + get: async (_unusedCacheKey: undefined, progressOptions) => { + using _span = new ProgressSpan(progressOptions.progressListener, { + message: `Reading ZIP central directory from ${url}`, + }); + const statResponse = await base.stat(progressOptions); + if (statResponse?.totalSize === undefined) { + throw new Error(`Failed to determine ZIP file size: ${url}`); + } + const metadata = await readZipMetadata( + makeZipReader(base), + statResponse.totalSize, + progressOptions, + ); + // Zip files sometimes contain zero-length files corresponding to + // directories. + filterArrayInplace( + metadata.entries, + (entry) => !entry.fileName.endsWith("/"), + ); + metadata.entries.sort((a, b) => + defaultStringCompare(a.fileName, b.fileName), + ); + return { data: metadata, size: metadata.sizeEstimate }; + }, + }); +} + +async function getZipMetadata( + chunkManager: ChunkManager, + base: FileHandle, + options: Partial, +): Promise { + const cache = getZipMetadataCache(chunkManager, base); + try { + return (await cache.get(undefined, options)) as CachedZipMetadata; + } finally { + cache.dispose(); + } +} + +function findEntry( + metadata: CachedZipMetadata, + key: string, +): CachedZipEntry | undefined { + const { entries } = metadata; + const index = binarySearch(entries, key, (key, entry) => + defaultStringCompare(key, entry.fileName), + ); + if (index < 0) return undefined; + return entries[index]; +} + +function list(metadata: ZipMetadata, prefix: string) { + const { entries } = metadata; + const startIndex = binarySearchLowerBound( + 0, + entries.length, + (index) => entries[index].fileName >= prefix, + ); + + const endIndex = binarySearchLowerBound( + Math.min(entries.length, startIndex + 1), + entries.length, + (index) => !entries[index].fileName.startsWith(prefix), + ); + + const listEntries: ListEntry[] = []; + const directories: string[] = []; + + for (let index = startIndex; index < endIndex; ) { + const entry = entries[index]; + const i = entry.fileName.indexOf("/", prefix.length); + if (i === -1) { + // Filename + listEntries.push({ key: entry.fileName }); + ++index; + } else { + // Directory + directories.push(entry.fileName.substring(0, i)); + const directoryPrefix = entry.fileName.substring(0, i + 1); + index = binarySearchLowerBound( + index + 1, + endIndex, + (index) => !entries[index].fileName.startsWith(directoryPrefix), + ); + } + } + + return { entries: listEntries, directories }; +} + +export class ZipKvStore + implements KvStore +{ + constructor( + public chunkManager: ChunkManager, + public base: BaseFileHandle, + ) {} + + private metadata: ZipMetadata | undefined; + + private async getMetadata(options: Partial) { + let { metadata } = this; + if (metadata === undefined) { + metadata = this.metadata = await getZipMetadata( + this.chunkManager, + this.base, + options, + ); + } + return metadata; + } + + getUrl(key: string) { + return this.base.getUrl() + `|zip:${encodePathForUrl(key)}`; + } + + async stat( + key: string, + options: StatOptions, + ): Promise { + const entry = findEntry(await this.getMetadata(options), key); + if (entry === undefined) return undefined; + return { totalSize: entry.uncompressedSize }; + } + + async read( + key: string, + options: DriverReadOptions, + ): Promise { + const entry = findEntry(await this.getMetadata(options), key); + if (entry === undefined) return undefined; + let { fileDataStart } = entry; + if (fileDataStart === undefined) { + fileDataStart = entry.fileDataStart = await readEntryDataHeader( + makeZipReader(this.base), + entry, + options, + ); + } + let handle: FileHandle = new FileByteRangeHandle(this.base, { + offset: fileDataStart, + length: entry.compressedSize, + }); + switch (entry.compressionMethod) { + case ZipCompressionMethod.STORE: + break; + case ZipCompressionMethod.DEFLATE: + handle = new GzipFileHandle(handle, "deflate-raw"); + break; + default: + throw new Error( + `Unsupported compression method: ${entry.compressionMethod}`, + ); + } + return handle.read(options); + } + + async list( + prefix: string, + options: DriverListOptions, + ): Promise { + const metadata = await this.getMetadata(options); + return list(metadata, prefix); + } + + get supportsOffsetReads() { + return true; + } + get supportsSuffixReads() { + return true; + } +} diff --git a/src/kvstore/zip/frontend.ts b/src/kvstore/zip/frontend.ts new file mode 100644 index 0000000000..959254c444 --- /dev/null +++ b/src/kvstore/zip/frontend.ts @@ -0,0 +1,40 @@ +/** + * @license + * Copyright 2025 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { SharedKvStoreContext } from "#src/kvstore/frontend.js"; +import { ProxyKvStore } from "#src/kvstore/frontend.js"; +import type { KvStore, KvStoreFileHandle } from "#src/kvstore/index.js"; +import { encodePathForUrl } from "#src/kvstore/url.js"; + +export class ZipKvStore extends ProxyKvStore implements KvStore { + constructor( + sharedKvStoreContext: SharedKvStoreContext, + public base: KvStoreFileHandle, + ) { + super(sharedKvStoreContext); + } + + getUrl(key: string) { + return this.base.getUrl() + `|zip:${encodePathForUrl(key)}`; + } + + get supportsOffsetReads() { + return true; + } + get supportsSuffixReads() { + return true; + } +} diff --git a/src/kvstore/zip/metadata.ts b/src/kvstore/zip/metadata.ts new file mode 100644 index 0000000000..dbf864ab05 --- /dev/null +++ b/src/kvstore/zip/metadata.ts @@ -0,0 +1,658 @@ +/** + * @license + * Copyright 2025 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * Derived from https://github.com/greggman/unzipit/blob/4d94c9b77f7815062ff4460311e8b3ce4f7d5deb/src/unzipit.js + * + * Includes only parsing of raw entries. + * + * @license + * + * The MIT License (MIT) + * + * Copyright (c) 2014 Josh Wolfe + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * MIT License + * + * Copyright (c) 2019 Gregg Tavares + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import { buf as crc32buf } from "crc-32"; +import type { ProgressOptions } from "#src/util/progress_listener.js"; + +export interface ZipEntry { + versionMadeBy: number; + versionNeededToExtract: number; + generalPurposeBitFlag: number; + compressionMethod: number; + lastModFileTime: number; + lastModFileDate: number; + crc32: number; + compressedSize: number; + uncompressedSize: number; + nameBytes: Uint8Array; + commentBytes: Uint8Array; + internalFileAttributes: number; + externalFileAttributes: number; + relativeOffsetOfLocalHeader: number; + fileName: string; +} + +export interface ZipMetadata { + entries: ZipEntry[]; + commentBytes: Uint8Array; + // Estimated size in bytes of metadata. + sizeEstimate: number; +} + +export const EOCDR_WITHOUT_COMMENT_SIZE = 22; +export const MAX_COMMENT_SIZE = 0xffff; // 2-byte size +const EOCDR_SIGNATURE = 0x06054b50; +const ZIP64_EOCDR_SIGNATURE = 0x06064b50; + +export interface Reader { + ( + offset: number, + length: number, + progressOptions: Partial, + ): Promise>; +} + +function lastReadCachingReader(base: Reader) { + let lastReadOffset: number = 0; + let lastReadBuffer: Uint8Array | undefined; + + return async function lastReadCachingRead( + offset: number, + length: number, + progressOptions: Partial, + ): Promise> { + if (lastReadBuffer !== undefined) { + if ( + offset > lastReadOffset && + offset + length <= lastReadOffset + lastReadBuffer.length + ) { + return lastReadBuffer.subarray( + offset - lastReadOffset, + offset + length - lastReadOffset, + ); + } + } + + const newBuffer = await base(offset, length, progressOptions); + lastReadOffset = offset; + lastReadBuffer = newBuffer; + return newBuffer; + }; +} + +export function parseEndOfCentralDirectoryRecord(data: Uint8Array): + | { + eocdrOffset: number; + diskNumber: number; + entryCount: number; + centralDirectorySize: number; + centralDirectoryOffset: number; + } + | undefined { + const dv = new DataView(data.buffer, data.byteOffset, data.byteLength); + const size = data.length; + for (let i = size - EOCDR_WITHOUT_COMMENT_SIZE; i >= 0; --i) { + // 0 - End of central directory signature + if (dv.getUint32(i, /*littleEndian=*/ true) !== EOCDR_SIGNATURE) { + continue; + } + + // 20 - Comment length + const commentLength = dv.getUint16(i + 20, /*littleEndian=*/ true); + const expectedCommentLength = size - i - EOCDR_WITHOUT_COMMENT_SIZE; + if (commentLength !== expectedCommentLength) { + continue; + } + + // 4 - Number of this disk + const diskNumber = dv.getUint16(i + 4, /*littleEndian=*/ true); + + // 6 - Disk where central directory starts + // 8 - Number of central directory records on this disk + // 10 - Total number of central directory records + const entryCount = dv.getUint16(i + 10, /*littleEndian=*/ true); + // 12 - Size of central directory (bytes) + const centralDirectorySize = dv.getUint32(i + 12, /*littleEndian=*/ true); + // 16 - Offset of start of central directory, relative to start of archive + const centralDirectoryOffset = dv.getUint32(i + 16, /*littleEndian=*/ true); + + return { + eocdrOffset: i, + diskNumber, + entryCount, + centralDirectorySize, + centralDirectoryOffset, + }; + } + + return undefined; +} + +async function findEndOfCentralDirectory( + reader: Reader, + totalLength: number, + options: Partial, +) { + const size = Math.min( + EOCDR_WITHOUT_COMMENT_SIZE + MAX_COMMENT_SIZE, + totalLength, + ); + const readStart = totalLength - size; + const data = await reader(readStart, size, options); + const record = parseEndOfCentralDirectoryRecord(data); + if (record === undefined) { + throw new Error( + "End of central directory record signature not found; either not a zip file or file is truncated.", + ); + } + const { + eocdrOffset, + diskNumber, + entryCount, + centralDirectorySize, + centralDirectoryOffset, + } = record; + if (diskNumber !== 0) { + throw new Error( + `Multi-volume zip files are not supported. This is volume: ${diskNumber}`, + ); + } + + // 22 - Comment + // the encoding is always cp437. + const commentBytes = data.slice(eocdrOffset + 22, data.length); + + if (entryCount === 0xffff || centralDirectoryOffset === 0xffffffff) { + return await readZip64CentralDirectory( + reader, + eocdrOffset, + commentBytes, + options, + ); + } else { + return await readEntries( + reader, + centralDirectoryOffset, + centralDirectorySize, + entryCount, + commentBytes, + options, + ); + } +} + +const END_OF_CENTRAL_DIRECTORY_LOCATOR_SIGNATURE = 0x07064b50; + +async function readZip64CentralDirectory( + reader: Reader, + offset: number, + commentBytes: Uint8Array, + progressOptions: Partial, +) { + // ZIP64 Zip64 end of central directory locator + const zip64EocdlOffset = offset - 20; + const eocdl = await reader(zip64EocdlOffset, 20, progressOptions); + + const eocdlDv = new DataView( + eocdl.buffer, + eocdl.byteOffset, + eocdl.byteLength, + ); + + // 0 - zip64 end of central dir locator signature + if ( + eocdlDv.getUint32(0, /*littleEndian=*/ true) !== + END_OF_CENTRAL_DIRECTORY_LOCATOR_SIGNATURE + ) { + throw new Error("invalid zip64 end of central directory locator signature"); + } + + // 4 - number of the disk with the start of the zip64 end of central directory + // 8 - relative offset of the zip64 end of central directory record + const zip64EocdrOffset = eocdlDv.getBigUint64(8, /*littleEndian=*/ true); + // 16 - total number of disks + + // ZIP64 end of central directory record + const zip64Eocdr = await reader( + Number(zip64EocdrOffset), + 56, + progressOptions, + ); + + const zip64EocdrDv = new DataView( + zip64Eocdr.buffer, + zip64Eocdr.byteOffset, + zip64Eocdr.byteLength, + ); + + // 0 - zip64 end of central dir signature 4 bytes (0x06064b50) + if ( + zip64EocdrDv.getUint32(0, /*littleEndian=*/ true) !== ZIP64_EOCDR_SIGNATURE + ) { + throw new Error("invalid zip64 end of central directory record signature"); + } + // 4 - size of zip64 end of central directory record 8 bytes + // 12 - version made by 2 bytes + // 14 - version needed to extract 2 bytes + // 16 - number of this disk 4 bytes + // 20 - number of the disk with the start of the central directory 4 bytes + // 24 - total number of entries in the central directory on this disk 8 bytes + // 32 - total number of entries in the central directory 8 bytes + const entryCount = zip64EocdrDv.getBigUint64(32, /*littleEndian=*/ true); + // 40 - size of the central directory 8 bytes + const centralDirectorySize = zip64EocdrDv.getBigUint64( + 40, + /*littleEndian=*/ true, + ); + // 48 - offset of start of central directory with respect to the starting disk number 8 bytes + const centralDirectoryOffset = zip64EocdrDv.getBigUint64( + 48, + /*littleEndian=*/ true, + ); + // 56 - zip64 extensible data sector (variable size) + return readEntries( + reader, + Number(centralDirectoryOffset), + Number(centralDirectorySize), + Number(entryCount), + commentBytes, + progressOptions, + ); +} + +const CENTRAL_DIRECTORY_FILE_HEADER_SIGNATURE = 0x02014b50; + +async function readEntries( + reader: Reader, + centralDirectoryOffset: number, + centralDirectorySize: number, + rawEntryCount: number, + commentBytes: Uint8Array, + progressOptions: Partial, +): Promise { + let readEntryCursor = 0; + const allEntriesBuffer = await reader( + centralDirectoryOffset, + centralDirectorySize, + progressOptions, + ); + const rawEntries = []; + + const dv = new DataView( + allEntriesBuffer.buffer, + allEntriesBuffer.byteOffset, + allEntriesBuffer.byteLength, + ); + + const textDecoder = new TextDecoder(); + + for (let e = 0; e < rawEntryCount; ++e) { + // 0 - Central directory file header signature + const signature = dv.getUint32(readEntryCursor + 0, /*littleEndian=*/ true); + if (signature !== CENTRAL_DIRECTORY_FILE_HEADER_SIGNATURE) { + throw new Error( + `invalid central directory file header signature: 0x${signature.toString(16)}`, + ); + } + // 4 - Version made by + const versionMadeBy = dv.getUint16( + readEntryCursor + 4, + /*littleEndian=*/ true, + ); + // 6 - Version needed to extract (minimum) + const versionNeededToExtract = dv.getUint16( + readEntryCursor + 6, + /*littleEndian=*/ true, + ); + // 8 - General purpose bit flag + const generalPurposeBitFlag = dv.getUint16( + readEntryCursor + 8, + /*littleEndian=*/ true, + ); + // 10 - Compression method + const compressionMethod = dv.getUint16( + readEntryCursor + 10, + /*littleEndian=*/ true, + ); + // 12 - File last modification time + const lastModFileTime = dv.getUint16( + readEntryCursor + 12, + /*littleEndian=*/ true, + ); + // 14 - File last modification date + const lastModFileDate = dv.getUint16( + readEntryCursor + 14, + /*littleEndian=*/ true, + ); + // 16 - CRC-32 + const crc32 = dv.getUint32(readEntryCursor + 16, /*littleEndian=*/ true); + // 20 - Compressed size + let compressedSize = dv.getUint32( + readEntryCursor + 20, + /*littleEndian=*/ true, + ); + // 24 - Uncompressed size + let uncompressedSize = dv.getUint32( + readEntryCursor + 24, + /*littleEndian=*/ true, + ); + // 28 - File name length (n) + const fileNameLength = dv.getUint16( + readEntryCursor + 28, + /*littleEndian=*/ true, + ); + // 30 - Extra field length (m) + const extraFieldLength = dv.getUint16( + readEntryCursor + 30, + /*littleEndian=*/ true, + ); + // 32 - File comment length (k) + const fileCommentLength = dv.getUint16( + readEntryCursor + 32, + /*littleEndian=*/ true, + ); + // 34 - Disk number where file starts + // 36 - Internal file attributes + const internalFileAttributes = dv.getUint16( + readEntryCursor + 36, + /*littleEndian=*/ true, + ); + // 38 - External file attributes + const externalFileAttributes = dv.getUint32( + readEntryCursor + 38, + /*littleEndian=*/ true, + ); + // 42 - Relative offset of local file header + let relativeOffsetOfLocalHeader = dv.getUint32( + readEntryCursor + 42, + /*littleEndian=*/ true, + ); + + if (generalPurposeBitFlag & 0x40) { + throw new Error("strong encryption is not supported"); + } + + readEntryCursor += 46; + + // 46 - File name + let nameBytes = allEntriesBuffer.subarray( + readEntryCursor, + (readEntryCursor += fileNameLength), + ); + + let isUTF8 = (generalPurposeBitFlag & 0x800) !== 0; + + // 46+n - Extra field + const extraFields = []; + for (let i = 0; i < extraFieldLength - 3; ) { + const headerId = dv.getUint16( + readEntryCursor + i + 0, + /*littleEndian=*/ true, + ); + const dataSize = dv.getUint16( + readEntryCursor + i + 2, + /*littleEndian=*/ true, + ); + const dataStart = i + 4; + const dataEnd = dataStart + dataSize; + if (dataEnd > extraFieldLength) { + throw new Error("extra field length exceeds extra field buffer size"); + } + extraFields.push({ + id: headerId, + offset: readEntryCursor + dataStart, + length: dataSize, + }); + i = dataEnd; + } + readEntryCursor += extraFieldLength; + + // 46+n+m - File comment + const commentBytes = allEntriesBuffer.slice( + readEntryCursor, + (readEntryCursor += fileCommentLength), + ); + + if ( + uncompressedSize === 0xffffffff || + compressedSize === 0xffffffff || + relativeOffsetOfLocalHeader === 0xffffffff + ) { + // ZIP64 format + // find the Zip64 Extended Information Extra Field + const zip64ExtraField = extraFields.find((e) => e.id === 0x0001); + if (zip64ExtraField === undefined) { + throw new Error("expected zip64 extended information extra field"); + } + const { offset: zip64EiefBufferOffset, length: zip64EiefBufferLength } = + zip64ExtraField; + let index = 0; + // 0 - Original Size 8 bytes + if (uncompressedSize === 0xffffffff) { + if (index + 8 > zip64EiefBufferLength) { + throw new Error( + "zip64 extended information extra field does not include uncompressed size", + ); + } + uncompressedSize = Number( + dv.getBigUint64( + zip64EiefBufferOffset + index, + /*littleEndian=*/ true, + ), + ); + index += 8; + } + // 8 - Compressed Size 8 bytes + if (compressedSize === 0xffffffff) { + if (index + 8 > zip64EiefBufferLength) { + throw new Error( + "zip64 extended information extra field does not include compressed size", + ); + } + compressedSize = Number( + dv.getBigUint64( + zip64EiefBufferOffset + index, + /*littleEndian=*/ true, + ), + ); + index += 8; + } + // 16 - Relative Header Offset 8 bytes + if (relativeOffsetOfLocalHeader === 0xffffffff) { + if (index + 8 > zip64EiefBufferLength) { + throw new Error( + "zip64 extended information extra field does not include relative header offset", + ); + } + relativeOffsetOfLocalHeader = Number( + dv.getBigUint64( + zip64EiefBufferOffset + index, + /*littleEndian=*/ true, + ), + ); + index += 8; + } + // 24 - Disk Start Number 4 bytes + } + + // check for Info-ZIP Unicode Path Extra Field (0x7075) + // see https://github.com/thejoshwolfe/yauzl/issues/33 + const nameField = extraFields.find( + (e) => + e.id === 0x7075 && + e.length >= 6 && // too short to be meaningful + allEntriesBuffer[e.offset] === 1 && // Version 1 byte version of this extra field, currently 1 + dv.getInt32(e.offset + 1, /*littleEndian=*/ true) === + crc32buf(nameBytes), + ); // NameCRC32 4 bytes File Name Field CRC32 Checksum + // > If the CRC check fails, this UTF-8 Path Extra Field should be + // > ignored and the File Name field in the header should be used instead. + if (nameField) { + nameBytes = allEntriesBuffer.slice( + nameField.offset + 5, + nameField.offset + nameField.length, + ); + isUTF8 = true; + } + + // validate file size + if (compressionMethod === 0) { + let expectedCompressedSize = uncompressedSize; + if ((generalPurposeBitFlag & 0x1) !== 0) { + // traditional encryption prefixes the file data with a header + expectedCompressedSize += 12; + } + if (compressedSize !== expectedCompressedSize) { + throw new Error( + `compressed/uncompressed size mismatch for stored file: ${compressedSize} != ${expectedCompressedSize}`, + ); + } + } + + // Just decode as UTF-8 regardless of `isUTF8`, because the non-UTF8 + // encoding is difficult/impossible to determine correctly. + let fileName = textDecoder.decode(nameBytes); + fileName = fileName.replaceAll("\\", "/"); + isUTF8; + + const rawEntry: ZipEntry = { + versionMadeBy, + versionNeededToExtract, + generalPurposeBitFlag, + compressionMethod, + lastModFileTime, + lastModFileDate, + crc32, + compressedSize, + uncompressedSize, + nameBytes, + commentBytes, + internalFileAttributes, + externalFileAttributes, + relativeOffsetOfLocalHeader, + fileName, + }; + rawEntries.push(rawEntry); + } + return { + commentBytes, + entries: rawEntries, + // Estimate that the JavaScript representation consumes twice the memory of + // the encoded representation. + sizeEstimate: commentBytes.length + allEntriesBuffer.length * 2, + }; +} + +export async function readEntryDataHeader( + reader: Reader, + rawEntry: ZipEntry, + options: Partial, +) { + if (rawEntry.generalPurposeBitFlag & 0x1) { + throw new Error("encrypted entries not supported"); + } + const data = await reader(rawEntry.relativeOffsetOfLocalHeader, 30, options); + const dv = new DataView(data.buffer, data.byteOffset, data.byteLength); + + // 0 - Local file header signature = 0x04034b50 + const signature = dv.getUint32(0, /*littleEndian=*/ true); + if (signature !== 0x04034b50) { + throw new Error( + `invalid local file header signature: 0x${signature.toString(16)}`, + ); + } + + // all this should be redundant + // 4 - Version needed to extract (minimum) + // 6 - General purpose bit flag + // 8 - Compression method + // 10 - File last modification time + // 12 - File last modification date + // 14 - CRC-32 + // 18 - Compressed size + // 22 - Uncompressed size + // 26 - File name length (n) + const fileNameLength = dv.getUint16(26, /*littleEndian=*/ true); + // 28 - Extra field length (m) + const extraFieldLength = dv.getUint16(28, /*littleEndian=*/ true); + // 30 - File name + // 30+n - Extra field + const localFileHeaderEnd = + rawEntry.relativeOffsetOfLocalHeader + + data.length + + fileNameLength + + extraFieldLength; + + return localFileHeaderEnd; +} + +export async function readZipMetadata( + reader: Reader, + totalLength: number, + options: Partial, +): Promise { + return await findEndOfCentralDirectory( + lastReadCachingReader(reader), + totalLength, + options, + ); +} + +export enum ZipCompressionMethod { + STORE = 0, + DEFLATE = 8, +} diff --git a/src/kvstore/zip/register_backend.ts b/src/kvstore/zip/register_backend.ts new file mode 100644 index 0000000000..e90a4eed17 --- /dev/null +++ b/src/kvstore/zip/register_backend.ts @@ -0,0 +1,43 @@ +/** + * @license + * Copyright 2025 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { SharedKvStoreContextCounterpart } from "#src/kvstore/backend.js"; +import { backendOnlyKvStoreProviderRegistry } from "#src/kvstore/backend.js"; +import type { KvStoreAdapterProvider } from "#src/kvstore/context.js"; +import { KvStoreFileHandle } from "#src/kvstore/index.js"; +import { ensureNoQueryOrFragmentParameters } from "#src/kvstore/url.js"; +import { ZipKvStore } from "#src/kvstore/zip/backend.js"; + +function zipProvider( + sharedKvStoreContext: SharedKvStoreContextCounterpart, +): KvStoreAdapterProvider { + return { + scheme: "zip", + description: "ZIP archive", + getKvStore(parsedUrl, base) { + ensureNoQueryOrFragmentParameters(parsedUrl); + return { + store: new ZipKvStore( + sharedKvStoreContext.chunkManager, + new KvStoreFileHandle(base.store, base.path), + ), + path: decodeURIComponent(parsedUrl.suffix ?? ""), + }; + }, + }; +} + +backendOnlyKvStoreProviderRegistry.registerKvStoreAdapterProvider(zipProvider); diff --git a/src/kvstore/zip/register_frontend.ts b/src/kvstore/zip/register_frontend.ts new file mode 100644 index 0000000000..ff47de0d26 --- /dev/null +++ b/src/kvstore/zip/register_frontend.ts @@ -0,0 +1,46 @@ +/** + * @license + * Copyright 2025 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { KvStoreAdapterProvider } from "#src/kvstore/context.js"; +import type { SharedKvStoreContext } from "#src/kvstore/frontend.js"; +import { frontendOnlyKvStoreProviderRegistry } from "#src/kvstore/frontend.js"; +import { KvStoreFileHandle } from "#src/kvstore/index.js"; +import { ensureNoQueryOrFragmentParameters } from "#src/kvstore/url.js"; +import { registerAutoDetect } from "#src/kvstore/zip/auto_detect.js"; +import { ZipKvStore } from "#src/kvstore/zip/frontend.js"; + +function zipProvider( + sharedKvStoreContext: SharedKvStoreContext, +): KvStoreAdapterProvider { + return { + scheme: "zip", + description: "ZIP archive", + getKvStore(parsedUrl, base) { + ensureNoQueryOrFragmentParameters(parsedUrl); + return { + store: new ZipKvStore( + sharedKvStoreContext, + new KvStoreFileHandle(base.store, base.path), + ), + path: decodeURIComponent(parsedUrl.suffix ?? ""), + }; + }, + }; +} + +frontendOnlyKvStoreProviderRegistry.registerKvStoreAdapterProvider(zipProvider); + +registerAutoDetect(frontendOnlyKvStoreProviderRegistry.autoDetectRegistry); diff --git a/src/layer/annotation/index.ts b/src/layer/annotation/index.ts index 35c1a4e430..663b76e052 100644 --- a/src/layer/annotation/index.ts +++ b/src/layer/annotation/index.ts @@ -29,7 +29,7 @@ import { import type { CoordinateTransformSpecification } from "#src/coordinate_transform.js"; import { makeCoordinateSpace } from "#src/coordinate_transform.js"; import type { DataSourceSpecification } from "#src/datasource/index.js"; -import { localAnnotationsUrl, LocalDataSource } from "#src/datasource/index.js"; +import { localAnnotationsUrl, LocalDataSource } from "#src/datasource/local.js"; import type { LayerManager, ManagedUserLayer } from "#src/layer/index.js"; import { LayerReference, @@ -726,19 +726,21 @@ function makeShaderCodeWidget(layer: AnnotationUserLayer) { } class ShaderCodeOverlay extends Overlay { - codeWidget = this.registerDisposer(makeShaderCodeWidget(this.layer)); + codeWidget: ShaderCodeWidget; constructor(public layer: AnnotationUserLayer) { super(); + this.codeWidget = this.registerDisposer(makeShaderCodeWidget(this.layer)); this.content.appendChild(this.codeWidget.element); this.codeWidget.textEditor.refresh(); } } class RenderingOptionsTab extends Tab { - codeWidget = this.registerDisposer(makeShaderCodeWidget(this.layer)); + codeWidget: ShaderCodeWidget; constructor(public layer: AnnotationUserLayer) { super(); const { element } = this; + this.codeWidget = this.registerDisposer(makeShaderCodeWidget(this.layer)); element.classList.add("neuroglancer-annotation-rendering-tab"); element.appendChild( this.registerDisposer( diff --git a/src/layer/image/index.ts b/src/layer/image/index.ts index 256050060c..2d2830f6c3 100644 --- a/src/layer/image/index.ts +++ b/src/layer/image/index.ts @@ -196,7 +196,7 @@ export class ImageUserLayer extends Base { }; } - selectionState: ImageLayerSelectionState; + declare selectionState: ImageLayerSelectionState; constructor(managedLayer: Borrowed) { super(managedLayer); @@ -521,10 +521,11 @@ for (const control of LAYER_CONTROLS) { } class RenderingOptionsTab extends Tab { - codeWidget = this.registerDisposer(makeShaderCodeWidget(this.layer)); + codeWidget: ShaderCodeWidget; constructor(public layer: ImageUserLayer) { super(); const { element } = this; + this.codeWidget = this.registerDisposer(makeShaderCodeWidget(this.layer)); element.classList.add("neuroglancer-image-dropdown"); for (const control of LAYER_CONTROLS) { @@ -579,9 +580,10 @@ class RenderingOptionsTab extends Tab { } class ShaderCodeOverlay extends Overlay { - codeWidget = this.registerDisposer(makeShaderCodeWidget(this.layer)); + codeWidget: ShaderCodeWidget; constructor(public layer: ImageUserLayer) { super(); + this.codeWidget = this.registerDisposer(makeShaderCodeWidget(this.layer)); this.content.classList.add("neuroglancer-image-layer-shader-overlay"); this.content.appendChild(this.codeWidget.element); this.codeWidget.textEditor.refresh(); diff --git a/src/layer/index.ts b/src/layer/index.ts index ff3f7d8d29..fea87063da 100644 --- a/src/layer/index.ts +++ b/src/layer/index.ts @@ -32,7 +32,7 @@ import { TrackableCoordinateSpace, } from "#src/coordinate_transform.js"; import type { - DataSourceProviderRegistry, + DataSourceRegistry, DataSourceSpecification, DataSubsource, } from "#src/datasource/index.js"; @@ -80,7 +80,7 @@ import { TrackableSidePanelLocation, } from "#src/ui/side_panel_location.js"; import type { GlobalToolBinder } from "#src/ui/tool.js"; -import { LocalToolBinder, SelectedLegacyTool } from "#src/ui/tool.js"; +import { LayerToolBinder, SelectedLegacyTool } from "#src/ui/tool.js"; import { gatherUpdate } from "#src/util/array.js"; import type { Borrowed, Owned } from "#src/util/disposable.js"; import { invokeDisposers, RefCounted } from "#src/util/disposable.js"; @@ -349,9 +349,7 @@ export class UserLayer extends RefCounted { tabs = this.registerDisposer(new TabSpecification()); panels = new UserLayerSidePanelsState(this); tool = this.registerDisposer(new SelectedLegacyTool(this)); - toolBinder = this.registerDisposer( - new LocalToolBinder(this, this.manager.root.toolBinder), - ); + toolBinder: LayerToolBinder; dataSourcesChanged = new NullarySignal(); dataSources: LayerDataSource[] = []; @@ -362,6 +360,9 @@ export class UserLayer extends RefCounted { constructor(public managedLayer: Borrowed) { super(); + this.toolBinder = this.registerDisposer( + new LayerToolBinder(this, this.manager.root.toolBinder), + ); this.localCoordinateSpaceCombiner.includeDimensionPredicate = isLocalOrChannelDimension; this.tabs.changed.add(this.specificationChanged.dispatch); @@ -955,6 +956,7 @@ export class LayerManager extends RefCounted { // Also notify the root LayerManager, to ensures the layer is removed if this is the last direct // reference. managedLayer.manager.rootLayers.layersChanged.dispatch(); + managedLayer.manager.rootLayers.specificationChanged.dispatch(); managedLayer.dispose(); } @@ -1245,8 +1247,7 @@ const DATA_SELECTION_STATE_DEFAULT_PANEL_LOCATION_VISIBLE = { export class TrackableDataSelectionState extends RefCounted - implements - TrackableValueInterface + implements TrackableValueInterface { changed = new NullarySignal(); history: PersistentViewerSelectionState[] = []; @@ -2079,7 +2080,7 @@ export abstract class LayerListSpecification extends RefCounted { abstract rpc: RPC; - abstract dataSourceProviderRegistry: Borrowed; + abstract dataSourceProviderRegistry: Borrowed; abstract layerManager: Borrowed; abstract chunkManager: Borrowed; abstract layerSelectedValues: Borrowed; @@ -2103,17 +2104,13 @@ export class TopLevelLayerListSpecification extends LayerListSpecification { return this; } - coordinateSpaceCombiner = new CoordinateSpaceCombiner( - this.coordinateSpace, - isGlobalDimension, - ); + coordinateSpaceCombiner: CoordinateSpaceCombiner; subsets = new Set(); - - layerSelectedValues = this.selectionState.layerSelectedValues; + layerSelectedValues: LayerSelectedValues; constructor( public display: DisplayContext, - public dataSourceProviderRegistry: DataSourceProviderRegistry, + public dataSourceProviderRegistry: DataSourceRegistry, public layerManager: LayerManager, public chunkManager: ChunkManager, public selectionState: Borrowed, @@ -2123,6 +2120,11 @@ export class TopLevelLayerListSpecification extends LayerListSpecification { public toolBinder: Borrowed, ) { super(); + this.coordinateSpaceCombiner = new CoordinateSpaceCombiner( + coordinateSpace, + isGlobalDimension, + ); + this.layerSelectedValues = selectionState.layerSelectedValues; this.registerDisposer( layerManager.layersChanged.add(this.changed.dispatch), ); diff --git a/src/layer/layer_data_source.ts b/src/layer/layer_data_source.ts index 41cbacdd5d..f3cb7b2691 100644 --- a/src/layer/layer_data_source.ts +++ b/src/layer/layer_data_source.ts @@ -28,6 +28,7 @@ import { import type { DataSource, DataSourceSpecification, + DataSourceWithRedirectInfo, DataSubsourceEntry, DataSubsourceSpecification, } from "#src/datasource/index.js"; @@ -37,9 +38,9 @@ import { getWatchableRenderLayerTransform } from "#src/render_coordinate_transfo import type { RenderLayer } from "#src/renderlayer.js"; import type { WatchableValueInterface } from "#src/trackable_value.js"; import { arraysEqual } from "#src/util/array.js"; -import { CancellationTokenSource } from "#src/util/cancellation.js"; import type { Borrowed, Owned } from "#src/util/disposable.js"; import { disposableOnce, RefCounted } from "#src/util/disposable.js"; +import { formatErrorMessage } from "#src/util/error.js"; import { verifyBoolean, verifyObject, @@ -50,6 +51,7 @@ import { } from "#src/util/json.js"; import * as matrix from "#src/util/matrix.js"; import { MessageList, MessageSeverity } from "#src/util/message_list.js"; +import { MultiConsumerProgressListener } from "#src/util/progress_listener.js"; import { NullarySignal } from "#src/util/signal.js"; export function parseDataSubsourceSpecificationFromJson( @@ -309,6 +311,7 @@ export type LayerDataSourceLoadState = export class LayerDataSource extends RefCounted { changed = new NullarySignal(); messages = new MessageList(); + progressListener = new MultiConsumerProgressListener(); private loadState_: LayerDataSourceLoadState = undefined; private spec_: DataSourceSpecification; private specGeneration = -1; @@ -397,23 +400,18 @@ export class LayerDataSource extends RefCounted { } this.refCounted_ = refCounted; this.spec_ = spec; - const chunkManager = layer.manager.chunkManager; const registry = layer.manager.dataSourceProviderRegistry; - const cancellationToken = new CancellationTokenSource(); - this.messages.addMessage({ - severity: MessageSeverity.info, - message: "Loading data source", - }); + const abortController = new AbortController(); registry .get({ - chunkManager, url: spec.url, - cancellationToken, + signal: abortController.signal, globalCoordinateSpace: layer.manager.root.coordinateSpace, transform: spec.transform, state: spec.state, + progressListener: this.progressListener, }) - .then((source: DataSource) => { + .then((source: DataSourceWithRedirectInfo) => { if (refCounted.wasDisposed) return; this.messages.clearMessages(); const loaded = refCounted.registerDisposer( @@ -438,20 +436,29 @@ export class LayerDataSource extends RefCounted { }), ); } + const { originalCanonicalUrl } = source; + const layerType = this.layer.type; + if ( + (layerType === "auto" || layerType === "new" || spec.setManually) && + originalCanonicalUrl !== undefined && + originalCanonicalUrl !== spec.url + ) { + this.spec = { ...spec, url: originalCanonicalUrl }; + } retainer(); }) - .catch((error: Error) => { + .catch((error) => { if (this.wasDisposed) return; this.loadState_ = { error }; this.messages.clearMessages(); this.messages.addMessage({ severity: MessageSeverity.error, - message: error.message, + message: formatErrorMessage(error), }); this.changed.dispatch(); }); refCounted.registerDisposer(() => { - cancellationToken.cancel(); + abortController.abort(); }); this.changed.dispatch(); } diff --git a/src/layer/segmentation/index.ts b/src/layer/segmentation/index.ts index 8a5981d87c..8551e8c576 100644 --- a/src/layer/segmentation/index.ts +++ b/src/layer/segmentation/index.ts @@ -22,7 +22,7 @@ import type { DataSourceSpecification } from "#src/datasource/index.js"; import { LocalDataSource, localEquivalencesUrl, -} from "#src/datasource/index.js"; +} from "#src/datasource/local.js"; import type { LayerActionContext, ManagedUserLayer } from "#src/layer/index.js"; import { LinkedLayerGroup, @@ -142,7 +142,40 @@ export class SegmentationUserLayerGroupState this.hideSegmentZero.changed.add(specificationChanged.dispatch); this.segmentQuery.changed.add(specificationChanged.dispatch); - const { visibleSegments, selectedSegments } = this; + const { selectedSegments } = this; + const visibleSegments = (this.visibleSegments = this.registerDisposer( + Uint64Set.makeWithCounterpart(layer.manager.rpc), + )); + this.segmentEquivalences = this.registerDisposer( + SharedDisjointUint64Sets.makeWithCounterpart( + layer.manager.rpc, + layer.registerDisposer( + makeCachedDerivedWatchableValue( + (x) => + x?.visibleSegmentEquivalencePolicy || + VisibleSegmentEquivalencePolicy.MIN_REPRESENTATIVE, + [this.graph], + ), + ), + ), + ); + + this.temporaryVisibleSegments = layer.registerDisposer( + Uint64Set.makeWithCounterpart(layer.manager.rpc), + ); + this.temporarySegmentEquivalences = layer.registerDisposer( + SharedDisjointUint64Sets.makeWithCounterpart( + layer.manager.rpc, + this.segmentEquivalences.disjointSets.visibleSegmentEquivalencePolicy, + ), + ); + this.useTemporaryVisibleSegments = layer.registerDisposer( + SharedWatchableValue.make(layer.manager.rpc, false), + ); + this.useTemporarySegmentEquivalences = layer.registerDisposer( + SharedWatchableValue.make(layer.manager.rpc, false), + ); + visibleSegments.changed.add(specificationChanged.dispatch); selectedSegments.changed.add(specificationChanged.dispatch); selectedSegments.changed.add((x, add) => { @@ -235,48 +268,23 @@ export class SegmentationUserLayerGroupState } localGraph = new LocalSegmentationGraphSource(); - visibleSegments = this.registerDisposer( - Uint64Set.makeWithCounterpart(this.layer.manager.rpc), - ); + visibleSegments: Uint64Set; selectedSegments = this.registerDisposer(new Uint64OrderedSet()); segmentPropertyMap = new WatchableValue< PreprocessedSegmentPropertyMap | undefined >(undefined); graph = new WatchableValue(undefined); - segmentEquivalences = this.registerDisposer( - SharedDisjointUint64Sets.makeWithCounterpart( - this.layer.manager.rpc, - this.layer.registerDisposer( - makeCachedDerivedWatchableValue( - (x) => - x?.visibleSegmentEquivalencePolicy || - VisibleSegmentEquivalencePolicy.MIN_REPRESENTATIVE, - [this.graph], - ), - ), - ), - ); + segmentEquivalences: SharedDisjointUint64Sets; localSegmentEquivalences = false; maxIdLength = new WatchableValue(1); hideSegmentZero = new TrackableBoolean(true, true); segmentQuery = new TrackableValue("", verifyString); - temporaryVisibleSegments = this.layer.registerDisposer( - Uint64Set.makeWithCounterpart(this.layer.manager.rpc), - ); - temporarySegmentEquivalences = this.layer.registerDisposer( - SharedDisjointUint64Sets.makeWithCounterpart( - this.layer.manager.rpc, - this.segmentEquivalences.disjointSets.visibleSegmentEquivalencePolicy, - ), - ); - useTemporaryVisibleSegments = this.layer.registerDisposer( - SharedWatchableValue.make(this.layer.manager.rpc, false), - ); - useTemporarySegmentEquivalences = this.layer.registerDisposer( - SharedWatchableValue.make(this.layer.manager.rpc, false), - ); + temporaryVisibleSegments: Uint64Set; + temporarySegmentEquivalences: SharedDisjointUint64Sets; + useTemporaryVisibleSegments: SharedWatchableValue; + useTemporarySegmentEquivalences: SharedWatchableValue; } export class SegmentationUserLayerColorGroupState @@ -403,6 +411,41 @@ class SegmentationUserLayerDisplayState implements SegmentationDisplayState { // Even though `SegmentationUserLayer` assigns this to its `displayState` property, redundantly // assign it here first in order to allow it to be accessed by `segmentationGroupState`. layer.displayState = this; + + this.linkedSegmentationGroup = layer.registerDisposer( + new LinkedLayerGroup( + layer.manager.rootLayers, + layer, + (userLayer) => userLayer instanceof SegmentationUserLayer, + (userLayer: SegmentationUserLayer) => + userLayer.displayState.linkedSegmentationGroup, + ), + ); + + this.linkedSegmentationColorGroup = this.layer.registerDisposer( + new LinkedLayerGroup( + layer.manager.rootLayers, + layer, + (userLayer) => userLayer instanceof SegmentationUserLayer, + (userLayer: SegmentationUserLayer) => + userLayer.displayState.linkedSegmentationColorGroup, + ), + ); + + this.originalSegmentationGroupState = layer.registerDisposer( + new SegmentationUserLayerGroupState(layer), + ); + + this.originalSegmentationColorGroupState = layer.registerDisposer( + new SegmentationUserLayerColorGroupState(layer), + ); + + this.transparentPickEnabled = layer.pick; + + this.useTempSegmentStatedColors2d = layer.registerDisposer( + SharedWatchableValue.make(layer.manager.rpc, false), + ); + this.segmentationGroupState = this.layer.registerDisposer( new LinkedSegmentationGroupState( this.linkedSegmentationGroup, @@ -416,6 +459,9 @@ class SegmentationUserLayerDisplayState implements SegmentationDisplayState { ), ); + this.selectSegment = layer.selectSegment; + this.filterBySegmentLabel = layer.filterBySegmentLabel; + this.hideSegmentZero = this.layer.registerDisposer( new IndirectWatchableValue( this.segmentationGroupState, @@ -488,47 +534,22 @@ class SegmentationUserLayerDisplayState implements SegmentationDisplayState { shaderError = makeWatchableShaderError(); renderScaleHistogram = new RenderScaleHistogram(); renderScaleTarget = trackableRenderScaleTarget(1); - selectSegment = this.layer.selectSegment; - transparentPickEnabled = this.layer.pick; + selectSegment: (id: Uint64, pin: boolean | "toggle") => void; + transparentPickEnabled: TrackableBoolean; baseSegmentColoring = new TrackableBoolean(false, false); baseSegmentHighlighting = new TrackableBoolean(false, false); - useTempSegmentStatedColors2d = this.layer.registerDisposer( - SharedWatchableValue.make(this.layer.manager.rpc, false), - ); + useTempSegmentStatedColors2d: SharedWatchableValue; - filterBySegmentLabel = this.layer.filterBySegmentLabel; + filterBySegmentLabel: (id: Uint64) => void; moveToSegment = (id: Uint64) => { this.layer.moveToSegment(id); }; - linkedSegmentationGroup: LinkedLayerGroup = this.layer.registerDisposer( - new LinkedLayerGroup( - this.layer.manager.rootLayers, - this.layer, - (userLayer) => userLayer instanceof SegmentationUserLayer, - (userLayer: SegmentationUserLayer) => - userLayer.displayState.linkedSegmentationGroup, - ), - ); - - linkedSegmentationColorGroup: LinkedLayerGroup = this.layer.registerDisposer( - new LinkedLayerGroup( - this.layer.manager.rootLayers, - this.layer, - (userLayer) => userLayer instanceof SegmentationUserLayer, - (userLayer: SegmentationUserLayer) => - userLayer.displayState.linkedSegmentationColorGroup, - ), - ); - - originalSegmentationGroupState = this.layer.registerDisposer( - new SegmentationUserLayerGroupState(this.layer), - ); - - originalSegmentationColorGroupState = this.layer.registerDisposer( - new SegmentationUserLayerColorGroupState(this.layer), - ); + linkedSegmentationGroup: LinkedLayerGroup; + linkedSegmentationColorGroup: LinkedLayerGroup; + originalSegmentationGroupState: SegmentationUserLayerGroupState; + originalSegmentationColorGroupState: SegmentationUserLayerColorGroupState; segmentationGroupState: WatchableValueInterface; segmentationColorGroupState: WatchableValueInterface; diff --git a/src/layer/single_mesh/index.ts b/src/layer/single_mesh/index.ts index 6e2b686943..d0be944802 100644 --- a/src/layer/single_mesh/index.ts +++ b/src/layer/single_mesh/index.ts @@ -193,13 +193,16 @@ function makeVertexAttributeWidget(layer: SingleMeshUserLayer) { } class DisplayOptionsTab extends Tab { - attributeWidget = this.registerDisposer( - makeVertexAttributeWidget(this.layer), - ); - codeWidget = this.registerDisposer(makeShaderCodeWidget(this.layer)); + attributeWidget: VertexAttributeWidget; + codeWidget: ShaderCodeWidget; + constructor(public layer: SingleMeshUserLayer) { super(); const { element } = this; + this.attributeWidget = this.registerDisposer( + makeVertexAttributeWidget(layer), + ); + this.codeWidget = this.registerDisposer(makeShaderCodeWidget(layer)); element.classList.add("neuroglancer-single-mesh-dropdown"); const topRow = document.createElement("div"); topRow.className = "neuroglancer-single-mesh-dropdown-top-row"; @@ -239,12 +242,14 @@ class DisplayOptionsTab extends Tab { } class ShaderCodeOverlay extends Overlay { - attributeWidget = this.registerDisposer( - makeVertexAttributeWidget(this.layer), - ); - codeWidget = this.registerDisposer(makeShaderCodeWidget(this.layer)); + attributeWidget: VertexAttributeWidget; + codeWidget: ShaderCodeWidget; constructor(public layer: SingleMeshUserLayer) { super(); + this.attributeWidget = this.registerDisposer( + makeVertexAttributeWidget(layer), + ); + this.codeWidget = this.registerDisposer(makeShaderCodeWidget(layer)); this.content.classList.add("neuroglancer-single-mesh-layer-shader-overlay"); this.content.appendChild(this.attributeWidget.element); this.content.appendChild(this.codeWidget.element); diff --git a/src/layer_group_viewer.ts b/src/layer_group_viewer.ts index dfca69cc08..c7b195e903 100644 --- a/src/layer_group_viewer.ts +++ b/src/layer_group_viewer.ts @@ -60,11 +60,7 @@ import { registerNested } from "#src/trackable_value.js"; import { ContextMenu } from "#src/ui/context_menu.js"; import { popDragStatus, pushDragStatus } from "#src/ui/drag_and_drop.js"; import { LayerBar } from "#src/ui/layer_bar.js"; -import { - endLayerDrag, - getDropEffectFromModifiers, - startLayerDrag, -} from "#src/ui/layer_drag_and_drop.js"; +import { endLayerDrag, startLayerDrag } from "#src/ui/layer_drag_and_drop.js"; import { setupPositionDropHandlers } from "#src/ui/position_drag_and_drop.js"; import { LocalToolBinder } from "#src/ui/tool.js"; import { AutomaticallyFocusedElement } from "#src/util/automatic_focus.js"; @@ -72,6 +68,7 @@ import type { TrackableRGB } from "#src/util/color.js"; import type { Borrowed, Owned } from "#src/util/disposable.js"; import { RefCounted } from "#src/util/disposable.js"; import { removeChildren } from "#src/util/dom.js"; +import { getDropEffectFromModifiers } from "#src/util/drag_and_drop.js"; import { dispatchEventAction, registerActionListener, @@ -581,6 +578,7 @@ export class LayerGroupViewer extends RefCounted { const layerPanelElement = layerPanel.element; layerPanelElement.addEventListener("dragstart", (event: DragEvent) => { pushDragStatus( + event, layerPanel.element, "drag", "Drag layer group to the left/top/right/bottom edge of a layer group, or to another layer bar/panel (including in another Neuroglancer window)", @@ -606,8 +604,8 @@ export class LayerGroupViewer extends RefCounted { layerPanel.element.style.backgroundColor = ""; }, 0); }); - layerPanel.element.addEventListener("dragend", () => { - popDragStatus(layerPanelElement, "drag"); + layerPanel.element.addEventListener("dragend", (event: DragEvent) => { + popDragStatus(event, layerPanelElement, "drag"); endLayerDrag(); if (dragSource !== undefined && dragSource.viewer === this) { dragSource.disposer(); diff --git a/src/layer_groups_layout.ts b/src/layer_groups_layout.ts index 851b3ff275..bfcd190e89 100644 --- a/src/layer_groups_layout.ts +++ b/src/layer_groups_layout.ts @@ -475,8 +475,8 @@ function setupDropZone( } dropZone.classList.add("neuroglancer-drag-over"); }); - dropZone.addEventListener("dragleave", () => { - popDragStatus(dropZone, "drop"); + dropZone.addEventListener("dragleave", (event) => { + popDragStatus(event, dropZone, "drop"); dropZone.classList.remove("neuroglancer-drag-over"); }); dropZone.addEventListener("dragover", (event: DragEvent) => { @@ -485,7 +485,7 @@ function setupDropZone( message: string, ) => { if (info.dropEffectMessage) message += ` (${info.dropEffectMessage})`; - pushDragStatus(dropZone, "drop", message); + pushDragStatus(event, dropZone, "drop", message); event.stopPropagation(); event.preventDefault(); }; @@ -511,14 +511,14 @@ function setupDropZone( }); dropZone.addEventListener("drop", (event: DragEvent) => { dropZone.classList.remove("neuroglancer-drag-over"); - popDragStatus(dropZone, "drop"); + popDragStatus(event, dropZone, "drop"); let dropLayers: DropLayers | undefined; let layoutSpec: any; if (hasViewerDrag(event)) { event.stopPropagation(); try { layoutSpec = JSON.parse(event.dataTransfer!.getData(viewerDragType)); - } catch (e) { + } catch { return; } dropLayers = getDropLayers(event, manager, { @@ -606,6 +606,7 @@ export class StackLayoutComponent event.preventDefault(); const updateMessage = () => { pushDragStatus( + event, dropZone, "drag", `Drag to resize, current ${ @@ -640,8 +641,8 @@ export class StackLayoutComponent Math.round((1 - firstFraction) * existingFlexSum * 100) / 100; updateMessage(); }, - () => { - popDragStatus(dropZone, "drag"); + (event) => { + popDragStatus(event, dropZone, "drag"); }, ); }); @@ -781,13 +782,7 @@ function makeComponent(container: LayoutComponentContainer, spec: any) { } export class RootLayoutContainer extends RefCounted implements Trackable { - container = this.registerDisposer( - new LayoutComponentContainer( - this.viewer, - this.defaultSpecification, - undefined, - ), - ); + container: LayoutComponentContainer; get changed() { return this.container.changed; @@ -802,6 +797,9 @@ export class RootLayoutContainer extends RefCounted implements Trackable { public defaultSpecification: any, ) { super(); + this.container = this.registerDisposer( + new LayoutComponentContainer(viewer, defaultSpecification, undefined), + ); } reset() { diff --git a/src/main.bundle.js b/src/main.bundle.js index 617f992b08..2cc375487b 100644 --- a/src/main.bundle.js +++ b/src/main.bundle.js @@ -1,3 +1,5 @@ +import "#src/util/polyfills.js"; import "#src/layer/enabled_frontend_modules.js"; import "#src/datasource/enabled_frontend_modules.js"; +import "#src/kvstore/enabled_frontend_modules.js"; import "#main"; diff --git a/src/main_module.ts b/src/main_module.ts index b232673900..79af4f9d24 100644 --- a/src/main_module.ts +++ b/src/main_module.ts @@ -1,2 +1,4 @@ +import "#src/util/polyfills.js"; import "#src/layer/enabled_frontend_modules.js"; import "#src/datasource/enabled_frontend_modules.js"; +import "#src/kvstore/enabled_frontend_modules.js"; diff --git a/src/main_python.ts b/src/main_python.ts index 64bf3075a7..8357627dd5 100644 --- a/src/main_python.ts +++ b/src/main_python.ts @@ -21,8 +21,7 @@ import { debounce } from "lodash-es"; import { CachingCredentialsManager } from "#src/credentials_provider/index.js"; -import { getDefaultDataSourceProvider } from "#src/datasource/default_provider.js"; -import { PythonDataSource } from "#src/datasource/python/frontend.js"; +import type { PythonDataSource } from "#src/datasource/python/frontend.js"; import { Client, ClientStateReceiver, @@ -114,21 +113,19 @@ const client = new Client(); const credentialsManager = new PythonCredentialsManager(client); -const dataSourceProvider = getDefaultDataSourceProvider({ +const viewer = ((window).viewer = makeDefaultViewer({ + showLayerDialog: false, + resetStateWhenEmpty: false, credentialsManager: new CachingCredentialsManager(credentialsManager), -}); -const pythonDataSource = new PythonDataSource(); -dataSourceProvider.register("python", pythonDataSource); +})); + +const pythonDataSource = viewer.dataSourceProvider.dataSources.get( + "python", +) as PythonDataSource; configState.add( "sourceGenerations", makeTrackableBasedSourceGenerationHandler(pythonDataSource), ); - -const viewer = ((window).viewer = makeDefaultViewer({ - showLayerDialog: false, - resetStateWhenEmpty: false, - dataSourceProvider, -})); setDefaultInputEventBindings(viewer.inputEventBindings); configState.add( "inputEventBindings", @@ -151,7 +148,10 @@ let sharedState: Trackable | undefined = viewer.state; if (window.location.hash) { const hashBinding = viewer.registerDisposer( - new UrlHashBinding(viewer.state, credentialsManager), + new UrlHashBinding( + viewer.state, + viewer.dataSourceProvider.sharedKvStoreContext, + ), ); hashBinding.updateFromUrlHash(); sharedState = undefined; @@ -159,7 +159,7 @@ if (window.location.hash) { const prefetchManager = new PrefetchManager( viewer.display, - dataSourceProvider, + viewer.dataSourceProvider, viewer.dataContext.addRef(), viewer.uiConfiguration, ); diff --git a/src/mesh/backend.ts b/src/mesh/backend.ts index ca5f313915..fe8191a1b5 100644 --- a/src/mesh/backend.ts +++ b/src/mesh/backend.ts @@ -45,7 +45,6 @@ import { getObjectKey, forEachVisibleSegment, } from "#src/segmentation_display_state/base.js"; -import type { CancellationToken } from "#src/util/cancellation.js"; import type { Endianness } from "#src/util/endian.js"; import { convertEndian32 } from "#src/util/endian.js"; import { getFrustrumPlanes, mat4, vec3 } from "#src/util/geom.js"; @@ -370,10 +369,7 @@ export function decodeTriangleVertexPositionsAndIndices( export interface MeshSource { // TODO(jbms): Move this declaration to class definition below and declare abstract once // TypeScript supports mixins with abstract classes. - downloadFragment( - chunk: FragmentChunk, - cancellationToken: CancellationToken, - ): Promise; + downloadFragment(chunk: FragmentChunk, signal: AbortSignal): Promise; } // eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging @@ -424,8 +420,8 @@ export class MeshSource extends ChunkSource { @registerSharedObject(FRAGMENT_SOURCE_RPC_ID) export class FragmentSource extends ChunkSource { meshSource: MeshSource | null = null; - download(chunk: FragmentChunk, cancellationToken: CancellationToken) { - return this.meshSource!.downloadFragment(chunk, cancellationToken); + download(chunk: FragmentChunk, signal: AbortSignal) { + return this.meshSource!.downloadFragment(chunk, signal); } } @@ -570,7 +566,7 @@ export interface MultiscaleMeshSource { // TypeScript supports mixins with abstract classes. downloadFragment( chunk: MultiscaleFragmentChunk, - cancellationToken: CancellationToken, + signal: AbortSignal, ): Promise; } @@ -622,11 +618,8 @@ export class MultiscaleMeshSource extends ChunkSource { @registerSharedObject(MULTISCALE_FRAGMENT_SOURCE_RPC_ID) export class MultiscaleFragmentSource extends ChunkSource { meshSource: MultiscaleMeshSource | null = null; - download( - chunk: MultiscaleFragmentChunk, - cancellationToken: CancellationToken, - ) { - return this.meshSource!.downloadFragment(chunk, cancellationToken); + download(chunk: MultiscaleFragmentChunk, signal: AbortSignal) { + return this.meshSource!.downloadFragment(chunk, signal); } } diff --git a/src/mesh/frontend.ts b/src/mesh/frontend.ts index 042ae4553e..bccb3c9ec6 100644 --- a/src/mesh/frontend.ts +++ b/src/mesh/frontend.ts @@ -67,7 +67,7 @@ import { } from "#src/util/geom.js"; import * as matrix from "#src/util/matrix.js"; import type { Uint64 } from "#src/util/uint64.js"; -import { Buffer } from "#src/webgl/buffer.js"; +import { GLBuffer } from "#src/webgl/buffer.js"; import type { GL } from "#src/webgl/context.js"; import { parameterizedEmitterDependentShaderGetter } from "#src/webgl/dynamic_shader.js"; import type { ShaderBuilder, ShaderProgram } from "#src/webgl/shader.js"; @@ -86,19 +86,19 @@ function copyMeshDataToGpu( gl: GL, chunk: FragmentChunk | MultiscaleFragmentChunk, ) { - chunk.vertexBuffer = Buffer.fromData( + chunk.vertexBuffer = GLBuffer.fromData( gl, chunk.meshData.vertexPositions, gl.ARRAY_BUFFER, gl.STATIC_DRAW, ); - chunk.indexBuffer = Buffer.fromData( + chunk.indexBuffer = GLBuffer.fromData( gl, chunk.meshData.indices, gl.ELEMENT_ARRAY_BUFFER, gl.STATIC_DRAW, ); - chunk.normalBuffer = Buffer.fromData( + chunk.normalBuffer = GLBuffer.fromData( gl, chunk.meshData.vertexNormals, gl.ARRAY_BUFFER, @@ -240,12 +240,13 @@ highp vec3 getVertexPosition() { export class MeshShaderManager { private tempLightVec = new Float32Array(4); - private vertexPositionHandler = - vertexPositionHandlers[this.vertexPositionFormat]; + private vertexPositionHandler: VertexPositionFormatHandler; constructor( public fragmentRelativeVertices: boolean, public vertexPositionFormat: VertexPositionFormat, - ) {} + ) { + this.vertexPositionHandler = vertexPositionHandlers[vertexPositionFormat]; + } beginLayer( gl: GL, @@ -412,11 +413,8 @@ export interface MeshDisplayState extends SegmentationDisplayState3D { } export class MeshLayer extends PerspectiveViewRenderLayer { - protected meshShaderManager = new MeshShaderManager( - /*fragmentRelativeVertices=*/ false, - VertexPositionFormat.float32, - ); - private getShader = this.meshShaderManager.makeGetter(this); + protected meshShaderManager; + private getShader; backend: SegmentationLayerSharedObject; constructor( @@ -425,6 +423,11 @@ export class MeshLayer extends PerspectiveViewRenderLayer; + declare chunks: Map; initializeCounterpart(rpc: RPC, options: any) { this.fragmentSource.initializeCounterpart(this.chunkManager.rpc!, {}); @@ -721,7 +724,7 @@ export class MeshSource extends ChunkSource { @registerSharedObjectOwner(FRAGMENT_SOURCE_RPC_ID) export class FragmentSource extends ChunkSource { - chunks: Map; + declare chunks: Map; get key() { return this.meshSource.key; } @@ -751,11 +754,8 @@ function hasFragmentChunk( } export class MultiscaleMeshLayer extends PerspectiveViewRenderLayer { - protected meshShaderManager = new MeshShaderManager( - /*fragmentRelativeVertices=*/ this.source.format.fragmentRelativeVertices, - this.source.format.vertexPositionFormat, - ); - private getShader = this.meshShaderManager.makeGetter(this); + protected meshShaderManager: MeshShaderManager; + private getShader; backend: SegmentationLayerSharedObject; constructor( @@ -764,6 +764,11 @@ export class MultiscaleMeshLayer extends PerspectiveViewRenderLayer; + declare chunks: Map; format: MultiscaleFragmentFormat; constructor( chunkManager: Borrowed, @@ -1150,7 +1155,7 @@ export class MultiscaleMeshSource extends ChunkSource { @registerSharedObjectOwner(MULTISCALE_FRAGMENT_SOURCE_RPC_ID) export class MultiscaleFragmentSource extends ChunkSource { - chunks: Map; + declare chunks: Map; get key() { return this.meshSource.key; } diff --git a/src/navigation_state.ts b/src/navigation_state.ts index 2f12c550fc..f9adcfd613 100644 --- a/src/navigation_state.ts +++ b/src/navigation_state.ts @@ -491,11 +491,12 @@ export class CoordinateSpacePlaybackVelocity extends RefCounted { velocities[index] = newVelocity; this.changed.dispatch(); }; - const prevVelocity = getVelocity(); + let prevVelocity = getVelocity(); owner.registerDisposer( this.changed.add(() => { const curVelocity = getVelocity(); if (curVelocity !== prevVelocity) { + prevVelocity = curVelocity; changed.dispatch(); } }), @@ -674,15 +675,17 @@ export class CoordinateSpacePlaybackVelocity extends RefCounted { export class LinkedCoordinateSpacePlaybackVelocity extends RefCounted { changed = new NullarySignal(); - velocity = this.registerDisposer( - new CoordinateSpacePlaybackVelocity(this.peer.coordinateSpace), - ); + velocity: CoordinateSpacePlaybackVelocity; constructor( public peer: Owned, public positionLink: TrackableLinkInterface, ) { super(); + this.velocity = this.registerDisposer( + new CoordinateSpacePlaybackVelocity(peer.coordinateSpace), + ); + this.registerDisposer(peer); this.velocity.changed.add(() => { if (this.positionLink.value === NavigationLinkType.UNLINKED) { @@ -1008,7 +1011,7 @@ export class OrientationState extends RefCounted { try { parseFiniteVec(this.orientation, obj); quat.normalize(this.orientation, this.orientation); - } catch (ignoredError) { + } catch { quat.identity(this.orientation); } this.changed.dispatch(); @@ -1447,17 +1450,10 @@ export function validateDisplayDimensionRenderInfoProperty( export class WatchableDisplayDimensionRenderInfo extends RefCounted { changed = new NullarySignal(); - private curRelativeDisplayScales: RelativeDisplayScales = - this.relativeDisplayScales.value; - private curDisplayDimensions: DisplayDimensions = - this.displayDimensions.value; - private curCoordinateSpace: CoordinateSpace = - this.relativeDisplayScales.coordinateSpace.value; - private value_: DisplayDimensionRenderInfo = getDisplayDimensionRenderInfo( - this.curCoordinateSpace, - this.curDisplayDimensions, - this.curRelativeDisplayScales, - ); + private curRelativeDisplayScales: RelativeDisplayScales; + private curDisplayDimensions: DisplayDimensions; + private curCoordinateSpace: CoordinateSpace; + private value_: DisplayDimensionRenderInfo; get value() { const { relativeDisplayScales: { @@ -1495,6 +1491,15 @@ export class WatchableDisplayDimensionRenderInfo extends RefCounted { public displayDimensions: Owned, ) { super(); + this.curRelativeDisplayScales = this.relativeDisplayScales.value; + this.curDisplayDimensions = this.displayDimensions.value; + this.curCoordinateSpace = this.relativeDisplayScales.coordinateSpace.value; + this.value_ = getDisplayDimensionRenderInfo( + this.curCoordinateSpace, + this.curDisplayDimensions, + this.curRelativeDisplayScales, + ); + this.registerDisposer(relativeDisplayScales); this.registerDisposer(displayDimensions); const maybeUpdateValue = () => { diff --git a/src/perspective_view/panel.ts b/src/perspective_view/panel.ts index 2f0bceb0fc..646519d907 100644 --- a/src/perspective_view/panel.ts +++ b/src/perspective_view/panel.ts @@ -269,7 +269,7 @@ class PerspectiveViewState extends PerspectiveViewStateBase { } export class PerspectivePanel extends RenderedDataPanel { - viewer: PerspectiveViewerState; + declare viewer: PerspectiveViewerState; projectionParameters: Owned; diff --git a/src/python_integration/prefetch.ts b/src/python_integration/prefetch.ts index c75d7caf12..28f9ae0370 100644 --- a/src/python_integration/prefetch.ts +++ b/src/python_integration/prefetch.ts @@ -20,7 +20,8 @@ */ import { debounce } from "lodash-es"; -import type { DataSourceProviderRegistry } from "#src/datasource/index.js"; +import type { DataManagementContext } from "#src/data_management_context.js"; +import type { DataSourceRegistry } from "#src/datasource/index.js"; import type { DisplayContext } from "#src/display_context.js"; import type { Borrowed, Owned } from "#src/util/disposable.js"; import { RefCounted } from "#src/util/disposable.js"; @@ -31,10 +32,7 @@ import { verifyObjectProperty, } from "#src/util/json.js"; import { NullarySignal } from "#src/util/signal.js"; -import type { - DataManagementContext, - ViewerUIConfiguration, -} from "#src/viewer.js"; +import type { ViewerUIConfiguration } from "#src/viewer.js"; import { Viewer } from "#src/viewer.js"; import { WatchableVisibilityPriority } from "#src/visibility_priority/frontend.js"; @@ -46,7 +44,7 @@ export class PrefetchManager extends RefCounted { constructor( public display: Borrowed, - public dataSourceProvider: DataSourceProviderRegistry, + public dataSourceProvider: DataSourceRegistry, public dataContext: Owned, public uiConfiguration: ViewerUIConfiguration, ) { diff --git a/src/python_integration/volume.ts b/src/python_integration/volume.ts index 8820099eda..39d1d5a93a 100644 --- a/src/python_integration/volume.ts +++ b/src/python_integration/volume.ts @@ -33,8 +33,6 @@ import type { VolumeChunkSource } from "#src/sliceview/volume/frontend.js"; import { SliceViewVolumeRenderLayer } from "#src/sliceview/volume/renderlayer.js"; import { TrackableValue } from "#src/trackable_value.js"; import { arraysEqual } from "#src/util/array.js"; -import type { CancellationToken } from "#src/util/cancellation.js"; -import { CancellationTokenSource } from "#src/util/cancellation.js"; import { DataType } from "#src/util/data_type.js"; import { RefCounted } from "#src/util/disposable.js"; import { valueOrThrow } from "#src/util/error.js"; @@ -374,7 +372,7 @@ export class VolumeRequestHandler extends RefCounted { (requestId: string, response: unknown) => void >(); - private alreadyHandledRequests = new Map(); + private alreadyHandledRequests = new Map(); private debouncedMaybeHandleRequests = this.registerCancellable( debounce(() => this.maybeHandleRequests(), 0), ); @@ -397,9 +395,9 @@ export class VolumeRequestHandler extends RefCounted { const { id } = request; seenRequests.add(id); if (alreadyHandledRequests.has(id)) continue; - const source = new CancellationTokenSource(); + const abortController = new AbortController(); try { - if (!this.maybeHandleRequest(request, source)) { + if (!this.maybeHandleRequest(request, abortController.signal)) { continue; } } catch (e) { @@ -409,12 +407,12 @@ export class VolumeRequestHandler extends RefCounted { }); } } - alreadyHandledRequests.set(id, source); + alreadyHandledRequests.set(id, abortController); } - for (const [requestId, cancellationSource] of alreadyHandledRequests) { + for (const [requestId, abortController] of alreadyHandledRequests) { if (!seenRequests.has(requestId)) { - cancellationSource.cancel(); + abortController.abort(); alreadyHandledRequests.delete(requestId); } } @@ -422,7 +420,7 @@ export class VolumeRequestHandler extends RefCounted { private maybeHandleRequest( request: VolumeRequest, - cancellationToken: CancellationToken, + signal: AbortSignal, ): boolean { const layer = this.viewer.layerManager.getLayerByName(request.layer); if (layer === undefined) { @@ -588,7 +586,7 @@ export class VolumeRequestHandler extends RefCounted { order: info.order, }; }, - cancellationToken, + { signal }, ); } catch (e) { response = { error: e.message }; diff --git a/src/render_coordinate_transform.ts b/src/render_coordinate_transform.ts index 36e31a7829..1987061306 100644 --- a/src/render_coordinate_transform.ts +++ b/src/render_coordinate_transform.ts @@ -287,7 +287,7 @@ export function getRenderLayerTransform( subspaceRank + 1, subspaceRank + 1, subspaceRank + 1, - ); + ) as Float32Array; } const channelSpaceShape = new Uint32Array(channelRank); const { diff --git a/src/renderlayer.ts b/src/renderlayer.ts index c874fac970..2fbea24894 100644 --- a/src/renderlayer.ts +++ b/src/renderlayer.ts @@ -257,6 +257,28 @@ export class SharedProjectionParameters< public updateInterval = 10, ) { super(); + this.update = this.registerCancellable( + debounce((_oldValue: T, newValue: T) => { + // Note: Because we are using debouce, we cannot rely on `_oldValue`, since + // `DerivedProjectionParameters` reuses the objects. + let valueUpdate: any; + if ( + newValue.displayDimensionRenderInfo !== + this.prevDisplayDimensionRenderInfo + ) { + valueUpdate = newValue; + this.prevDisplayDimensionRenderInfo = + newValue.displayDimensionRenderInfo; + } else { + const { displayDimensionRenderInfo, ...remainder } = newValue; + valueUpdate = remainder; + } + this.rpc!.invoke(PROJECTION_PARAMETERS_CHANGED_RPC_METHOD_ID, { + id: this.rpcId, + value: valueUpdate, + }); + }, this.updateInterval), + ); this.initializeCounterpart(rpc, { value: base.value }); this.registerDisposer(base.changed.add(this.update)); } @@ -265,26 +287,5 @@ export class SharedProjectionParameters< this.update.flush(); } - private update = this.registerCancellable( - debounce((_oldValue: T, newValue: T) => { - // Note: Because we are using debouce, we cannot rely on `_oldValue`, since - // `DerivedProjectionParameters` reuses the objects. - let valueUpdate: any; - if ( - newValue.displayDimensionRenderInfo !== - this.prevDisplayDimensionRenderInfo - ) { - valueUpdate = newValue; - this.prevDisplayDimensionRenderInfo = - newValue.displayDimensionRenderInfo; - } else { - const { displayDimensionRenderInfo, ...remainder } = newValue; - valueUpdate = remainder; - } - this.rpc!.invoke(PROJECTION_PARAMETERS_CHANGED_RPC_METHOD_ID, { - id: this.rpcId, - value: valueUpdate, - }); - }, this.updateInterval), - ); + private update; } diff --git a/src/segment_color.ts b/src/segment_color.ts index d7d5db0ba5..db966a9f4a 100644 --- a/src/segment_color.ts +++ b/src/segment_color.ts @@ -33,9 +33,11 @@ import { glsl_hsvToRgb, glsl_uint64 } from "#src/webgl/shader_lib.js"; const NUM_COMPONENTS = 2; export class SegmentColorShaderManager { - seedName = this.prefix + "_seed"; + seedName: string; - constructor(public prefix: string) {} + constructor(public prefix: string) { + this.seedName = prefix + "_seed"; + } defineShader(builder: ShaderBuilder) { const { seedName } = this; diff --git a/src/segmentation_display_state/property_map.spec.ts b/src/segmentation_display_state/property_map.spec.ts index fbce7ba0c7..51305ac3da 100644 --- a/src/segmentation_display_state/property_map.spec.ts +++ b/src/segmentation_display_state/property_map.spec.ts @@ -14,16 +14,18 @@ * limitations under the License. */ -import { describe, it, expect } from "vitest"; +import { describe, test, expect } from "vitest"; import { mergeSegmentPropertyMaps, + parseSegmentQuery, PreprocessedSegmentPropertyMap, SegmentPropertyMap, } from "#src/segmentation_display_state/property_map.js"; +import { DataType } from "#src/util/data_type.js"; import { Uint64 } from "#src/util/uint64.js"; describe("PreprocessedSegmentPropertyMap", () => { - it("handles lookups correctly", () => { + test("handles lookups correctly", () => { const map = new PreprocessedSegmentPropertyMap({ inlineProperties: { ids: Uint32Array.of(5, 0, 15, 0, 20, 5), @@ -39,7 +41,7 @@ describe("PreprocessedSegmentPropertyMap", () => { }); describe("mergeSegmentPropertyMaps", () => { - it("works correctly for 2 maps", () => { + test("works correctly for 2 maps", () => { const a = new SegmentPropertyMap({ inlineProperties: { ids: Uint32Array.of(5, 0, 6, 0, 8, 0), @@ -65,3 +67,351 @@ describe("mergeSegmentPropertyMaps", () => { }); }); }); + +describe("parseSegmentQuery", () => { + const map = new PreprocessedSegmentPropertyMap({ + inlineProperties: { + ids: Uint32Array.of(), + properties: [ + { type: "label", id: "label", values: [] }, + { + type: "number", + dataType: DataType.INT32, + description: undefined, + id: "prop1", + values: Int32Array.of(), + bounds: [-10, 100], + }, + { + id: "tags", + type: "tags", + tags: ["abc", "def"], + tagDescriptions: ["foo", "bar"], + values: [], + }, + ], + }, + }); + + test("handles empty query", () => { + expect(parseSegmentQuery(undefined, "")).toMatchInlineSnapshot(` + { + "excludeTags": [], + "includeColumns": [], + "includeTags": [], + "numericalConstraints": [], + "prefix": undefined, + "regexp": undefined, + "sortBy": [ + { + "fieldId": "id", + "order": "<", + }, + ], + } + `); + }); + + test("handles single number", () => { + expect(parseSegmentQuery(undefined, "123")).toMatchInlineSnapshot(` + { + "ids": [ + "123", + ], + } + `); + }); + + test("handles multiple numbers", () => { + expect(parseSegmentQuery(undefined, "123 456")).toMatchInlineSnapshot(` + { + "ids": [ + "123", + "456", + ], + } + `); + }); + + test("handles regular expression", () => { + expect(parseSegmentQuery(map, "/xyz")).toMatchInlineSnapshot(` + { + "excludeTags": [], + "includeColumns": [], + "includeTags": [], + "numericalConstraints": [], + "prefix": undefined, + "regexp": /xyz/, + "sortBy": [ + { + "fieldId": "label", + "order": "<", + }, + ], + } + `); + }); + + test("handles prefix", () => { + expect(parseSegmentQuery(map, "xyz")).toMatchInlineSnapshot(` + { + "excludeTags": [], + "includeColumns": [], + "includeTags": [], + "numericalConstraints": [], + "prefix": "xyz", + "regexp": undefined, + "sortBy": [ + { + "fieldId": "label", + "order": "<", + }, + ], + } + `); + }); + + test("handles prefix", () => { + expect(parseSegmentQuery(map, "xyz")).toMatchInlineSnapshot(` + { + "excludeTags": [], + "includeColumns": [], + "includeTags": [], + "numericalConstraints": [], + "prefix": "xyz", + "regexp": undefined, + "sortBy": [ + { + "fieldId": "label", + "order": "<", + }, + ], + } + `); + }); + + test("handles numeric > comparison", () => { + expect(parseSegmentQuery(map, "prop1>5")).toMatchInlineSnapshot(` + { + "excludeTags": [], + "includeColumns": [], + "includeTags": [], + "numericalConstraints": [ + { + "bounds": [ + 6, + 100, + ], + "fieldId": "prop1", + }, + ], + "prefix": undefined, + "regexp": undefined, + "sortBy": [ + { + "fieldId": "label", + "order": "<", + }, + ], + } + `); + }); + + test("handles numeric >= comparison", () => { + expect(parseSegmentQuery(map, "prop1>=5")).toMatchInlineSnapshot(` + { + "excludeTags": [], + "includeColumns": [], + "includeTags": [], + "numericalConstraints": [ + { + "bounds": [ + 5, + 100, + ], + "fieldId": "prop1", + }, + ], + "prefix": undefined, + "regexp": undefined, + "sortBy": [ + { + "fieldId": "label", + "order": "<", + }, + ], + } + `); + }); + + test("handles numeric = comparison", () => { + expect(parseSegmentQuery(map, "prop1=5")).toMatchInlineSnapshot(` + { + "excludeTags": [], + "includeColumns": [], + "includeTags": [], + "numericalConstraints": [ + { + "bounds": [ + 5, + 5, + ], + "fieldId": "prop1", + }, + ], + "prefix": undefined, + "regexp": undefined, + "sortBy": [ + { + "fieldId": "label", + "order": "<", + }, + ], + } + `); + }); + + test("handles numeric >= comparison", () => { + expect(parseSegmentQuery(map, "prop1>=5")).toMatchInlineSnapshot(` + { + "excludeTags": [], + "includeColumns": [], + "includeTags": [], + "numericalConstraints": [ + { + "bounds": [ + 5, + 100, + ], + "fieldId": "prop1", + }, + ], + "prefix": undefined, + "regexp": undefined, + "sortBy": [ + { + "fieldId": "label", + "order": "<", + }, + ], + } + `); + }); + + test("handles numeric > comparison", () => { + expect(parseSegmentQuery(map, "prop1>5")).toMatchInlineSnapshot(` + { + "excludeTags": [], + "includeColumns": [], + "includeTags": [], + "numericalConstraints": [ + { + "bounds": [ + 6, + 100, + ], + "fieldId": "prop1", + }, + ], + "prefix": undefined, + "regexp": undefined, + "sortBy": [ + { + "fieldId": "label", + "order": "<", + }, + ], + } + `); + }); + + test("handles numeric > comparison negative", () => { + expect(parseSegmentQuery(map, "prop1>-5")).toMatchInlineSnapshot(` + { + "excludeTags": [], + "includeColumns": [], + "includeTags": [], + "numericalConstraints": [ + { + "bounds": [ + -4, + 100, + ], + "fieldId": "prop1", + }, + ], + "prefix": undefined, + "regexp": undefined, + "sortBy": [ + { + "fieldId": "label", + "order": "<", + }, + ], + } + `); + }); + + test("handles sort field", () => { + expect(parseSegmentQuery(map, ">prop1")).toMatchInlineSnapshot(` + { + "excludeTags": [], + "includeColumns": [], + "includeTags": [], + "numericalConstraints": [], + "prefix": undefined, + "regexp": undefined, + "sortBy": [ + { + "fieldId": "prop1", + "order": ">", + }, + ], + } + `); + }); + + test("handles column inclusions", () => { + expect(parseSegmentQuery(map, "|prop1")).toMatchInlineSnapshot(` + { + "excludeTags": [], + "includeColumns": [ + "prop1", + ], + "includeTags": [], + "numericalConstraints": [], + "prefix": undefined, + "regexp": undefined, + "sortBy": [ + { + "fieldId": "label", + "order": "<", + }, + ], + } + `); + }); + + test("handles tags", () => { + expect(parseSegmentQuery(map, "#abc -#def")).toMatchInlineSnapshot(` + { + "excludeTags": [ + "def", + ], + "includeColumns": [], + "includeTags": [ + "abc", + ], + "numericalConstraints": [], + "prefix": undefined, + "regexp": undefined, + "sortBy": [ + { + "fieldId": "label", + "order": "<", + }, + ], + } + `); + }); +}); diff --git a/src/segmentation_display_state/property_map.ts b/src/segmentation_display_state/property_map.ts index aa1c798530..e4e5d90f39 100644 --- a/src/segmentation_display_state/property_map.ts +++ b/src/segmentation_display_state/property_map.ts @@ -19,11 +19,7 @@ import { ChunkSource } from "#src/chunk_manager/frontend.js"; import type { IndexedSegmentProperty } from "#src/segmentation_display_state/base.js"; import type { Uint64OrderedSet } from "#src/uint64_ordered_set.js"; import type { Uint64Set } from "#src/uint64_set.js"; -import type { - TypedArray, - TypedArrayConstructor, - WritableArrayLike, -} from "#src/util/array.js"; +import type { TypedArray, WritableArrayLike } from "#src/util/array.js"; import { mergeSequences } from "#src/util/array.js"; import { DataType } from "#src/util/data_type.js"; import type { Borrowed } from "#src/util/disposable.js"; @@ -68,13 +64,13 @@ export interface InlineSegmentNumericalProperty { type: "number"; dataType: DataType; description: string | undefined; - values: TypedArray; + values: TypedArray; bounds: DataTypeInterval; } export interface InlineSegmentPropertyMap { // Specifies low/high 32-bit portions of ids. - ids: Uint32Array; + ids: Uint32Array; properties: InlineSegmentProperty[]; } @@ -83,7 +79,7 @@ export interface IndexedSegmentPropertyMapOptions { } export class IndexedSegmentPropertySource extends ChunkSource { - OPTIONS: IndexedSegmentPropertyMapOptions; + declare OPTIONS: IndexedSegmentPropertyMapOptions; properties: readonly Readonly[]; constructor( @@ -289,9 +285,7 @@ export function normalizeInlineSegmentPropertyMap( } const properties = inlineProperties.properties.map((property) => { const { values } = property; - const newValues = new (values.constructor as - | TypedArrayConstructor - | typeof Array)(length); + const newValues = new (values.constructor as typeof Array)(length); for (let i = 0; i < length; ++i) { newValues[i] = values[permutation[i]]; } @@ -385,7 +379,7 @@ function mergeInlinePropertyMaps( ++numUnique; }, ); - let ids: Uint32Array; + let ids: Uint32Array; if (numUnique === aCount) { ids = aIds; } else if (numUnique === bCount) { @@ -687,7 +681,7 @@ export function parseSegmentQuery( } try { parsed.regexp = new RegExp(word.substring(1)); - } catch (e) { + } catch { errors.push({ begin: startIndex, end: endIndex, @@ -697,7 +691,7 @@ export function parseSegmentQuery( continue; } const constraintMatch = word.match( - /^([a-zA-Z][a-zA-Z0-9_]*)(<|<=|=|>=|>)([0-9.].*)$/, + /^([a-zA-Z][a-zA-Z0-9_]*)(<|<=|=|>=|>)(-?[0-9.].*)$/, ); if (constraintMatch !== null) { let fieldId = constraintMatch[1].toLowerCase(); diff --git a/src/shared_disjoint_sets.ts b/src/shared_disjoint_sets.ts index 2f1d9b20dc..0f6b24a0f0 100644 --- a/src/shared_disjoint_sets.ts +++ b/src/shared_disjoint_sets.ts @@ -67,12 +67,6 @@ export class SharedDisjointUint64Sets return obj; } - disposed() { - this.disjointSets = undefined; - this.changed = undefined; - super.disposed(); - } - link(a: Uint64, b: Uint64) { if (this.disjointSets.link(a, b)) { const { rpc } = this; diff --git a/src/single_mesh/backend.ts b/src/single_mesh/backend.ts index 0ad2650529..3357260995 100644 --- a/src/single_mesh/backend.ts +++ b/src/single_mesh/backend.ts @@ -14,17 +14,14 @@ * limitations under the License. */ -import type { ChunkManager } from "#src/chunk_manager/backend.js"; import { Chunk, ChunkSource, withChunkManager, WithParameters, } from "#src/chunk_manager/backend.js"; -import { ChunkPriorityTier } from "#src/chunk_manager/base.js"; -import type { PriorityGetter } from "#src/chunk_manager/generic_file_source.js"; -import type { SharedCredentialsProviderCounterpart } from "#src/credentials_provider/shared_counterpart.js"; -import { WithSharedCredentialsProviderCounterpart } from "#src/credentials_provider/shared_counterpart.js"; +import type { SharedKvStoreContextCounterpart } from "#src/kvstore/backend.js"; +import { WithSharedKvStoreContextCounterpart } from "#src/kvstore/backend.js"; import { computeVertexNormals } from "#src/mesh/backend.js"; import type { SingleMeshData, @@ -39,12 +36,8 @@ import { SingleMeshSourceParametersWithInfo, } from "#src/single_mesh/base.js"; import type { TypedArray } from "#src/util/array.js"; -import type { CancellationToken } from "#src/util/cancellation.js"; import { stableStringify } from "#src/util/json.js"; -import type { - SpecialProtocolCredentials, - SpecialProtocolCredentialsProvider, -} from "#src/util/special_protocol_request.js"; +import type { ProgressOptions } from "#src/util/progress_listener.js"; import { getBasePriority, getPriorityTier, @@ -113,11 +106,9 @@ export interface SingleMeshVertexAttributes { interface SingleMeshFactory { description?: string; getMesh: ( - chunkManager: ChunkManager, - credentialsProvider: SpecialProtocolCredentialsProvider, + sharedKvStoreContext: SharedKvStoreContextCounterpart, url: string, - getPriority: PriorityGetter, - cancellationToken: CancellationToken, + options: Partial, ) => Promise; } @@ -150,20 +141,12 @@ function getDataSource( } export function getMesh( - chunkManager: ChunkManager, - credentialsProvider: SpecialProtocolCredentialsProvider, + sharedKvStoreContext: SharedKvStoreContextCounterpart, url: string, - getPriority: PriorityGetter, - cancellationToken: CancellationToken, + options: Partial, ) { const [factory, path] = getDataSource(singleMeshFactories, url); - return factory.getMesh( - chunkManager, - credentialsProvider, - path, - getPriority, - cancellationToken, - ); + return factory.getMesh(sharedKvStoreContext, path, options); } export function getMinMax(array: TypedArray): [number, number] { @@ -177,26 +160,16 @@ export function getMinMax(array: TypedArray): [number, number] { } export function getCombinedMesh( - chunkManager: ChunkManager, - credentialsProvider: SpecialProtocolCredentialsProvider, + sharedKvStoreContext: SharedKvStoreContextCounterpart, parameters: SingleMeshSourceParameters, - getPriority: PriorityGetter, - cancellationToken: CancellationToken, + options: Partial, ) { - return getMesh( - chunkManager, - credentialsProvider, - parameters.meshSourceUrl, - getPriority, - cancellationToken, - ); + return getMesh(sharedKvStoreContext, parameters.meshSourceUrl, options); } @registerSharedObject() export class SingleMeshSource extends WithParameters( - WithSharedCredentialsProviderCounterpart()( - ChunkSource, - ), + WithSharedKvStoreContextCounterpart(ChunkSource), SingleMeshSourceParametersWithInfo, ) { getChunk() { @@ -210,31 +183,24 @@ export class SingleMeshSource extends WithParameters( return chunk; } - download(chunk: SingleMeshChunk, cancellationToken: CancellationToken) { - const getPriority = () => ({ - priorityTier: chunk.priorityTier, - priority: chunk.priority, - }); - return getCombinedMesh( - this.chunkManager, - this.credentialsProvider, + async download(chunk: SingleMeshChunk, signal: AbortSignal) { + const data = await getCombinedMesh( + this.sharedKvStoreContext, this.parameters, - getPriority, - cancellationToken, - ).then((data) => { - if ( - stableStringify(data.info) !== stableStringify(this.parameters.info) - ) { - throw new Error("Mesh info has changed."); - } - if (data.vertexNormals === undefined) { - data.vertexNormals = computeVertexNormals( - data.vertexPositions, - data.indices, - ); - } - chunk.data = data; - }); + { + signal, + }, + ); + if (stableStringify(data.info) !== stableStringify(this.parameters.info)) { + throw new Error("Mesh info has changed."); + } + if (data.vertexNormals === undefined) { + data.vertexNormals = computeVertexNormals( + data.vertexPositions, + data.indices, + ); + } + chunk.data = data; } } @@ -274,33 +240,18 @@ export class SingleMeshLayer extends SingleMeshLayerBase { } } -const INFO_PRIORITY = 1000; - registerPromiseRPC( GET_SINGLE_MESH_INFO_RPC_ID, - async function (x, cancellationToken): RPCPromise { - const chunkManager = this.getRef(x.chunkManager); - const credentialsProvider = this.getOptionalRef< - SharedCredentialsProviderCounterpart< - Exclude - > - >(x.credentialsProvider); - try { - const parameters = x.parameters; - const mesh = await getCombinedMesh( - chunkManager, - credentialsProvider, - parameters, - () => ({ - priorityTier: ChunkPriorityTier.VISIBLE, - priority: INFO_PRIORITY, - }), - cancellationToken, - ); - return { value: mesh.info }; - } finally { - chunkManager.dispose(); - credentialsProvider?.dispose(); - } + async function (x, progressOptions): RPCPromise { + const sharedKvStoreContext = this.get( + x.sharedKvStoreContext, + ) as SharedKvStoreContextCounterpart; + const parameters = x.parameters; + const mesh = await getCombinedMesh( + sharedKvStoreContext, + parameters, + progressOptions, + ); + return { value: mesh.info }; }, ); diff --git a/src/single_mesh/base.ts b/src/single_mesh/base.ts index 30c499c758..c56421975c 100644 --- a/src/single_mesh/base.ts +++ b/src/single_mesh/base.ts @@ -39,10 +39,10 @@ export interface SingleMeshInfo { } export interface SingleMeshData { - vertexPositions: Float32Array; - indices: Uint32Array; - vertexNormals?: Float32Array; - vertexAttributes: Float32Array[]; + vertexPositions: Float32Array; + indices: Uint32Array; + vertexNormals?: Float32Array; + vertexAttributes: Float32Array[]; } export class SingleMeshSourceParameters { diff --git a/src/single_mesh/frontend.ts b/src/single_mesh/frontend.ts index 233f1f69d1..babbb00987 100644 --- a/src/single_mesh/frontend.ts +++ b/src/single_mesh/frontend.ts @@ -15,17 +15,13 @@ */ import { ChunkState } from "#src/chunk_manager/base.js"; -import type { ChunkManager } from "#src/chunk_manager/frontend.js"; import { Chunk, ChunkSource, WithParameters, } from "#src/chunk_manager/frontend.js"; -import { - getCredentialsProviderCounterpart, - WithCredentialsProvider, -} from "#src/credentials_provider/chunk_source_frontend.js"; -import type { CredentialsManager } from "#src/credentials_provider/index.js"; +import { WithSharedKvStoreContext } from "#src/kvstore/chunk_source_frontend.js"; +import type { SharedKvStoreContext } from "#src/kvstore/frontend.js"; import type { PickState, VisibleLayerInfo } from "#src/layer/index.js"; import type { PerspectivePanel } from "#src/perspective_view/panel.js"; import type { PerspectiveViewRenderContext } from "#src/perspective_view/render_layer.js"; @@ -47,10 +43,9 @@ import { WatchableValue } from "#src/trackable_value.js"; import { DataType } from "#src/util/data_type.js"; import type { mat4 } from "#src/util/geom.js"; import { vec3 } from "#src/util/geom.js"; -import type { SpecialProtocolCredentials } from "#src/util/special_protocol_request.js"; -import { parseSpecialUrl } from "#src/util/special_protocol_request.js"; +import type { ProgressOptions } from "#src/util/progress_listener.js"; import { withSharedVisibility } from "#src/visibility_priority/frontend.js"; -import type { Buffer } from "#src/webgl/buffer.js"; +import type { GLBuffer } from "#src/webgl/buffer.js"; import { glsl_COLORMAPS } from "#src/webgl/colormaps.js"; import type { GL } from "#src/webgl/context.js"; import { @@ -90,6 +85,16 @@ import { TextureFormat, } from "#src/webgl/texture_access.js"; import { SharedObject } from "#src/worker_rpc.js"; +import type { + DataSource, + GetKvStoreBasedDataSourceOptions, + KvStoreBasedDataSourceProvider, +} from "#src/datasource/index.js"; +import { ensureEmptyUrlSuffix } from "#src/kvstore/url.js"; +import { + makeCoordinateSpace, + makeIdentityTransform, +} from "#src/coordinate_transform.js"; const DEFAULT_FRAGMENT_MAIN = `void main() { emitGray(); @@ -400,8 +405,8 @@ export class VertexChunkData { } export class SingleMeshChunk extends Chunk { - source: SingleMeshSource; - indexBuffer: Buffer; + declare source: SingleMeshSource; + indexBuffer: GLBuffer; numIndices: number; indices: Uint32Array; vertexData: VertexChunkData; @@ -439,7 +444,7 @@ export function getAttributeTextureFormats( } export class SingleMeshSource extends WithParameters( - WithCredentialsProvider()(ChunkSource), + WithSharedKvStoreContext(ChunkSource), SingleMeshSourceParametersWithInfo, ) { attributeTextureFormats = getAttributeTextureFormats( @@ -459,51 +464,55 @@ const SharedObjectWithSharedVisibility = withSharedVisibility(SharedObject); class SingleMeshLayerSharedObject extends SharedObjectWithSharedVisibility {} export class SingleMeshLayer extends PerspectiveViewRenderLayer { - private shaderManager = new SingleMeshShaderManager( - pickAttributeNames(this.source.info.vertexAttributes.map((a) => a.name)), - this.source.info.vertexAttributes, - ); + private shaderManager: SingleMeshShaderManager; private shaders = new Map(); private sharedObject = this.registerDisposer( new SingleMeshLayerSharedObject(), ); - private shaderGetter = parameterizedEmitterDependentShaderGetter( - this, - this.gl, - { - memoizeKey: { - t: "single_mesh/RenderLayer", - attributes: this.source.info.vertexAttributes, - }, - fallbackParameters: new WatchableValue( - getFallbackBuilderState(parseShaderUiControls(DEFAULT_FRAGMENT_MAIN)), - ), - parameters: this.displayState.shaderControlState.builderState, - encodeParameters: (p) => p.key, - shaderError: this.displayState.shaderError, - defineShader: ( - builder: ShaderBuilder, - shaderBuilderState: ShaderControlsBuilderState, - ) => { - if (shaderBuilderState.parseResult.errors.length !== 0) { - throw new Error("Invalid UI control specification"); - } - addControlsToBuilder(shaderBuilderState, builder); - this.shaderManager.defineShader(builder); - builder.setFragmentMainFunction( - shaderCodeWithLineDirective(shaderBuilderState.parseResult.code), - ); - }, - }, - ); - - protected countingBuffer = this.registerDisposer(getCountingBuffer(this.gl)); + private shaderGetter; + protected countingBuffer; constructor( public source: SingleMeshSource, public displayState: SingleMeshDisplayState, public transform: WatchableRenderLayerTransform, ) { super(); + this.shaderManager = new SingleMeshShaderManager( + pickAttributeNames(source.info.vertexAttributes.map((a) => a.name)), + source.info.vertexAttributes, + ); + this.shaderGetter = parameterizedEmitterDependentShaderGetter( + this, + this.gl, + { + memoizeKey: { + t: "single_mesh/RenderLayer", + attributes: this.source.info.vertexAttributes, + }, + fallbackParameters: new WatchableValue( + getFallbackBuilderState(parseShaderUiControls(DEFAULT_FRAGMENT_MAIN)), + ), + parameters: this.displayState.shaderControlState.builderState, + encodeParameters: (p) => p.key, + shaderError: this.displayState.shaderError, + defineShader: ( + builder: ShaderBuilder, + shaderBuilderState: ShaderControlsBuilderState, + ) => { + if (shaderBuilderState.parseResult.errors.length !== 0) { + throw new Error("Invalid UI control specification"); + } + addControlsToBuilder(shaderBuilderState, builder); + this.shaderManager.defineShader(builder); + builder.setFragmentMainFunction( + shaderCodeWithLineDirective(shaderBuilderState.parseResult.code), + ); + }, + }, + ); + + this.countingBuffer = this.registerDisposer(getCountingBuffer(this.gl)); + this.registerDisposer( displayState.shaderControlState.parseResult.changed.add( this.redrawNeeded.dispatch, @@ -646,46 +655,77 @@ export class SingleMeshLayer extends PerspectiveViewRenderLayer, ) { - return chunkManager.memoize.getUncounted( + return sharedKvStoreContext.chunkManager.memoize.getAsync( { type: "single_mesh:getMeshInfo", url }, - async () => { - const { url: parsedUrl, credentialsProvider } = parseSpecialUrl( - url, - credentialsManager, - ); - const info = await chunkManager.rpc!.promiseInvoke( - GET_SINGLE_MESH_INFO_RPC_ID, - { - chunkManager: chunkManager.addCounterpartRef(), - credentialsProvider: - getCredentialsProviderCounterpart( - chunkManager, - credentialsProvider, - ), - parameters: { meshSourceUrl: parsedUrl }, - }, - ); - return { info, url: parsedUrl, credentialsProvider }; + options, + async (progressOptions) => { + const info = + await sharedKvStoreContext.chunkManager.rpc!.promiseInvoke( + GET_SINGLE_MESH_INFO_RPC_ID, + { + sharedKvStoreContext: sharedKvStoreContext.rpcId, + parameters: { meshSourceUrl: url }, + }, + { + signal: progressOptions.signal, + progressListener: options.progressListener, + }, + ); + return info; }, ); } export async function getSingleMeshSource( - chunkManager: ChunkManager, - credentialsManager: CredentialsManager, + sharedKvStoreContext: SharedKvStoreContext, url: string, + options: Partial, ) { - const { - info, - url: parsedUrl, - credentialsProvider, - } = await getSingleMeshInfo(chunkManager, credentialsManager, url); - return chunkManager.getChunkSource(SingleMeshSource, { - credentialsProvider, - parameters: { meshSourceUrl: parsedUrl, info }, + const info = await getSingleMeshInfo(sharedKvStoreContext, url, options); + return sharedKvStoreContext.chunkManager.getChunkSource(SingleMeshSource, { + sharedKvStoreContext, + parameters: { meshSourceUrl: url, info }, }); } + +export class SingleMeshDataSource implements KvStoreBasedDataSourceProvider { + constructor( + public scheme: string, + public description: string, + ) {} + + get singleFile() { + return true; + } + + async get(options: GetKvStoreBasedDataSourceOptions): Promise { + ensureEmptyUrlSuffix(options.url); + const meshSource = await getSingleMeshSource( + options.registry.sharedKvStoreContext, + `${options.url.scheme}://${options.kvStoreUrl}`, + options, + ); + const modelSpace = makeCoordinateSpace({ + rank: 3, + names: ["x", "y", "z"], + units: ["m", "m", "m"], + scales: Float64Array.of(1e-9, 1e-9, 1e-9), + }); + const dataSource: DataSource = { + canonicalUrl: `${options.kvStoreUrl}|${options.url.scheme}:`, + modelTransform: makeIdentityTransform(modelSpace), + subsources: [ + { + id: "default", + default: true, + subsource: { singleMesh: meshSource }, + }, + ], + }; + return dataSource; + } +} diff --git a/src/skeleton/backend.ts b/src/skeleton/backend.ts index cae8989b4d..f47c1a190e 100644 --- a/src/skeleton/backend.ts +++ b/src/skeleton/backend.ts @@ -120,7 +120,7 @@ export class SkeletonChunk extends Chunk { } export class SkeletonSource extends ChunkSource { - chunks: Map; + declare chunks: Map; getChunk(objectId: Uint64) { const key = getObjectKey(objectId); let chunk = this.chunks.get(key); diff --git a/src/skeleton/frontend.ts b/src/skeleton/frontend.ts index dc84c40b73..c95e8303ad 100644 --- a/src/skeleton/frontend.ts +++ b/src/skeleton/frontend.ts @@ -51,7 +51,7 @@ import { NullarySignal } from "#src/util/signal.js"; import type { Trackable } from "#src/util/trackable.js"; import { CompoundTrackable } from "#src/util/trackable.js"; import { TrackableEnum } from "#src/util/trackable_enum.js"; -import { Buffer } from "#src/webgl/buffer.js"; +import { GLBuffer } from "#src/webgl/buffer.js"; import { defineCircleShader, drawCircles, @@ -117,7 +117,7 @@ class RenderHelper extends RefCounted { private textureAccessHelper = new OneDimensionalTextureAccessHelper( "vertexData", ); - private vertexIdHelper = this.registerDisposer(VertexIdHelper.get(this.gl)); + private vertexIdHelper; get vertexAttributes(): VertexAttributeRenderInfo[] { return this.base.vertexAttributes; } @@ -129,29 +129,45 @@ class RenderHelper extends RefCounted { builder.addUniform("highp uint", "uPickID"); } - edgeShaderGetter = parameterizedEmitterDependentShaderGetter(this, this.gl, { - memoizeKey: { - type: "skeleton/SkeletonShaderManager/edge", - vertexAttributes: this.vertexAttributes, - }, - fallbackParameters: this.base.fallbackShaderParameters, - parameters: - this.base.displayState.skeletonRenderingOptions.shaderControlState - .builderState, - shaderError: this.base.displayState.shaderError, - defineShader: ( - builder: ShaderBuilder, - shaderBuilderState: ShaderControlsBuilderState, - ) => { - if (shaderBuilderState.parseResult.errors.length !== 0) { - throw new Error("Invalid UI control specification"); - } - this.defineCommonShader(builder); - this.defineAttributeAccess(builder); - defineLineShader(builder); - builder.addAttribute("highp uvec2", "aVertexIndex"); - builder.addUniform("highp float", "uLineWidth"); - let vertexMain = ` + edgeShaderGetter; + nodeShaderGetter; + + get gl(): GL { + return this.base.gl; + } + + constructor( + public base: SkeletonLayer, + public targetIsSliceView: boolean, + ) { + super(); + this.vertexIdHelper = this.registerDisposer(VertexIdHelper.get(this.gl)); + this.edgeShaderGetter = parameterizedEmitterDependentShaderGetter( + this, + this.gl, + { + memoizeKey: { + type: "skeleton/SkeletonShaderManager/edge", + vertexAttributes: this.vertexAttributes, + }, + fallbackParameters: this.base.fallbackShaderParameters, + parameters: + this.base.displayState.skeletonRenderingOptions.shaderControlState + .builderState, + shaderError: this.base.displayState.shaderError, + defineShader: ( + builder: ShaderBuilder, + shaderBuilderState: ShaderControlsBuilderState, + ) => { + if (shaderBuilderState.parseResult.errors.length !== 0) { + throw new Error("Invalid UI control specification"); + } + this.defineCommonShader(builder); + this.defineAttributeAccess(builder); + defineLineShader(builder); + builder.addAttribute("highp uvec2", "aVertexIndex"); + builder.addUniform("highp float", "uLineWidth"); + let vertexMain = ` highp vec3 vertexA = readAttribute0(aVertexIndex.x); highp vec3 vertexB = readAttribute0(aVertexIndex.y); emitLine(uProjection, vertexA, vertexB, uLineWidth); @@ -159,7 +175,7 @@ highp uint lineEndpointIndex = getLineEndpointIndex(); highp uint vertexIndex = aVertexIndex.x * lineEndpointIndex + aVertexIndex.y * (1u - lineEndpointIndex); `; - builder.addFragmentCode(` + builder.addFragmentCode(` vec4 segmentColor() { return uColor; } @@ -170,51 +186,58 @@ void emitDefault() { emit(vec4(uColor.rgb, uColor.a * getLineAlpha() * ${this.getCrossSectionFadeFactor()}), uPickID); } `); - builder.addFragmentCode(glsl_COLORMAPS); - const { vertexAttributes } = this; - const numAttributes = vertexAttributes.length; - for (let i = 1; i < numAttributes; ++i) { - const info = vertexAttributes[i]; - builder.addVarying(`highp ${info.glslDataType}`, `vCustom${i}`); - vertexMain += `vCustom${i} = readAttribute${i}(vertexIndex);\n`; - builder.addFragmentCode(`#define ${info.name} vCustom${i}\n`); - } - builder.setVertexMain(vertexMain); - addControlsToBuilder(shaderBuilderState, builder); - builder.setFragmentMainFunction( - shaderCodeWithLineDirective(shaderBuilderState.parseResult.code), - ); - }, - }); - - nodeShaderGetter = parameterizedEmitterDependentShaderGetter(this, this.gl, { - memoizeKey: { - type: "skeleton/SkeletonShaderManager/node", - vertexAttributes: this.vertexAttributes, - }, - fallbackParameters: this.base.fallbackShaderParameters, - parameters: - this.base.displayState.skeletonRenderingOptions.shaderControlState - .builderState, - shaderError: this.base.displayState.shaderError, - defineShader: ( - builder: ShaderBuilder, - shaderBuilderState: ShaderControlsBuilderState, - ) => { - if (shaderBuilderState.parseResult.errors.length !== 0) { - throw new Error("Invalid UI control specification"); - } - this.defineCommonShader(builder); - this.defineAttributeAccess(builder); - defineCircleShader(builder, /*crossSectionFade=*/ this.targetIsSliceView); - builder.addUniform("highp float", "uNodeDiameter"); - let vertexMain = ` + builder.addFragmentCode(glsl_COLORMAPS); + const { vertexAttributes } = this; + const numAttributes = vertexAttributes.length; + for (let i = 1; i < numAttributes; ++i) { + const info = vertexAttributes[i]; + builder.addVarying(`highp ${info.glslDataType}`, `vCustom${i}`); + vertexMain += `vCustom${i} = readAttribute${i}(vertexIndex);\n`; + builder.addFragmentCode(`#define ${info.name} vCustom${i}\n`); + } + builder.setVertexMain(vertexMain); + addControlsToBuilder(shaderBuilderState, builder); + builder.setFragmentMainFunction( + shaderCodeWithLineDirective(shaderBuilderState.parseResult.code), + ); + }, + }, + ); + + this.nodeShaderGetter = parameterizedEmitterDependentShaderGetter( + this, + this.gl, + { + memoizeKey: { + type: "skeleton/SkeletonShaderManager/node", + vertexAttributes: this.vertexAttributes, + }, + fallbackParameters: this.base.fallbackShaderParameters, + parameters: + this.base.displayState.skeletonRenderingOptions.shaderControlState + .builderState, + shaderError: this.base.displayState.shaderError, + defineShader: ( + builder: ShaderBuilder, + shaderBuilderState: ShaderControlsBuilderState, + ) => { + if (shaderBuilderState.parseResult.errors.length !== 0) { + throw new Error("Invalid UI control specification"); + } + this.defineCommonShader(builder); + this.defineAttributeAccess(builder); + defineCircleShader( + builder, + /*crossSectionFade=*/ this.targetIsSliceView, + ); + builder.addUniform("highp float", "uNodeDiameter"); + let vertexMain = ` highp uint vertexIndex = uint(gl_InstanceID); highp vec3 vertexPosition = readAttribute0(vertexIndex); emitCircle(uProjection * vec4(vertexPosition, 1.0), uNodeDiameter, 0.0); `; - builder.addFragmentCode(` + builder.addFragmentCode(` vec4 segmentColor() { return uColor; } @@ -229,32 +252,23 @@ void emitDefault() { emitRGBA(uColor); } `); - builder.addFragmentCode(glsl_COLORMAPS); - const { vertexAttributes } = this; - const numAttributes = vertexAttributes.length; - for (let i = 1; i < numAttributes; ++i) { - const info = vertexAttributes[i]; - builder.addVarying(`highp ${info.glslDataType}`, `vCustom${i}`); - vertexMain += `vCustom${i} = readAttribute${i}(vertexIndex);\n`; - builder.addFragmentCode(`#define ${info.name} vCustom${i}\n`); - } - builder.setVertexMain(vertexMain); - addControlsToBuilder(shaderBuilderState, builder); - builder.setFragmentMainFunction( - shaderCodeWithLineDirective(shaderBuilderState.parseResult.code), - ); - }, - }); - - get gl(): GL { - return this.base.gl; - } - - constructor( - public base: SkeletonLayer, - public targetIsSliceView: boolean, - ) { - super(); + builder.addFragmentCode(glsl_COLORMAPS); + const { vertexAttributes } = this; + const numAttributes = vertexAttributes.length; + for (let i = 1; i < numAttributes; ++i) { + const info = vertexAttributes[i]; + builder.addVarying(`highp ${info.glslDataType}`, `vCustom${i}`); + vertexMain += `vCustom${i} = readAttribute${i}(vertexIndex);\n`; + builder.addFragmentCode(`#define ${info.name} vCustom${i}\n`); + } + builder.setVertexMain(vertexMain); + addControlsToBuilder(shaderBuilderState, builder); + builder.setFragmentMainFunction( + shaderCodeWithLineDirective(shaderBuilderState.parseResult.code), + ); + }, + }, + ); } defineAttributeAccess(builder: ShaderBuilder) { @@ -648,13 +662,13 @@ export class SkeletonLayer extends RefCounted { } export class PerspectiveViewSkeletonLayer extends PerspectiveViewRenderLayer { - private renderHelper = this.registerDisposer( - new RenderHelper(this.base, false), - ); - private renderOptions = - this.base.displayState.skeletonRenderingOptions.params3d; + private renderHelper: RenderHelper; + private renderOptions: ViewSpecificSkeletonRenderingOptions; constructor(public base: SkeletonLayer) { super(); + this.renderHelper = this.registerDisposer(new RenderHelper(base, false)); + this.renderOptions = base.displayState.skeletonRenderingOptions.params3d; + this.layerChunkProgressInfo = base.layerChunkProgressInfo; this.registerDisposer(base); this.registerDisposer(base.redrawNeeded.add(this.redrawNeeded.dispatch)); @@ -701,13 +715,12 @@ export class PerspectiveViewSkeletonLayer extends PerspectiveViewRenderLayer { } export class SliceViewPanelSkeletonLayer extends SliceViewPanelRenderLayer { - private renderHelper = this.registerDisposer( - new RenderHelper(this.base, true), - ); - private renderOptions = - this.base.displayState.skeletonRenderingOptions.params2d; + private renderHelper: RenderHelper; + private renderOptions: ViewSpecificSkeletonRenderingOptions; constructor(public base: SkeletonLayer) { super(); + this.renderHelper = this.registerDisposer(new RenderHelper(base, true)); + this.renderOptions = base.displayState.skeletonRenderingOptions.params2d; this.layerChunkProgressInfo = base.layerChunkProgressInfo; this.registerDisposer(base); const { renderOptions } = this; @@ -765,10 +778,10 @@ const vertexPositionAttribute: VertexAttributeRenderInfo = { }; export class SkeletonChunk extends Chunk { - source: SkeletonSource; + declare source: SkeletonSource; vertexAttributes: Uint8Array; indices: Uint32Array; - indexBuffer: Buffer; + indexBuffer: GLBuffer; numIndices: number; numVertices: number; vertexAttributeOffsets: Uint32Array; @@ -809,7 +822,7 @@ export class SkeletonChunk extends Chunk { vertexAttributeTextures[i] = texture; } gl.bindTexture(WebGL2RenderingContext.TEXTURE_2D, null); - this.indexBuffer = Buffer.fromData( + this.indexBuffer = GLBuffer.fromData( gl, this.indices, WebGL2RenderingContext.ARRAY_BUFFER, @@ -862,7 +875,7 @@ export class SkeletonSource extends ChunkSource { return attributeTextureFormats; } - chunks: Map; + declare chunks: Map; getChunk(x: any) { return new SkeletonChunk(this, x); } diff --git a/src/sliceview/backend.ts b/src/sliceview/backend.ts index f95e2062b7..a921901d2e 100644 --- a/src/sliceview/backend.ts +++ b/src/sliceview/backend.ts @@ -48,8 +48,7 @@ import { } from "#src/sliceview/base.js"; import { ChunkLayout } from "#src/sliceview/chunk_layout.js"; import type { WatchableValueInterface } from "#src/trackable_value.js"; -import type { CancellationToken } from "#src/util/cancellation.js"; -import { CANCELED } from "#src/util/cancellation.js"; +import { raceWithAbort } from "#src/util/abort.js"; import { erf } from "#src/util/erf.js"; import { vec3, vec3Key } from "#src/util/geom.js"; import { VelocityEstimator } from "#src/util/velocity_estimation.js"; @@ -389,7 +388,7 @@ export class SliceViewChunkSourceBackend< implements SliceViewChunkSourceInterface { spec: Spec; - chunks: Map; + declare chunks: Map; constructor(rpc: RPC, options: any) { super(rpc, options); this.spec = options.spec; @@ -412,7 +411,7 @@ export class SliceViewRenderLayerBackend extends SharedObjectCounterpart implements SliceViewRenderLayerInterface, ChunkRenderLayerBackend { - rpcId: number; + declare rpcId: number; renderScaleTarget: SharedWatchableValue; localPosition: WatchableValueInterface; @@ -536,7 +535,7 @@ registerPromiseRPC( SLICEVIEW_REQUEST_CHUNK_RPC_ID, async function ( x: { this: RPC; source: number; chunkGridPosition: Float32Array }, - cancellationToken: CancellationToken, + progressOptions, ): RPCPromise { const source = this.get(x.source) as SliceViewChunkSourceBackend; const { chunkManager } = source; @@ -546,6 +545,10 @@ registerPromiseRPC( // Already available on frontend. return { value: undefined }; } + if (chunk.state === ChunkState.FAILED) { + // Already failed + throw chunk.error; + } const disposeRecompute = chunkManager.recomputeChunkPriorities.add(() => { chunkManager.requestChunk( chunk, @@ -568,13 +571,8 @@ registerPromiseRPC( }; }); source.registerChunkListener(key, listener!); - const cancelPromise = new Promise((_resolve, reject) => { - cancellationToken.add(() => { - reject(CANCELED); - }); - }); try { - await Promise.race([promise, cancelPromise]); + await raceWithAbort(promise, progressOptions.signal); return { value: undefined }; } finally { source.unregisterChunkListener(key, listener!); diff --git a/src/sliceview/backend_chunk_decoders/bossNpz.ts b/src/sliceview/backend_chunk_decoders/bossNpz.ts index 2ee975c7b7..250cc3ba4e 100644 --- a/src/sliceview/backend_chunk_decoders/bossNpz.ts +++ b/src/sliceview/backend_chunk_decoders/bossNpz.ts @@ -22,27 +22,20 @@ * (each corresponding to a different variable) in NPY binary format. */ -import { decodeGzip } from "#src/async_computation/decode_gzip_request.js"; -import { requestAsyncComputation } from "#src/async_computation/request.js"; import { postProcessRawData } from "#src/sliceview/backend_chunk_decoders/postprocess.js"; import { DataType } from "#src/sliceview/base.js"; import type { VolumeChunk } from "#src/sliceview/volume/backend.js"; -import type { CancellationToken } from "#src/util/cancellation.js"; import { vec3Key } from "#src/util/geom.js"; +import { decodeGzip } from "#src/util/gzip.js"; import { parseNpy } from "#src/util/npy.js"; export async function decodeBossNpzChunk( chunk: VolumeChunk, - cancellationToken: CancellationToken, + signal: AbortSignal, response: ArrayBuffer, ) { const parseResult = parseNpy( - await requestAsyncComputation( - decodeGzip, - cancellationToken, - [response], - new Uint8Array(response), - ), + new Uint8Array(await decodeGzip(response, "deflate")), ); const chunkDataSize = chunk.chunkDataSize!; const source = chunk.source!; @@ -68,5 +61,5 @@ export async function decodeBossNpzChunk( } does not match expected data type ${DataType[spec.dataType]}`, ); } - await postProcessRawData(chunk, cancellationToken, parseResult.data); + await postProcessRawData(chunk, signal, parseResult.data); } diff --git a/src/sliceview/backend_chunk_decoders/compressed_segmentation.ts b/src/sliceview/backend_chunk_decoders/compressed_segmentation.ts index e9e387456e..2a9a6d8358 100644 --- a/src/sliceview/backend_chunk_decoders/compressed_segmentation.ts +++ b/src/sliceview/backend_chunk_decoders/compressed_segmentation.ts @@ -15,13 +15,12 @@ */ import type { VolumeChunk } from "#src/sliceview/volume/backend.js"; -import type { CancellationToken } from "#src/util/cancellation.js"; export async function decodeCompressedSegmentationChunk( chunk: VolumeChunk, - cancellationToken: CancellationToken, + signal: AbortSignal, response: ArrayBuffer, ) { - cancellationToken; + signal; chunk.data = new Uint32Array(response); } diff --git a/src/sliceview/backend_chunk_decoders/compresso.ts b/src/sliceview/backend_chunk_decoders/compresso.ts index b35548a3a6..c4e3ac680e 100644 --- a/src/sliceview/backend_chunk_decoders/compresso.ts +++ b/src/sliceview/backend_chunk_decoders/compresso.ts @@ -18,20 +18,18 @@ import { decodeCompresso } from "#src/async_computation/decode_compresso_request import { requestAsyncComputation } from "#src/async_computation/request.js"; import { decodeRawChunk } from "#src/sliceview/backend_chunk_decoders/raw.js"; import type { VolumeChunk } from "#src/sliceview/volume/backend.js"; -import type { TypedArray } from "#src/util/array.js"; -import type { CancellationToken } from "#src/util/cancellation.js"; export async function decodeCompressoChunk( chunk: VolumeChunk, - cancellationToken: CancellationToken, + signal: AbortSignal, response: ArrayBuffer, ) { - const image: TypedArray = await requestAsyncComputation( + const image = await requestAsyncComputation( decodeCompresso, - cancellationToken, + signal, [response], new Uint8Array(response), ); - await decodeRawChunk(chunk, cancellationToken, image.buffer); + await decodeRawChunk(chunk, signal, image.buffer); } diff --git a/src/sliceview/backend_chunk_decoders/index.ts b/src/sliceview/backend_chunk_decoders/index.ts index 04e3d8dd31..f9e4e94e83 100644 --- a/src/sliceview/backend_chunk_decoders/index.ts +++ b/src/sliceview/backend_chunk_decoders/index.ts @@ -20,9 +20,8 @@ */ import type { VolumeChunk } from "#src/sliceview/volume/backend.js"; -import type { CancellationToken } from "#src/util/cancellation.js"; export type ChunkDecoder = ( chunk: VolumeChunk, - cancellationToken: CancellationToken, + signal: AbortSignal, response: ArrayBuffer, ) => Promise; diff --git a/src/sliceview/backend_chunk_decoders/jpeg.ts b/src/sliceview/backend_chunk_decoders/jpeg.ts index 854b84f667..6a9ede1553 100644 --- a/src/sliceview/backend_chunk_decoders/jpeg.ts +++ b/src/sliceview/backend_chunk_decoders/jpeg.ts @@ -18,17 +18,16 @@ import { decodeJpeg } from "#src/async_computation/decode_jpeg_request.js"; import { requestAsyncComputation } from "#src/async_computation/request.js"; import { postProcessRawData } from "#src/sliceview/backend_chunk_decoders/postprocess.js"; import type { VolumeChunk } from "#src/sliceview/volume/backend.js"; -import type { CancellationToken } from "#src/util/cancellation.js"; export async function decodeJpegChunk( chunk: VolumeChunk, - cancellationToken: CancellationToken, + signal: AbortSignal, response: ArrayBuffer, ) { const chunkDataSize = chunk.chunkDataSize!; const { uint8Array: decoded } = await requestAsyncComputation( decodeJpeg, - cancellationToken, + signal, [response], new Uint8Array(response), undefined, @@ -37,5 +36,5 @@ export async function decodeJpegChunk( chunkDataSize[3] || 1, false, ); - await postProcessRawData(chunk, cancellationToken, decoded); + await postProcessRawData(chunk, signal, decoded); } diff --git a/src/sliceview/backend_chunk_decoders/jxl.ts b/src/sliceview/backend_chunk_decoders/jxl.ts index 914367a715..f515d8f856 100644 --- a/src/sliceview/backend_chunk_decoders/jxl.ts +++ b/src/sliceview/backend_chunk_decoders/jxl.ts @@ -18,22 +18,21 @@ import { decodeJxl } from "#src/async_computation/decode_jxl_request.js"; import { requestAsyncComputation } from "#src/async_computation/request.js"; import { postProcessRawData } from "#src/sliceview/backend_chunk_decoders/postprocess.js"; import type { VolumeChunk } from "#src/sliceview/volume/backend.js"; -import type { CancellationToken } from "#src/util/cancellation.js"; export async function decodeJxlChunk( chunk: VolumeChunk, - cancellationToken: CancellationToken, + signal: AbortSignal, response: ArrayBuffer, ) { const chunkDataSize = chunk.chunkDataSize!; const { uint8Array: decoded } = await requestAsyncComputation( decodeJxl, - cancellationToken, + signal, [response], new Uint8Array(response), chunkDataSize[0] * chunkDataSize[1] * chunkDataSize[2], chunkDataSize[3] || 1, 1, // bytesPerPixel ); - await postProcessRawData(chunk, cancellationToken, decoded); + await postProcessRawData(chunk, signal, decoded); } diff --git a/src/sliceview/backend_chunk_decoders/ndstoreNpz.ts b/src/sliceview/backend_chunk_decoders/ndstoreNpz.ts index 6f7164d628..210129fd1d 100644 --- a/src/sliceview/backend_chunk_decoders/ndstoreNpz.ts +++ b/src/sliceview/backend_chunk_decoders/ndstoreNpz.ts @@ -22,27 +22,20 @@ * (each corresponding to a different variable) in NPY binary format. */ -import { decodeGzip } from "#src/async_computation/decode_gzip_request.js"; -import { requestAsyncComputation } from "#src/async_computation/request.js"; import { postProcessRawData } from "#src/sliceview/backend_chunk_decoders/postprocess.js"; import { DataType } from "#src/sliceview/base.js"; import type { VolumeChunk } from "#src/sliceview/volume/backend.js"; import { arraysEqual } from "#src/util/array.js"; -import type { CancellationToken } from "#src/util/cancellation.js"; +import { decodeGzip } from "#src/util/gzip.js"; import { parseNpy } from "#src/util/npy.js"; export async function decodeNdstoreNpzChunk( chunk: VolumeChunk, - cancellationToken: CancellationToken, + signal: AbortSignal, response: ArrayBuffer, ) { const parseResult = parseNpy( - await requestAsyncComputation( - decodeGzip, - cancellationToken, - [response], - new Uint8Array(response), - ), + new Uint8Array(await decodeGzip(response, "deflate")), ); const chunkDataSize = chunk.chunkDataSize!; const source = chunk.source!; @@ -62,5 +55,5 @@ export async function decodeNdstoreNpzChunk( `expected data type ${DataType[spec.dataType]}`, ); } - await postProcessRawData(chunk, cancellationToken, parseResult.data); + await postProcessRawData(chunk, signal, parseResult.data); } diff --git a/src/sliceview/backend_chunk_decoders/png.ts b/src/sliceview/backend_chunk_decoders/png.ts index f5d34b5e50..22bb9f37e9 100644 --- a/src/sliceview/backend_chunk_decoders/png.ts +++ b/src/sliceview/backend_chunk_decoders/png.ts @@ -18,19 +18,18 @@ import { decodePng } from "#src/async_computation/decode_png_request.js"; import { requestAsyncComputation } from "#src/async_computation/request.js"; import { decodeRawChunk } from "#src/sliceview/backend_chunk_decoders/raw.js"; import type { VolumeChunk } from "#src/sliceview/volume/backend.js"; -import type { CancellationToken } from "#src/util/cancellation.js"; import { DATA_TYPE_BYTES } from "#src/util/data_type.js"; export async function decodePngChunk( chunk: VolumeChunk, - cancellationToken: CancellationToken, + signal: AbortSignal, response: ArrayBuffer, ) { const chunkDataSize = chunk.chunkDataSize!; const dataType = chunk.source!.spec.dataType; const { uint8Array: image } = await requestAsyncComputation( decodePng, - cancellationToken, + signal, [response], /*buffer=*/ new Uint8Array(response), /*width=*/ undefined, @@ -41,5 +40,5 @@ export async function decodePngChunk( /*convertToGrayscale=*/ false, ); - await decodeRawChunk(chunk, cancellationToken, image.buffer); + await decodeRawChunk(chunk, signal, image.buffer); } diff --git a/src/sliceview/backend_chunk_decoders/postprocess.ts b/src/sliceview/backend_chunk_decoders/postprocess.ts index 69efafaca2..23bbf0d89a 100644 --- a/src/sliceview/backend_chunk_decoders/postprocess.ts +++ b/src/sliceview/backend_chunk_decoders/postprocess.ts @@ -25,14 +25,12 @@ import { import { requestAsyncComputation } from "#src/async_computation/request.js"; import { DataType } from "#src/sliceview/base.js"; import type { VolumeChunk } from "#src/sliceview/volume/backend.js"; -import type { CancellationToken } from "#src/util/cancellation.js"; export async function postProcessRawData( chunk: VolumeChunk, - cancellationToken: CancellationToken, + signal: AbortSignal, data: ArrayBufferView, ) { - cancellationToken; const { spec } = chunk.source!; if (spec.compressedSegmentationBlockSize !== undefined) { const { dataType } = spec; @@ -47,7 +45,7 @@ export async function postProcessRawData( case DataType.UINT32: chunk.data = await requestAsyncComputation( encodeCompressedSegmentationUint32, - cancellationToken, + signal, [data.buffer], data as Uint32Array, shape, @@ -57,7 +55,7 @@ export async function postProcessRawData( case DataType.UINT64: chunk.data = await requestAsyncComputation( encodeCompressedSegmentationUint64, - cancellationToken, + signal, [data.buffer], data as Uint32Array, shape, diff --git a/src/sliceview/backend_chunk_decoders/raw.ts b/src/sliceview/backend_chunk_decoders/raw.ts index 96426f6b98..2a883c16d3 100644 --- a/src/sliceview/backend_chunk_decoders/raw.ts +++ b/src/sliceview/backend_chunk_decoders/raw.ts @@ -16,7 +16,6 @@ import { postProcessRawData } from "#src/sliceview/backend_chunk_decoders/postprocess.js"; import type { VolumeChunk } from "#src/sliceview/volume/backend.js"; -import type { CancellationToken } from "#src/util/cancellation.js"; import { DATA_TYPE_BYTES, makeDataTypeArrayView } from "#src/util/data_type.js"; import type { Endianness } from "#src/util/endian.js"; import { convertEndian, ENDIANNESS } from "#src/util/endian.js"; @@ -24,13 +23,13 @@ import * as vector from "#src/util/vector.js"; export async function decodeRawChunk( chunk: VolumeChunk, - cancellationToken: CancellationToken, + signal: AbortSignal, response: ArrayBuffer, endianness: Endianness = ENDIANNESS, byteOffset = 0, byteLength: number = response.byteLength, ) { - cancellationToken; + signal; const { spec } = chunk.source!; const { dataType } = spec; const numElements = vector.prod(chunk.chunkDataSize!); @@ -49,5 +48,5 @@ export async function decodeRawChunk( byteLength, ); convertEndian(data, endianness, bytesPerElement); - await postProcessRawData(chunk, cancellationToken, data); + await postProcessRawData(chunk, signal, data); } diff --git a/src/sliceview/compressed_segmentation/chunk_format.ts b/src/sliceview/compressed_segmentation/chunk_format.ts index d8e86f39ba..74ea6e518d 100644 --- a/src/sliceview/compressed_segmentation/chunk_format.ts +++ b/src/sliceview/compressed_segmentation/chunk_format.ts @@ -300,7 +300,7 @@ export class CompressedSegmentationVolumeChunk extends SingleTextureVolumeChunk< Uint32Array, TextureLayout > { - CHUNK_FORMAT_TYPE: ChunkFormat; + declare CHUNK_FORMAT_TYPE: ChunkFormat; setTextureData(gl: GL) { const { data } = this; diff --git a/src/sliceview/compressed_segmentation/decode_uint32.ts b/src/sliceview/compressed_segmentation/decode_uint32.ts index 8fa21d13b5..8794469964 100644 --- a/src/sliceview/compressed_segmentation/decode_uint32.ts +++ b/src/sliceview/compressed_segmentation/decode_uint32.ts @@ -1,5 +1,4 @@ -// DO NOT EDIT. Generated from -// templates/neuroglancer/sliceview/compressed_segmentation/decode.template.ts. +// DO NOT EDIT. Generated from templates/sliceview/compressed_segmentation/decode.template.ts. /** * @license * Copyright 2016 Google Inc. diff --git a/src/sliceview/compressed_segmentation/decode_uint64.ts b/src/sliceview/compressed_segmentation/decode_uint64.ts index 76a4b32e6b..329d014cee 100644 --- a/src/sliceview/compressed_segmentation/decode_uint64.ts +++ b/src/sliceview/compressed_segmentation/decode_uint64.ts @@ -1,5 +1,4 @@ -// DO NOT EDIT. Generated from -// templates/neuroglancer/sliceview/compressed_segmentation/decode.template.ts. +// DO NOT EDIT. Generated from templates/sliceview/compressed_segmentation/decode.template.ts. /** * @license * Copyright 2016 Google Inc. diff --git a/src/sliceview/compressed_segmentation/encode.benchmark.ts b/src/sliceview/compressed_segmentation/encode.benchmark.ts index dcd19fbc49..022c72ce66 100644 --- a/src/sliceview/compressed_segmentation/encode.benchmark.ts +++ b/src/sliceview/compressed_segmentation/encode.benchmark.ts @@ -32,7 +32,12 @@ describe("64x64x64 example", async () => { "testdata", ); const exampleChunkDataUint8Array = await fs.readFile( - path.resolve(testDataDir, "64x64x64-raw-uint64-segmentation.dat"), + path.resolve( + testDataDir, + "codec", + "compressed_segmentation", + "64x64x64-raw-uint64-segmentation.dat", + ), ); const exampleChunkData64 = new Uint32Array(exampleChunkDataUint8Array.buffer); const exampleChunkData32 = exampleChunkData64.filter((_element, index) => { diff --git a/src/sliceview/compressed_segmentation/encode_common.ts b/src/sliceview/compressed_segmentation/encode_common.ts index 4cc5bcc3f9..ac283a0e21 100644 --- a/src/sliceview/compressed_segmentation/encode_common.ts +++ b/src/sliceview/compressed_segmentation/encode_common.ts @@ -1,5 +1,4 @@ -// DO NOT EDIT. Generated from -// templates/neuroglancer/sliceview/compressed_segmentation/encode_common.template.ts. +// DO NOT EDIT. Generated from templates/sliceview/compressed_segmentation/encode_common.template.ts. /** * @license * Copyright 2016 Google Inc. @@ -351,22 +350,22 @@ export function encodeChannel( const curGridSize = (gridSize[i] = Math.ceil(volumeSize[i] / blockSize[i])); blockIndexSize *= curGridSize; } - const gx = gridSize[0]; - const gy = gridSize[1]; - const gz = gridSize[2]; - const xSize = volumeSize[0]; - const ySize = volumeSize[1]; - const zSize = volumeSize[2]; - const xBlockSize = blockSize[0]; - const yBlockSize = blockSize[1]; - const zBlockSize = blockSize[2]; + const gx = gridSize[0], + gy = gridSize[1], + gz = gridSize[2]; + const xSize = volumeSize[0], + ySize = volumeSize[1], + zSize = volumeSize[2]; + const xBlockSize = blockSize[0], + yBlockSize = blockSize[1], + zBlockSize = blockSize[2]; const baseOffset = output.length; let headerOffset = baseOffset; const actualSize = [0, 0, 0]; output.resize(baseOffset + blockIndexSize); - const sx = inputStrides[0]; - const sy = inputStrides[1]; - const sz = inputStrides[2]; + const sx = inputStrides[0], + sy = inputStrides[1], + sz = inputStrides[2]; for (let bz = 0; bz < gz; ++bz) { actualSize[2] = Math.min(zBlockSize, zSize - bz * zBlockSize); for (let by = 0; by < gy; ++by) { diff --git a/src/sliceview/compressed_segmentation/encode_uint32.ts b/src/sliceview/compressed_segmentation/encode_uint32.ts index e5d62e588c..fc868d266d 100644 --- a/src/sliceview/compressed_segmentation/encode_uint32.ts +++ b/src/sliceview/compressed_segmentation/encode_uint32.ts @@ -1,5 +1,4 @@ -// DO NOT EDIT. Generated from -// templates/neuroglancer/sliceview/compressed_segmentation/encode.template.ts. +// DO NOT EDIT. Generated from templates/sliceview/compressed_segmentation/encode.template.ts. /** * @license * Copyright 2016 Google Inc. @@ -49,15 +48,15 @@ export function encodeBlock( cache: Map, output: Uint32ArrayBuilder, ): [number, number] { - const ax = actualSize[0]; - const ay = actualSize[1]; - const az = actualSize[2]; - const bx = blockSize[0]; - const by = blockSize[1]; - const bz = blockSize[2]; + const ax = actualSize[0], + ay = actualSize[1], + az = actualSize[2]; + const bx = blockSize[0], + by = blockSize[1], + bz = blockSize[2]; const sx = inputStrides[0]; - let sy = inputStrides[1]; - let sz = inputStrides[2]; + let sy = inputStrides[1], + sz = inputStrides[2]; sz -= sy * ay; sy -= sx * ax; if (ax * ay * az === 0) { @@ -153,7 +152,7 @@ export function encodeChannel( blockSize: ArrayLike, rawData: Uint32Array, volumeSize: ArrayLike, - baseInputOffset = 0, + baseInputOffset: number = 0, inputStrides = getFortranOrderStrides(volumeSize, 1), ) { return encodeChannelCommon( @@ -172,7 +171,7 @@ export function encodeChannels( blockSize: ArrayLike, rawData: Uint32Array, volumeSize: ArrayLike, - baseInputOffset = 0, + baseInputOffset: number = 0, inputStrides = getFortranOrderStrides(volumeSize, 1), ) { return encodeChannelsCommon( diff --git a/src/sliceview/compressed_segmentation/encode_uint64.ts b/src/sliceview/compressed_segmentation/encode_uint64.ts index b40fd5c84b..e2030d8f73 100644 --- a/src/sliceview/compressed_segmentation/encode_uint64.ts +++ b/src/sliceview/compressed_segmentation/encode_uint64.ts @@ -1,5 +1,4 @@ -// DO NOT EDIT. Generated from -// templates/neuroglancer/sliceview/compressed_segmentation/encode.template.ts. +// DO NOT EDIT. Generated from templates/sliceview/compressed_segmentation/encode.template.ts. /** * @license * Copyright 2016 Google Inc. @@ -49,15 +48,15 @@ export function encodeBlock( cache: Map, output: Uint32ArrayBuilder, ): [number, number] { - const ax = actualSize[0]; - const ay = actualSize[1]; - const az = actualSize[2]; - const bx = blockSize[0]; - const by = blockSize[1]; - const bz = blockSize[2]; + const ax = actualSize[0], + ay = actualSize[1], + az = actualSize[2]; + const bx = blockSize[0], + by = blockSize[1], + bz = blockSize[2]; const sx = inputStrides[0]; - let sy = inputStrides[1]; - let sz = inputStrides[2]; + let sy = inputStrides[1], + sz = inputStrides[2]; sz -= sy * ay; sy -= sx * ax; if (ax * ay * az === 0) { @@ -170,7 +169,7 @@ export function encodeChannel( blockSize: ArrayLike, rawData: Uint32Array, volumeSize: ArrayLike, - baseInputOffset = 0, + baseInputOffset: number = 0, inputStrides = getFortranOrderStrides(volumeSize, 2), ) { return encodeChannelCommon( @@ -189,7 +188,7 @@ export function encodeChannels( blockSize: ArrayLike, rawData: Uint32Array, volumeSize: ArrayLike, - baseInputOffset = 0, + baseInputOffset: number = 0, inputStrides = getFortranOrderStrides(volumeSize, 2), ) { return encodeChannelsCommon( diff --git a/src/sliceview/compresso/index.ts b/src/sliceview/compresso/index.ts index 3ab4100a35..b29ba329e7 100644 --- a/src/sliceview/compresso/index.ts +++ b/src/sliceview/compresso/index.ts @@ -75,7 +75,7 @@ function readHeader(buffer: Uint8Array): { export async function decompressCompresso( buffer: Uint8Array, -): Promise { +): Promise> { const m = await getCompressoModulePromise(); const { sx, sy, sz, dataWidth } = readHeader(buffer); diff --git a/src/sliceview/frontend.ts b/src/sliceview/frontend.ts index dd20d2a6b7..4cd15754fd 100644 --- a/src/sliceview/frontend.ts +++ b/src/sliceview/frontend.ts @@ -62,14 +62,13 @@ import { import { ChunkLayout } from "#src/sliceview/chunk_layout.js"; import { SliceViewRenderLayer } from "#src/sliceview/renderlayer.js"; import type { WatchableValueInterface } from "#src/trackable_value.js"; -import type { CancellationToken } from "#src/util/cancellation.js"; -import { uncancelableToken } from "#src/util/cancellation.js"; import type { Borrowed, Disposer, Owned } from "#src/util/disposable.js"; import { invokeDisposers, RefCounted } from "#src/util/disposable.js"; import type { vec4 } from "#src/util/geom.js"; import { kOneVec, kZeroVec4, mat4, vec3 } from "#src/util/geom.js"; import { MessageList, MessageSeverity } from "#src/util/message_list.js"; import { getObjectId } from "#src/util/object_id.js"; +import type { ProgressOptions } from "#src/util/progress_listener.js"; import { NullarySignal } from "#src/util/signal.js"; import { withSharedVisibility } from "#src/visibility_priority/frontend.js"; import type { GL } from "#src/webgl/context.js"; @@ -159,10 +158,10 @@ function disposeTransformedSources( @registerSharedObjectOwner(SLICEVIEW_RPC_ID) export class SliceView extends Base { - gl = this.chunkManager.gl; + gl: GL; viewChanged = new NullarySignal(); - rpc: RPC; - rpcId: number; + declare rpc: RPC; + declare rpcId: number; renderingStale = true; @@ -170,22 +169,17 @@ export class SliceView extends Base { visibleLayerList = new Array(); - visibleLayers: Map; + declare visibleLayers: Map; - offscreenFramebuffer = this.registerDisposer( - new FramebufferConfiguration(this.gl, { - colorBuffers: makeTextureBuffers(this.gl, 1), - depthBuffer: new DepthTextureBuffer(this.gl), - }), - ); + offscreenFramebuffer; histogramInputTextures: TextureBuffer[] = []; - offscreenFramebuffersWithHistograms = [this.offscreenFramebuffer]; + offscreenFramebuffersWithHistograms; get displayDimensionRenderInfo() { return this.navigationState.displayDimensionRenderInfo; } - private histogramGenerator = TextureHistogramGenerator.get(this.gl); + private histogramGenerator: TextureHistogramGenerator; computeHistograms( count: number, @@ -200,7 +194,7 @@ export class SliceView extends Base { ); } - projectionParameters: Owned< + declare projectionParameters: Owned< DerivedProjectionParameters >; @@ -276,6 +270,17 @@ export class SliceView extends Base { }, }), ); + this.gl = chunkManager.gl; + + this.offscreenFramebuffer = this.registerDisposer( + new FramebufferConfiguration(this.gl, { + colorBuffers: makeTextureBuffers(this.gl, 1), + depthBuffer: new DepthTextureBuffer(this.gl), + }), + ); + this.offscreenFramebuffersWithHistograms = [this.offscreenFramebuffer]; + this.histogramGenerator = TextureHistogramGenerator.get(this.gl); + this.registerDisposer(navigationState); this.registerDisposer(this.projectionParameters); this.registerDisposer( @@ -408,7 +413,6 @@ export class SliceView extends Base { const { visibleLayers, visibleLayerList } = this; const { displayDimensionRenderInfo } = this.projectionParameters.value; const rpc = this.rpc!; - const rpcMessage: any = { id: this.rpcId }; let changed = false; visibleLayerList.length = 0; for (const renderLayer of this.layerManager.readyRenderLayers()) { @@ -449,20 +453,22 @@ export class SliceView extends Base { layerInfo.displayDimensionRenderInfo = displayDimensionRenderInfo; layerInfo.transformGeneration = curTransformGeneration; } - rpcMessage.layerId = renderLayer.rpcId; - rpcMessage.sources = serializeAllTransformedSources( - layerInfo.allSources, - ); - rpcMessage.displayDimensionRenderInfo = displayDimensionRenderInfo; this.flushBackendProjectionParameters(); - rpc.invoke(SLICEVIEW_ADD_VISIBLE_LAYER_RPC_ID, rpcMessage); + rpc.invoke(SLICEVIEW_ADD_VISIBLE_LAYER_RPC_ID, { + id: this.rpcId, + layerId: renderLayer.rpcId, + sources: serializeAllTransformedSources(layerInfo.allSources), + displayDimensionRenderInfo: displayDimensionRenderInfo, + }); changed = true; } } for (const [renderLayer, layerInfo] of visibleLayers) { if (layerInfo.lastSeenGeneration === curUpdateGeneration) continue; - rpcMessage.layerId = renderLayer.rpcId; - rpc.invoke(SLICEVIEW_REMOVE_VISIBLE_LAYER_RPC_ID, rpcMessage); + rpc.invoke(SLICEVIEW_REMOVE_VISIBLE_LAYER_RPC_ID, { + id: this.rpcId, + layerId: renderLayer.rpcId, + }); visibleLayers.delete(renderLayer); disposeTransformedSources(renderLayer, layerInfo.allSources); invokeDisposers(layerInfo.disposers); @@ -605,9 +611,9 @@ export abstract class SliceViewChunkSource< extends ChunkSource implements SliceViewChunkSourceInterface { - chunks: Map; + declare chunks: Map; - OPTIONS: SliceViewChunkSourceOptions; + declare OPTIONS: SliceViewChunkSourceOptions; spec: Spec; @@ -646,7 +652,7 @@ export abstract class SliceViewChunkSource< async fetchChunk( chunkGridPosition: Float32Array, transform: (chunk: Chunk) => T, - cancellationToken: CancellationToken = uncancelableToken, + progressOptions: Partial, ): Promise { const key = chunkGridPosition.join(); const existingChunk = this.chunks.get(key); @@ -675,7 +681,7 @@ export abstract class SliceViewChunkSource< await this.rpc!.promiseInvoke( SLICEVIEW_REQUEST_CHUNK_RPC_ID, { source: this.rpcId, chunkGridPosition }, - cancellationToken, + progressOptions, ); return await promise; } finally { @@ -701,7 +707,7 @@ export interface SliceViewChunkSource { export class SliceViewChunk extends Chunk { chunkGridPosition: vec3; - source: SliceViewChunkSource; + declare source: SliceViewChunkSource; constructor(source: SliceViewChunkSource, x: any) { super(source); @@ -714,7 +720,7 @@ export class SliceViewChunk extends Chunk { * Helper for rendering a SliceView that has been pre-rendered to a texture. */ export class SliceViewRenderHelper extends RefCounted { - private copyVertexPositionsBuffer = getSquareCornersBuffer(this.gl); + private copyVertexPositionsBuffer; private shader: ShaderProgram; private textureCoordinateAdjustment = new Float32Array(4); @@ -724,6 +730,8 @@ export class SliceViewRenderHelper extends RefCounted { emitter: ShaderModule, ) { super(); + this.copyVertexPositionsBuffer = getSquareCornersBuffer(this.gl); + const builder = new ShaderBuilder(gl); builder.addVarying("vec2", "vTexCoord"); builder.addUniform("sampler2D", "uSampler"); diff --git a/src/sliceview/jxl/.dockerignore b/src/sliceview/jxl/.dockerignore new file mode 100644 index 0000000000..91224e5de8 --- /dev/null +++ b/src/sliceview/jxl/.dockerignore @@ -0,0 +1 @@ +**/* diff --git a/src/sliceview/jxl/Cargo.lock b/src/sliceview/jxl/Cargo.lock new file mode 100644 index 0000000000..da9ebff216 --- /dev/null +++ b/src/sliceview/jxl/Cargo.lock @@ -0,0 +1,233 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "crossbeam-deque" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" + +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" + +[[package]] +name = "jxl-bitstream" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5855ff16398ffbcf81fee52c41ca65326499c8764b21bb9952c367ace98995fb" +dependencies = [ + "tracing", +] + +[[package]] +name = "jxl-coding" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da5b5093904e940bc11ef50e872c7bdf7b6e88653f012b925f8479daf212b5c9" +dependencies = [ + "jxl-bitstream", + "tracing", +] + +[[package]] +name = "jxl-color" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8ec11695f2091e50531c970ad7eb4819989a20a2c89d68ae1b4f74f48454c10" +dependencies = [ + "jxl-bitstream", + "jxl-coding", + "jxl-grid", + "jxl-threadpool", + "tracing", +] + +[[package]] +name = "jxl-frame" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4719f285ebfff5e64f352d0ef149a5244aef4f8e6b5aa666ba6241e90b50632f" +dependencies = [ + "jxl-bitstream", + "jxl-coding", + "jxl-grid", + "jxl-image", + "jxl-modular", + "jxl-threadpool", + "jxl-vardct", + "tracing", +] + +[[package]] +name = "jxl-grid" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13a28ba2734da33624db4b426b44750a7b1238e6cba65d27b7d84bf3cba7f507" +dependencies = [ + "tracing", +] + +[[package]] +name = "jxl-image" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3824c81613c05c19a9e4329d569145d3f460c0fcadb3965bd8418162d43f7f4" +dependencies = [ + "jxl-bitstream", + "jxl-color", + "jxl-grid", + "tracing", +] + +[[package]] +name = "jxl-modular" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7e10bbc6041d9ea64bcfc6931ed89f0192954ac0a02bdbad624aa43b345e613" +dependencies = [ + "jxl-bitstream", + "jxl-coding", + "jxl-grid", + "jxl-threadpool", + "tracing", +] + +[[package]] +name = "jxl-oxide" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71f3b9dbe4adefadac57b25a15bf7735202ba58c0e5500c6bfb2d63398bf21c2" +dependencies = [ + "jxl-bitstream", + "jxl-color", + "jxl-frame", + "jxl-grid", + "jxl-image", + "jxl-render", + "jxl-threadpool", + "tracing", +] + +[[package]] +name = "jxl-render" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4259446ca029587f2b7850d223d57b4f69665dd8628e83bcb0a6c2ab964f1ef" +dependencies = [ + "jxl-bitstream", + "jxl-coding", + "jxl-color", + "jxl-frame", + "jxl-grid", + "jxl-image", + "jxl-modular", + "jxl-threadpool", + "jxl-vardct", + "tracing", +] + +[[package]] +name = "jxl-threadpool" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d2860c68899a3c6266044fc26c6a0041e9f27145f58cc69b6eedc1b77f5ee13" +dependencies = [ + "rayon", + "rayon-core", + "tracing", +] + +[[package]] +name = "jxl-vardct" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15da4b49b832b3d8a67329f47e2a1732e0847667938bb9b4a37d99a4668775c2" +dependencies = [ + "jxl-bitstream", + "jxl-coding", + "jxl-grid", + "jxl-modular", + "jxl-threadpool", + "tracing", +] + +[[package]] +name = "jxl-wasm" +version = "1.0.0" +dependencies = [ + "jxl-oxide", +] + +[[package]] +name = "once_cell" +version = "1.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" + +[[package]] +name = "pin-project-lite" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" + +[[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" +dependencies = [ + "once_cell", +] diff --git a/src/sliceview/jxl/Dockerfile b/src/sliceview/jxl/Dockerfile index d7adaf55da..9eec36fe24 100644 --- a/src/sliceview/jxl/Dockerfile +++ b/src/sliceview/jxl/Dockerfile @@ -1,4 +1,4 @@ -FROM rust:slim-bullseye +FROM rust:slim-bullseye@sha256:46bad2a122975b3d3f7443e137015e0567bc4c63e467a818d9b92517def5f4d6 RUN rustup target add wasm32-unknown-unknown diff --git a/src/sliceview/jxl/jxl_decoder.wasm b/src/sliceview/jxl/jxl_decoder.wasm index d5c3b161c4..c1dedd52f5 100755 Binary files a/src/sliceview/jxl/jxl_decoder.wasm and b/src/sliceview/jxl/jxl_decoder.wasm differ diff --git a/src/sliceview/panel.ts b/src/sliceview/panel.ts index 172ee6f253..d92c94df94 100644 --- a/src/sliceview/panel.ts +++ b/src/sliceview/panel.ts @@ -100,7 +100,7 @@ const tempVec3b = vec3.create(); const tempVec4 = vec4.create(); export class SliceViewPanel extends RenderedDataPanel { - viewer: SliceViewerState; + declare viewer: SliceViewerState; private axesLineHelper = this.registerDisposer(AxesLineHelper.get(this.gl)); private sliceViewRenderHelper = this.registerDisposer( diff --git a/src/sliceview/png/index.ts b/src/sliceview/png/index.ts index c138aca232..19f039657e 100644 --- a/src/sliceview/png/index.ts +++ b/src/sliceview/png/index.ts @@ -15,6 +15,7 @@ */ import type { DecodedImage } from "#src/async_computation/decode_png_request.js"; +import { transposeArray2d } from "#src/util/array.js"; const libraryEnv = { emscripten_notify_memory_growth: () => {}, @@ -160,7 +161,7 @@ function readHeader(buffer: Uint8Array): { `png: invalid bit depth for grayscale + alpha channel colorspace. Got: ${bitDepth}`, ); } - numChannels = 4; + numChannels = 2; } else { throw new Error(`png: Invalid color space: ${colorSpace}`); } @@ -232,11 +233,16 @@ export async function decompressPng( // Likewise, we reference memory.buffer instead of heap.buffer // because memory growth during decompress could have detached // the buffer. - const image = new Uint8Array( + let image = new Uint8Array( (m.exports.memory as WebAssembly.Memory).buffer, imagePtr, nbytes, ); + + if (numChannels !== 1) { + image = transposeArray2d(image, sx * sy, numChannels); + } + // copy the array so it can be memory managed by JS // and we can free the emscripten buffer return { diff --git a/src/sliceview/renderlayer.ts b/src/sliceview/renderlayer.ts index ad52ba48c1..61c4b2aa57 100644 --- a/src/sliceview/renderlayer.ts +++ b/src/sliceview/renderlayer.ts @@ -52,7 +52,7 @@ import { constantWatchableValue } from "#src/trackable_value.js"; import type { Borrowed } from "#src/util/disposable.js"; import { HistogramSpecifications } from "#src/webgl/empirical_cdf.js"; import type { ShaderModule } from "#src/webgl/shader.js"; -import type { RpcId, SharedObject } from "#src/worker_rpc.js"; +import type { RpcId } from "#src/worker_rpc.js"; export interface SliceViewRenderLayerOptions { /** @@ -202,7 +202,7 @@ export abstract class SliceViewRenderLayer< ); } - RPC_TYPE_ID: string; + declare RPC_TYPE_ID: string; initializeCounterpart() { const sharedObject = this.registerDisposer( @@ -292,6 +292,4 @@ export class SliceViewPanelRenderLayer< attachment; return true; } - - backend: SharedObject | undefined; } diff --git a/src/sliceview/single_texture_chunk_format.ts b/src/sliceview/single_texture_chunk_format.ts index 4fe03f2737..53468aedfd 100644 --- a/src/sliceview/single_texture_chunk_format.ts +++ b/src/sliceview/single_texture_chunk_format.ts @@ -126,7 +126,7 @@ export abstract class SingleTextureVolumeChunk< texture: WebGLTexture | null = null; data: Data | null; textureLayout: TextureLayout | null; - CHUNK_FORMAT_TYPE: SingleTextureChunkFormat; + declare CHUNK_FORMAT_TYPE: SingleTextureChunkFormat; constructor(source: VolumeChunkSource, x: any) { super(source, x); diff --git a/src/sliceview/uncompressed_chunk_format.browser_test.ts b/src/sliceview/uncompressed_chunk_format.browser_test.ts index 2ee2ade407..132bfa6940 100644 --- a/src/sliceview/uncompressed_chunk_format.browser_test.ts +++ b/src/sliceview/uncompressed_chunk_format.browser_test.ts @@ -59,7 +59,7 @@ describe("sliceview/uncompressed_chunk_format", () => { ]) { const numElements = prod4(volumeSize); for (const [dataType, arrayConstructor] of < - [DataType, TypedArrayConstructor][] + [DataType, TypedArrayConstructor][] >[ [DataType.UINT8, Uint8Array], [DataType.UINT16, Uint16Array], diff --git a/src/sliceview/uncompressed_chunk_format.ts b/src/sliceview/uncompressed_chunk_format.ts index 440e6c28df..e4fc7409ea 100644 --- a/src/sliceview/uncompressed_chunk_format.ts +++ b/src/sliceview/uncompressed_chunk_format.ts @@ -51,7 +51,7 @@ import { class TextureLayout extends RefCounted { strides: Uint32Array; - textureShape = new Uint32Array(this.textureDims); + textureShape: Uint32Array; constructor( gl: GL, public chunkDataSize: Uint32Array, @@ -68,7 +68,9 @@ class TextureLayout extends RefCounted { textureDims === 3 ? gl.max3dTextureSize : gl.maxTextureSize; let textureDim = 0; let textureDimSize = 1; - const { textureShape } = this; + const textureShape = (this.textureShape = new Uint32Array( + this.textureDims, + )); textureShape.fill(1); for (let chunkDim = 0; chunkDim < rank; ++chunkDim) { const size = chunkDataSize[chunkDim]; @@ -284,8 +286,8 @@ export class UncompressedVolumeChunk extends SingleTextureVolumeChunk< Uint8Array, TextureLayout > { - CHUNK_FORMAT_TYPE: ChunkFormat; - source: Source; + declare CHUNK_FORMAT_TYPE: ChunkFormat; + declare source: Source; setTextureData(gl: GL) { const { source } = this; @@ -346,7 +348,9 @@ export function getFillValueArray( dataType: DataType, fillValue: number | Uint64, ) { - const array = new DATA_TYPE_ARRAY_CONSTRUCTOR[dataType]( + const array = new (DATA_TYPE_ARRAY_CONSTRUCTOR[ + dataType + ] as TypedArrayConstructor)( DATA_TYPE_JAVASCRIPT_ELEMENTS_PER_ARRAY_ELEMENT[dataType], ); if (dataType === DataType.UINT64) { diff --git a/src/sliceview/volume/backend.ts b/src/sliceview/volume/backend.ts index 5fe4b79d01..4c7c39b8de 100644 --- a/src/sliceview/volume/backend.ts +++ b/src/sliceview/volume/backend.ts @@ -142,7 +142,7 @@ export class VolumeChunkSource extends SliceViewChunkSourceBackend implements VolumeChunkSourceInterface { - spec: VolumeChunkSpecification; + declare spec: VolumeChunkSpecification; tempChunkDataSize: Uint32Array; tempChunkPosition: Float32Array; constructor(rpc: RPC, options: any) { diff --git a/src/sliceview/volume/frontend.ts b/src/sliceview/volume/frontend.ts index dea825db88..a373b5644a 100644 --- a/src/sliceview/volume/frontend.ts +++ b/src/sliceview/volume/frontend.ts @@ -268,9 +268,9 @@ export class VolumeChunkSource } export abstract class VolumeChunk extends SliceViewChunk { - source: VolumeChunkSource; + declare source: VolumeChunkSource; chunkDataSize: Uint32Array; - CHUNK_FORMAT_TYPE: ChunkFormat; + declare CHUNK_FORMAT_TYPE: ChunkFormat; get chunkFormat(): this["CHUNK_FORMAT_TYPE"] { return this.source.chunkFormat; diff --git a/src/sliceview/volume/renderlayer.ts b/src/sliceview/volume/renderlayer.ts index a01325eb1a..178719f264 100644 --- a/src/sliceview/volume/renderlayer.ts +++ b/src/sliceview/volume/renderlayer.ts @@ -333,7 +333,7 @@ interface ShaderContext { export abstract class SliceViewVolumeRenderLayer< ShaderParameters = any, > extends SliceViewRenderLayer { - multiscaleSource: MultiscaleVolumeChunkSource; + declare multiscaleSource: MultiscaleVolumeChunkSource; protected shaderGetter: ParameterizedContextDependentShaderGetter< { chunkFormat: ChunkFormat | null; dataHistogramsEnabled: boolean }, ShaderParameters, diff --git a/src/sliceview/volume/segmentation_renderlayer.ts b/src/sliceview/volume/segmentation_renderlayer.ts index df09948c83..d2da8376fe 100644 --- a/src/sliceview/volume/segmentation_renderlayer.ts +++ b/src/sliceview/volume/segmentation_renderlayer.ts @@ -25,7 +25,10 @@ import { SegmentStatedColorShaderManager, } from "#src/segment_color.js"; import { getVisibleSegments } from "#src/segmentation_display_state/base.js"; -import type { SegmentationDisplayState } from "#src/segmentation_display_state/frontend.js"; +import type { + SegmentationDisplayState, + SegmentationGroupState, +} from "#src/segmentation_display_state/frontend.js"; import { registerRedrawWhenSegmentationDisplayStateChanged } from "#src/segmentation_display_state/frontend.js"; import type { SliceViewSourceOptions } from "#src/sliceview/base.js"; import type { @@ -88,8 +91,7 @@ const HAS_SELECTED_SEGMENT_FLAG = 1; const SHOW_ALL_SEGMENTS_FLAG = 2; export class SegmentationRenderLayer extends SliceViewVolumeRenderLayer { - public readonly segmentationGroupState = - this.displayState.segmentationGroupState.value; + public readonly segmentationGroupState: SegmentationGroupState; protected segmentColorShaderManager = new SegmentColorShaderManager( "segmentColorHash", ); @@ -99,29 +101,13 @@ export class SegmentationRenderLayer extends SliceViewVolumeRenderLayer | undefined; private hashTableManager = new HashSetShaderManager("visibleSegments"); - private gpuHashTable = this.registerDisposer( - GPUHashTable.get( - this.gl, - this.segmentationGroupState.visibleSegments.hashTable, - ), - ); - private gpuTemporaryHashTable = GPUHashTable.get( - this.gl, - this.segmentationGroupState.temporaryVisibleSegments.hashTable, - ); + private gpuHashTable; + private gpuTemporaryHashTable; private equivalencesShaderManager = new HashMapShaderManager("equivalences"); - private equivalencesHashMap = new EquivalencesHashMap( - this.segmentationGroupState.segmentEquivalences.disjointSets, - ); - private temporaryEquivalencesHashMap = new EquivalencesHashMap( - this.segmentationGroupState.temporarySegmentEquivalences.disjointSets, - ); - private gpuEquivalencesHashTable = this.registerDisposer( - GPUHashTable.get(this.gl, this.equivalencesHashMap.hashMap), - ); - private gpuTemporaryEquivalencesHashTable = this.registerDisposer( - GPUHashTable.get(this.gl, this.temporaryEquivalencesHashMap.hashMap), - ); + private equivalencesHashMap; + private temporaryEquivalencesHashMap; + private gpuEquivalencesHashTable; + private gpuTemporaryEquivalencesHashTable; constructor( multiscaleSource: MultiscaleVolumeChunkSource, @@ -183,6 +169,30 @@ export class SegmentationRenderLayer extends SliceViewVolumeRenderLayer, ); diff --git a/src/status.css b/src/status.css index b0d7b9c850..bf4ab50873 100644 --- a/src/status.css +++ b/src/status.css @@ -14,7 +14,7 @@ * limitations under the License. */ -#statusContainer { +#neuroglancer-status-container { position: absolute; bottom: 0px; z-index: 100; @@ -25,7 +25,7 @@ font: 10pt sans-serif; } -#statusContainer li { +#neuroglancer-status-container li { width: 100vw; max-height: 25vh; overflow-y: auto; @@ -39,7 +39,7 @@ padding: 2px; } -#statusContainerModal { +#neuroglancer-status-container-modal { pointer-events: none; position: absolute; z-index: 100; @@ -57,15 +57,16 @@ grid-row-gap: 10px; } -#statusContainerModal > div { +#neuroglancer-status-container-modal > div { pointer-events: initial; position: relative; background-color: #808080; padding: 20px; padding-top: 30px; + border: 1px solid white; } -#statusContainerModal > div > div:first-child { +#neuroglancer-status-container-modal > div > div:first-child { position: absolute; top: 4px; right: 4px; @@ -73,6 +74,6 @@ padding: 0; } -#statusContainerModal li { +#neuroglancer-status-container-modal li { display: block; } diff --git a/src/status.ts b/src/status.ts index 519df57449..2507cdc6f4 100644 --- a/src/status.ts +++ b/src/status.ts @@ -18,88 +18,88 @@ import "#src/status.css"; import { makeCloseButton } from "#src/widget/close_button.js"; -let statusContainer: HTMLElement | null = null; -let modalStatusContainer: HTMLElement | null = null; +let statusContainer: HTMLElement | undefined; +let modalStatusContainer: HTMLElement | undefined; + +// Exported for use by #tests/fixtures/status_message_handler.js +export const statusMessages = new Set(); export const DEFAULT_STATUS_DELAY = 200; export type Delay = boolean | number; +function getStatusContainer() { + if (statusContainer === undefined) { + statusContainer = document.createElement("ul"); + statusContainer.id = "neuroglancer-status-container"; + const el: HTMLElement | null = document.getElementById( + "neuroglancer-container", + ); + if (el) { + el.appendChild(statusContainer); + } else { + document.body.appendChild(statusContainer); + } + } + return statusContainer; +} + +function getModalStatusContainer() { + if (modalStatusContainer === undefined) { + modalStatusContainer = document.createElement("ul"); + modalStatusContainer.id = "neuroglancer-status-container-modal"; + const el: HTMLElement | null = document.getElementById( + "neuroglancer-container", + ); + if (el) { + el.appendChild(modalStatusContainer); + } else { + document.body.appendChild(modalStatusContainer); + } + } + return modalStatusContainer; +} + +// For use by #tests/fixtures/status_message_handler.js +export function getStatusMessageContainers() { + return [getStatusContainer(), getModalStatusContainer()]; +} + export class StatusMessage { element: HTMLElement; - modalElementWrapper: HTMLElement | undefined; + private modalElementWrapper: HTMLElement | undefined; private timer: number | null; + private visibility = true; constructor(delay: Delay = false, modal = false) { - if (statusContainer === null) { - statusContainer = document.createElement("ul"); - statusContainer.id = "statusContainer"; - const el: HTMLElement | null = document.getElementById( - "neuroglancer-container", - ); - if (el) { - el.appendChild(statusContainer); - } else { - document.body.appendChild(statusContainer); - } - } - if (modal && modalStatusContainer === null) { - modalStatusContainer = document.createElement("ul"); - modalStatusContainer.id = "statusContainerModal"; - const el: HTMLElement | null = document.getElementById( - "neuroglancer-container", - ); - if (el) { - el.appendChild(modalStatusContainer); - } else { - document.body.appendChild(modalStatusContainer); - } - } const element = document.createElement("li"); this.element = element; if (delay === true) { delay = DEFAULT_STATUS_DELAY; } + this.setModal(modal); if (delay !== false) { this.setVisible(false); this.timer = window.setTimeout(this.setVisible.bind(this, true), delay); } else { this.timer = null; } - if (modal) { - const modalElementWrapper = document.createElement("div"); - const dismissModalElement = makeCloseButton({ - title: "Dismiss", - onClick: () => { - this.dismissModal(); - }, - }); - dismissModalElement.classList.add("dismiss-modal"); - dismissModalElement.addEventListener("click", () => this.dismissModal()); - modalElementWrapper.appendChild(dismissModalElement); - modalElementWrapper.appendChild(element); - this.modalElementWrapper = modalElementWrapper; - modalStatusContainer!.appendChild(modalElementWrapper); - } else { - statusContainer.appendChild(element); - } + statusMessages.add(this); } + + [Symbol.dispose]() { + this.dispose(); + } + dispose() { if (this.modalElementWrapper) { modalStatusContainer!.removeChild(this.modalElementWrapper); } else { statusContainer!.removeChild(this.element); } - this.element = undefined; if (this.timer !== null) { clearTimeout(this.timer); } - } - dismissModal() { - if (this.modalElementWrapper) { - modalStatusContainer!.removeChild(this.modalElementWrapper); - this.modalElementWrapper = undefined; - statusContainer!.appendChild(this.element); - } + statusMessages.delete(this); } setText(text: string, makeVisible?: boolean) { this.element.textContent = text; @@ -113,12 +113,52 @@ export class StatusMessage { this.setVisible(true); } } + setModal(value: boolean) { + if (value) { + if (this.modalElementWrapper === undefined) { + const modalElementWrapper = document.createElement("div"); + const dismissModalElement = makeCloseButton({ + title: "Dismiss", + onClick: () => { + this.setModal(false); + }, + }); + dismissModalElement.classList.add("neuroglancer-dismiss-modal"); + modalElementWrapper.appendChild(dismissModalElement); + modalElementWrapper.appendChild(this.element); + this.modalElementWrapper = modalElementWrapper; + this.applyVisibility(); + getModalStatusContainer().appendChild(modalElementWrapper); + } + } else { + if (this.modalElementWrapper !== undefined) { + modalStatusContainer!.removeChild(this.modalElementWrapper); + this.modalElementWrapper = undefined; + getStatusContainer().appendChild(this.element); + } else if (this.element.parentElement === null) { + getStatusContainer().appendChild(this.element); + } + } + } + + private applyVisibility() { + const newVisibility = this.visibility ? "" : "none"; + this.element.style.display = newVisibility; + const { modalElementWrapper } = this; + if (modalElementWrapper !== undefined) { + modalElementWrapper.style.display = newVisibility; + } + } + setVisible(value: boolean) { if (this.timer !== null) { clearTimeout(this.timer); this.timer = null; } - this.element.style.display = value ? "block" : "none"; + if (value !== this.visibility) { + this.visibility = value; + this.applyVisibility(); + } } static forPromise( diff --git a/src/third_party/codemirror-glsl.ts b/src/third_party/codemirror-glsl.ts new file mode 100644 index 0000000000..22271a5e6a --- /dev/null +++ b/src/third_party/codemirror-glsl.ts @@ -0,0 +1,260 @@ +// The following code is derived from https://github.com/hughsk/glsl-editor by +// Hugh Kennedy , subject to the license listed below. +// +// This is a conversion of the original CommonJS module to TypeScript and ESM format. +// +// This software is released under the MIT license: +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +import type CodeMirrorModule from "codemirror"; +import type { EditorConfiguration, Mode, StringStream } from "codemirror"; + +interface Tokenize { + (stream: StringStream, state: State): string; +} + +interface State { + tokenize: Tokenize | null; + context: Context; + indented: number; + startOfLine: boolean; +} + +class Context { + constructor( + public indented: number, + public column: number, + public type: string, + public align: boolean | null, + public prev: Context | undefined = undefined, + ) {} +} + +function glslMode(config: EditorConfiguration, parserConfig: any): Mode { + const indentUnit = config.indentUnit!, + keywords = parserConfig.keywords || words(glslKeywords), + builtins = parserConfig.builtins || words(glslBuiltins), + blockKeywords = + parserConfig.blockKeywords || + words("case do else for if switch while struct"), + atoms = parserConfig.atoms || words("null"), + hooks = parserConfig.hooks || {}, + multiLineStrings = parserConfig.multiLineStrings; + const isOperatorChar = /[+\-*&%=<>!?|/]/; + + let curPunc; + + function tokenBase(stream: StringStream, state: State): string { + const ch = stream.next()!; + if (hooks[ch]) { + const result = hooks[ch](stream, state); + if (result !== false) return result; + } + if (ch == '"' || ch == "'") { + state.tokenize = tokenString(ch); + return state.tokenize(stream, state); + } + if (/[[\]{}(),;:.]/.test(ch)) { + curPunc = ch; + return "bracket"; + } + if (/\d/.test(ch)) { + stream.eatWhile(/[\w.]/); + return "number"; + } + if (ch == "/") { + if (stream.eat("*")) { + state.tokenize = tokenComment; + return tokenComment(stream, state); + } + if (stream.eat("/")) { + stream.skipToEnd(); + return "comment"; + } + } + if (ch == "#") { + stream.eatWhile(/[\S]+/); + stream.eatWhile(/[\s]+/); + stream.eatWhile(/[\S]+/); + stream.eatWhile(/[\s]+/); + return "comment"; + } + if (isOperatorChar.test(ch)) { + stream.eatWhile(isOperatorChar); + return "operator"; + } + stream.eatWhile(/[\w$_]/); + const cur = stream.current(); + if (Object.hasOwn(keywords, cur)) { + if (Object.hasOwn(blockKeywords, cur)) curPunc = "newstatement"; + return "keyword"; + } + if (Object.hasOwn(builtins, cur)) { + return "builtin"; + } + if (Object.hasOwn(atoms, cur)) return "atom"; + return "word"; + } + + function tokenString(quote: string): Tokenize { + return function (stream: StringStream, state: State) { + let escaped = false, + next, + end = false; + while ((next = stream.next()) != null) { + if (next == quote && !escaped) { + end = true; + break; + } + escaped = !escaped && next == "\\"; + } + if (end || !(escaped || multiLineStrings)) state.tokenize = tokenBase; + return "string"; + }; + } + + function tokenComment(stream: StringStream, state: State): string { + let maybeEnd = false, + ch; + while ((ch = stream.next())) { + if (ch == "/" && maybeEnd) { + state.tokenize = tokenBase; + break; + } + maybeEnd = ch == "*"; + } + return "comment"; + } + + function pushContext(state: State, col: number, type: string) { + return (state.context = new Context( + state.indented, + col, + type, + null, + state.context, + )); + } + function popContext(state: State): Context { + const t = state.context.type; + if (t == ")" || t == "]" || t == "}") + state.indented = state.context.indented; + return (state.context = state.context.prev!); + } + + // Interface + + return { + startState: function (basecolumn?: number): State { + return { + tokenize: null, + context: new Context((basecolumn || 0) - indentUnit, 0, "top", false), + indented: 0, + startOfLine: true, + }; + }, + + token: function (stream: StringStream, state: State) { + let ctx = state.context; + if (stream.sol()) { + if (ctx.align == null) ctx.align = false; + state.indented = stream.indentation(); + state.startOfLine = true; + } + if (stream.eatSpace()) return null; + curPunc = null; + const style = (state.tokenize || tokenBase)(stream, state); + if (style == "comment" || style == "meta") return style; + if (ctx.align == null) ctx.align = true; + + if ((curPunc == ";" || curPunc == ":") && ctx.type == "statement") + popContext(state); + else if (curPunc == "{") pushContext(state, stream.column(), "}"); + else if (curPunc == "[") pushContext(state, stream.column(), "]"); + else if (curPunc == "(") pushContext(state, stream.column(), ")"); + else if (curPunc == "}") { + while (ctx.type == "statement") ctx = popContext(state); + if (ctx.type == "}") ctx = popContext(state); + while (ctx.type == "statement") ctx = popContext(state); + } else if (curPunc == ctx.type) popContext(state); + else if ( + ctx.type == "}" || + ctx.type == "top" || + (ctx.type == "statement" && curPunc == "newstatement") + ) + pushContext(state, stream.column(), "statement"); + state.startOfLine = false; + return style; + }, + + indent: function (state: State, textAfter: string) { + if (state.tokenize != tokenBase && state.tokenize != null) return 0; + const firstChar = textAfter && textAfter.charAt(0), + ctx = state.context, + closing = firstChar == ctx.type; + if (ctx.type == "statement") + return ctx.indented + (firstChar == "{" ? 0 : indentUnit); + else if (ctx.align) return ctx.column + (closing ? 0 : 1); + else return ctx.indented + (closing ? 0 : indentUnit); + }, + + electricChars: "{}", + }; +} + +function words(str: string): Record { + const obj: Record = {}, + words = str.split(" "); + for (let i = 0; i < words.length; ++i) obj[words[i]] = true; + return obj; +} + +const glslKeywords = + "attribute const uniform varying break continue " + + "do for while if else in out inout float int void bool true false " + + "lowp mediump highp precision invariant discard return mat2 mat3 " + + "mat4 vec2 vec3 vec4 ivec2 ivec3 ivec4 bvec2 bvec3 bvec4 sampler2D " + + "samplerCube struct gl_FragCoord gl_FragColor"; +const glslBuiltins = + "radians degrees sin cos tan asin acos atan pow " + + "exp log exp2 log2 sqrt inversesqrt abs sign floor ceil fract mod " + + "min max clamp mix step smoothstep length distance dot cross " + + "normalize faceforward reflect refract matrixCompMult lessThan " + + "lessThanEqual greaterThan greaterThanEqual equal notEqual any all " + + "not dFdx dFdy fwidth texture2D texture2DProj texture2DLod " + + "texture2DProjLod textureCube textureCubeLod require export"; + +function cppHook(stream: any, state: any) { + if (!state.startOfLine) return false; + stream.skipToEnd(); + return "meta"; +} + +export default function (CodeMirror: typeof CodeMirrorModule) { + CodeMirror.defineMode("glsl", glslMode); + + CodeMirror.defineMIME("text/x-glsl", { + name: "glsl", + keywords: words(glslKeywords), + builtins: words(glslBuiltins), + blockKeywords: words("case do else for if switch while struct"), + atoms: words("null"), + hooks: { "#": cppHook }, + } as any); +} diff --git a/src/third_party/jpgjs/jpg.d.ts b/src/third_party/jpgjs/jpg.d.ts index 91d6ec452a..8439e8b614 100644 --- a/src/third_party/jpgjs/jpg.d.ts +++ b/src/third_party/jpgjs/jpg.d.ts @@ -23,5 +23,9 @@ export class JpegDecoder { height: number; numComponents: number; parse(data: Uint8Array): void; - getData(width: number, height: number, forceRGBOutput?: boolean): Uint8Array; + getData( + width: number, + height: number, + forceRGBOutput?: boolean, + ): Uint8Array; } diff --git a/src/trackable_boolean.ts b/src/trackable_boolean.ts index 2fd2653b49..c6bd7aefa2 100644 --- a/src/trackable_boolean.ts +++ b/src/trackable_boolean.ts @@ -109,12 +109,13 @@ export class TrackableBooleanCheckbox extends RefCounted { } export class ElementVisibilityFromTrackableBoolean extends RefCounted { - private initialDisplay = this.element.style.display; + private initialDisplay: string; constructor( public model: WatchableValueInterface, public element: HTMLElement, ) { super(); + this.initialDisplay = this.element.style.display; this.updateVisibility(); this.registerDisposer( model.changed.add( diff --git a/src/trackable_vec3.ts b/src/trackable_vec3.ts index c220858393..fe233b52af 100644 --- a/src/trackable_vec3.ts +++ b/src/trackable_vec3.ts @@ -48,7 +48,7 @@ export class TrackableVec3 implements Trackable { restoreState(x: any) { try { this.value = verify3dVec(x.split(",")); - } catch (e) { + } catch { this.value = this.defaultValue; } } diff --git a/src/ui/annotations.ts b/src/ui/annotations.ts index c799c90be6..6744105eaf 100644 --- a/src/ui/annotations.ts +++ b/src/ui/annotations.ts @@ -382,6 +382,29 @@ export class AnnotationLayerView extends Tab { ) { super(); this.element.classList.add("neuroglancer-annotation-layer-view"); + this.selectedAnnotationState = makeCachedLazyDerivedWatchableValue( + (selectionState, pin) => { + if (selectionState === undefined) return undefined; + const { layer } = this; + const layerSelectionState = selectionState.layers.find( + (s) => s.layer === layer, + )?.state; + if (layerSelectionState === undefined) return undefined; + const { annotationId } = layerSelectionState; + if (annotationId === undefined) return undefined; + const annotationLayerState = this.annotationStates.states.find( + (x) => + x.sourceIndex === layerSelectionState.annotationSourceIndex && + (layerSelectionState.annotationSubsource === undefined || + x.subsourceId === layerSelectionState.annotationSubsource), + ); + if (annotationLayerState === undefined) return undefined; + return { annotationId, annotationLayerState, pin }; + }, + layer.manager.root.selectionState, + layer.manager.root.selectionState.pin, + ); + this.registerDisposer(this.visibility.changed.add(() => this.updateView())); this.registerDisposer( this.annotationStates.changed.add(() => @@ -530,28 +553,7 @@ export class AnnotationLayerView extends Tab { } } - private selectedAnnotationState = makeCachedLazyDerivedWatchableValue( - (selectionState, pin) => { - if (selectionState === undefined) return undefined; - const { layer } = this; - const layerSelectionState = selectionState.layers.find( - (s) => s.layer === layer, - )?.state; - if (layerSelectionState === undefined) return undefined; - const { annotationId } = layerSelectionState; - if (annotationId === undefined) return undefined; - const annotationLayerState = this.annotationStates.states.find( - (x) => - x.sourceIndex === layerSelectionState.annotationSourceIndex && - (layerSelectionState.annotationSubsource === undefined || - x.subsourceId === layerSelectionState.annotationSubsource), - ); - if (annotationLayerState === undefined) return undefined; - return { annotationId, annotationLayerState, pin }; - }, - this.layer.manager.root.selectionState, - this.layer.manager.root.selectionState.pin, - ); + private selectedAnnotationState; private updateSelectionView() { const selectionState = this.selectedAnnotationState.value; @@ -967,11 +969,13 @@ export class AnnotationLayerView extends Tab { } export class AnnotationTab extends Tab { - private layerView = this.registerDisposer( - new AnnotationLayerView(this.layer, this.layer.annotationDisplayState), - ); + private layerView: AnnotationLayerView; constructor(public layer: Borrowed) { super(); + this.layerView = this.registerDisposer( + new AnnotationLayerView(layer, layer.annotationDisplayState), + ); + const { element } = this; element.classList.add("neuroglancer-annotations-tab"); element.appendChild(this.layerView.element); @@ -1008,7 +1012,7 @@ function getSelectedAssociatedSegments( } abstract class PlaceAnnotationTool extends LegacyTool { - layer: UserLayerWithAnnotations; + declare layer: UserLayerWithAnnotations; constructor(layer: UserLayerWithAnnotations, options: any) { super(layer); options; @@ -1180,7 +1184,7 @@ abstract class TwoStepAnnotationTool extends PlaceAnnotationTool { } abstract class PlaceTwoCornerAnnotationTool extends TwoStepAnnotationTool { - annotationType: + declare annotationType: | AnnotationType.LINE | AnnotationType.AXIS_ALIGNED_BOUNDING_BOX; @@ -2039,6 +2043,7 @@ export function UserLayerWithAnnotationsMixin< subsourceId: subsourceEntry.id, role, }); + this.annotationDisplayState.annotationProperties.value = []; this.addAnnotationLayerState(state, loadedSubsource); } diff --git a/src/ui/default_viewer_setup.ts b/src/ui/default_viewer_setup.ts index fc5d5aeaee..fc6bb1a406 100644 --- a/src/ui/default_viewer_setup.ts +++ b/src/ui/default_viewer_setup.ts @@ -37,7 +37,7 @@ export function setupDefaultViewer(options?: Partial) { const hashBinding = viewer.registerDisposer( new UrlHashBinding( viewer.state, - viewer.dataSourceProvider.credentialsManager, + viewer.dataSourceProvider.sharedKvStoreContext, { defaultFragment: typeof NEUROGLANCER_DEFAULT_STATE_FRAGMENT !== "undefined" diff --git a/src/ui/drag_and_drop.ts b/src/ui/drag_and_drop.ts index 715e53c590..560418d6e2 100644 --- a/src/ui/drag_and_drop.ts +++ b/src/ui/drag_and_drop.ts @@ -28,6 +28,7 @@ const dragStatusStack: { target: EventTarget; operation: DragStatusType; status: DragStatusRenderer; + leaveHandler?: () => void; }[] = []; function getStatusElement() { @@ -46,9 +47,21 @@ function clearStatus() { } } -function applyStatus(status: DragStatusRenderer) { +function applyStatus(event: MouseEvent, status: DragStatusRenderer) { const element = getStatusElement(); removeChildren(element); + if (event.clientX === 0 && event.clientY === 0) { + // Probably an invalid position due to dragging outside the window. + } else { + if (event.clientX < window.innerWidth / 2) { + element.style.left = "auto"; + element.style.right = "0px"; + } else { + element.style.right = "auto"; + element.style.left = "0px"; + } + } + if (typeof status === "string") { element.appendChild(document.createTextNode(status)); } else { @@ -58,23 +71,32 @@ function applyStatus(status: DragStatusRenderer) { } function removeDragStatus(target: EventTarget, operation: DragStatusType) { - filterArrayInplace( - dragStatusStack, - (entry) => !(entry.target === target && entry.operation === operation), - ); + filterArrayInplace(dragStatusStack, (entry) => { + if (entry.target === target && entry.operation === operation) { + entry.leaveHandler?.(); + return false; + } + return true; + }); } export function pushDragStatus( + event: MouseEvent, target: EventTarget, operation: DragStatusType, status: DragStatusRenderer, + leaveHandler?: () => void, ) { removeDragStatus(target, operation); - dragStatusStack.push({ target, operation, status }); - applyStatus(status); + dragStatusStack.push({ target, operation, status, leaveHandler }); + applyStatus(event, status); } -export function popDragStatus(target: EventTarget, operation: DragStatusType) { +export function popDragStatus( + event: MouseEvent, + target: EventTarget, + operation: DragStatusType, +) { removeDragStatus(target, operation); const entry = dragStatusStack.length === 0 @@ -83,6 +105,6 @@ export function popDragStatus(target: EventTarget, operation: DragStatusType) { if (entry === undefined) { clearStatus(); } else { - applyStatus(entry.status); + applyStatus(event, entry.status); } } diff --git a/src/ui/layer_bar.ts b/src/ui/layer_bar.ts index cb6eadeea7..711a77e400 100644 --- a/src/ui/layer_bar.ts +++ b/src/ui/layer_bar.ts @@ -183,16 +183,8 @@ export class LayerBar extends RefCounted { private valueUpdateNeeded = false; dropZone: HTMLDivElement; private layerWidgetInsertionPoint = document.createElement("div"); - private positionWidget = this.registerDisposer( - new PositionWidget( - this.viewerNavigationState.position.value, - this.manager.root.coordinateSpaceCombiner, - { - velocity: this.viewerNavigationState.velocity.velocity, - getToolBinder: () => this.layerGroupViewer.toolBinder, - }, - ), - ); + private positionWidget: PositionWidget; + /** * For use within this module only. */ @@ -226,6 +218,17 @@ export class LayerBar extends RefCounted { public showLayerHoverValues: WatchableValueInterface, ) { super(); + this.positionWidget = this.registerDisposer( + new PositionWidget( + this.viewerNavigationState.position.value, + this.manager.root.coordinateSpaceCombiner, + { + velocity: this.viewerNavigationState.velocity.velocity, + getToolBinder: () => this.layerGroupViewer.toolBinder, + }, + ), + ); + const { element, manager, selectedLayer } = this; element.className = "neuroglancer-layer-panel"; this.registerDisposer( diff --git a/src/ui/layer_data_sources_tab.css b/src/ui/layer_data_sources_tab.css index 0fa84d0b20..f72fe24c2e 100644 --- a/src/ui/layer_data_sources_tab.css +++ b/src/ui/layer_data_sources_tab.css @@ -112,3 +112,13 @@ li.neuroglancer-message-info { .neuroglancer-layer-data-sources-tab-type-detection-type { font-weight: bold; } + +.neuroglancer-layer-data-sources-tab .neuroglancer-progress { + margin: 0px; + list-style: none; + padding: 0px; +} + +.neuroglancer-layer-data-sources-tab .neuroglancer-progress > li { + color: #ccc; +} diff --git a/src/ui/layer_data_sources_tab.ts b/src/ui/layer_data_sources_tab.ts index 5174f9209b..866acd4850 100644 --- a/src/ui/layer_data_sources_tab.ts +++ b/src/ui/layer_data_sources_tab.ts @@ -19,7 +19,7 @@ */ import "#src/ui/layer_data_sources_tab.css"; -import { LocalDataSource } from "#src/datasource/index.js"; +import { LocalDataSource } from "#src/datasource/local.js"; import type { UserLayer, UserLayerConstructor } from "#src/layer/index.js"; import { changeLayerName, @@ -40,7 +40,6 @@ import type { WatchableValueInterface } from "#src/trackable_value.js"; import { WatchableValue } from "#src/trackable_value.js"; import type { DebouncedFunction } from "#src/util/animation_frame_debounce.js"; import { animationFrameDebounce } from "#src/util/animation_frame_debounce.js"; -import type { CancellationToken } from "#src/util/cancellation.js"; import { DataType } from "#src/util/data_type.js"; import type { Borrowed } from "#src/util/disposable.js"; import { RefCounted } from "#src/util/disposable.js"; @@ -51,36 +50,62 @@ import { } from "#src/util/dom.js"; import type { MessageList } from "#src/util/message_list.js"; import { MessageSeverity } from "#src/util/message_list.js"; +import type { ProgressListener } from "#src/util/progress_listener.js"; import { makeAddButton } from "#src/widget/add_button.js"; import { CoordinateSpaceTransformWidget } from "#src/widget/coordinate_transform.js"; +import type { + Completer, + SyntaxHighlighter, +} from "#src/widget/multiline_autocomplete.js"; import { AutocompleteTextInput, makeCompletionElementWithDescription, } from "#src/widget/multiline_autocomplete.js"; +import { ProgressListenerWidget } from "#src/widget/progress_listener.js"; import { Tab } from "#src/widget/tab_view.js"; +const dataSourceUrlSyntaxHighlighter: SyntaxHighlighter = { + splitPattern: /\|?[^|:/_]*(?:[:/_]+)?/g, + getSeparatorNode: (text: string) => { + if (text.startsWith("|") && text.length > 1) { + // Create an empty span with CSS class that adds `::after` node with + // content "\a". This prevents the linebreak from affecting text selection. + const node = document.createElement("span"); + node.classList.add("neuroglancer-multiline-autocomplete-linebreak"); + return node; + } else { + return document.createElement("wbr"); + } + }, +}; + class SourceUrlAutocomplete extends AutocompleteTextInput { dataSourceView: DataSourceView; dirty: WatchableValueInterface; constructor(dataSourceView: DataSourceView) { const { manager } = dataSourceView.source.layer; - const sourceCompleter = ( - value: string, - cancellationToken: CancellationToken, - ) => - manager.dataSourceProviderRegistry - .completeUrl({ + const sourceCompleter: Completer = async ( + { value }, + signal: AbortSignal, + progressListener: ProgressListener, + ) => { + const originalResult = + await manager.dataSourceProviderRegistry.completeUrl({ url: value, - chunkManager: manager.chunkManager, - cancellationToken, - }) - .then((originalResult) => ({ - completions: originalResult.completions, - makeElement: makeCompletionElementWithDescription, - offset: originalResult.offset, - showSingleResult: true, - })); - super({ completer: sourceCompleter, delay: 0 }); + signal, + progressListener, + }); + return { + ...originalResult, + makeElement: makeCompletionElementWithDescription, + showSingleResult: true, + }; + }; + super({ + completer: sourceCompleter, + syntaxHighlighter: dataSourceUrlSyntaxHighlighter, + delay: 0, + }); this.placeholder = "Data source URL"; this.dataSourceView = dataSourceView; this.element.classList.add("neuroglancer-layer-data-source-url-input"); @@ -309,14 +334,6 @@ export class DataSourceView extends RefCounted { const { source } = this; const existingSpec = source.spec; const userLayer = this.source.layer; - url = userLayer.manager.dataSourceProviderRegistry.normalizeUrl({ url }); - if (url !== urlInput.value) { - urlInput.disableCompletion(); - urlInput.setValueAndSelection(url, { - begin: url.length, - end: url.length, - }); - } urlInput.dirty.value = false; // If url is non-empty and unchanged, don't set spec, as that would trigger a reload of the // data source. If the url is empty, always set spec in order to possible remove the empty @@ -333,12 +350,14 @@ export class DataSourceView extends RefCounted { try { const newName = userLayer.manager.dataSourceProviderRegistry.suggestLayerName(url); - changeLayerName(userLayer.managedLayer, newName); + if (newName) { + changeLayerName(userLayer.managedLayer, newName); + } } catch { // Ignore errors obtaining a suggested layer name. } } - source.spec = { ...existingSpec, url }; + source.spec = { ...existingSpec, url, setManually: true }; }; urlInput.onCommit.add(updateUrlFromView); @@ -348,6 +367,12 @@ export class DataSourceView extends RefCounted { element.appendChild( this.registerDisposer(new MessagesView(source.messages)).element, ); + const progressListenerWidget = new ProgressListenerWidget(); + element.appendChild(progressListenerWidget.element); + source.progressListener.addListener(progressListenerWidget); + this.registerDisposer(() => + source.progressListener.removeListener(progressListenerWidget), + ); this.updateView(); } diff --git a/src/ui/layer_drag_and_drop.ts b/src/ui/layer_drag_and_drop.ts index fb6f87d9dc..4c3867e671 100644 --- a/src/ui/layer_drag_and_drop.ts +++ b/src/ui/layer_drag_and_drop.ts @@ -26,6 +26,7 @@ import { decodeParametersFromDragTypeList, encodeParametersAsDragType, getDropEffect, + getDropEffectFromModifiers, setDropEffect, } from "#src/util/drag_and_drop.js"; import { @@ -228,42 +229,6 @@ export class DropLayers { type LayerDropEffect = "none" | "move" | "copy" | "link"; -export function getDropEffectFromModifiers( - event: DragEvent, - defaultDropEffect: DropEffect, - moveAllowed: boolean, -): { dropEffect: DropEffect | "move" | "copy"; dropEffectMessage: string } { - let dropEffect: DropEffect | "move" | "copy"; - if (event.shiftKey) { - dropEffect = "copy"; - } else if (event.ctrlKey && moveAllowed) { - dropEffect = "move"; - } else { - dropEffect = defaultDropEffect; - } - let message = ""; - const addMessage = (msg: string) => { - if (message !== "") { - message += ", "; - } - message += msg; - }; - if (defaultDropEffect !== "none" && dropEffect !== defaultDropEffect) { - if (event.shiftKey) { - addMessage(`release SHIFT to ${defaultDropEffect}`); - } else { - addMessage(`release CONTROL to ${defaultDropEffect}`); - } - } - if (dropEffect !== "copy") { - addMessage("hold SHIFT to copy"); - } - if (dropEffect !== "move" && moveAllowed && defaultDropEffect !== "move") { - addMessage("hold CONTROL to move"); - } - return { dropEffect, dropEffectMessage: message }; -} - export function getLayerDropEffect( event: DragEvent, manager: Borrowed, @@ -523,13 +488,13 @@ export function registerLayerBarDropHandlers( if (update(event, /*updateDropEffect=*/ true) !== undefined) { event.preventDefault(); } else { - popDragStatus(panel.element, "drop"); + popDragStatus(event, panel.element, "drop"); } }); target.addEventListener("drop", (event: DragEvent) => { event.preventDefault(); panel.dragEnterCount = 0; - popDragStatus(panel.element, "drop"); + popDragStatus(event, panel.element, "drop"); const dropLayers = update(event, /*updateDropEffect=*/ false)?.dropLayers; panel.dropLayers = undefined; if (dropLayers === undefined) return; @@ -545,7 +510,7 @@ export function registerLayerBarDropHandlers( target.addEventListener("dragover", (event: DragEvent) => { const updateResult = update(event, /*updateDropEffect=*/ true); if (updateResult === undefined) { - popDragStatus(panel.element, "drop"); + popDragStatus(event, panel.element, "drop"); return; } const { dropLayers, dropEffect, dropEffectMessage } = updateResult; @@ -565,7 +530,7 @@ export function registerLayerBarDropHandlers( if (dropEffectMessage) { message += ` (${dropEffectMessage})`; } - pushDragStatus(panel.element, "drop", message); + pushDragStatus(event, panel.element, "drop", message); event.preventDefault(); event.stopPropagation(); }); @@ -580,6 +545,7 @@ export function registerLayerDragHandlers( element.draggable = true; element.addEventListener("dragstart", (event: DragEvent) => { pushDragStatus( + event, element, "drag", "Drag layer to another layer bar/panel (including in another Neuroglancer window), " + @@ -593,8 +559,8 @@ export function registerLayerDragHandlers( }); event.stopPropagation(); }); - element.addEventListener("dragend", () => { - popDragStatus(element, "drag"); + element.addEventListener("dragend", (event) => { + popDragStatus(event, element, "drag"); // This call to endLayerDrag is a no-op if a drag was completed successfully within the same // browser window, because it will already have been called by the `drop` handler. This call // has an effect only for a cancelled drag or a successful cross-browser window drag. @@ -610,9 +576,9 @@ export function registerLayerBarDragLeaveHandler(panel: LayerBarDropInterface) { panel.element.addEventListener("dragenter", () => { ++panel.dragEnterCount; }); - panel.element.addEventListener("dragleave", () => { + panel.element.addEventListener("dragleave", (event) => { if (--panel.dragEnterCount !== 0) return; - popDragStatus(panel.element, "drop"); + popDragStatus(event, panel.element, "drop"); const { dropLayers } = panel; if (dropLayers !== undefined) { destroyDropLayers(dropLayers); diff --git a/src/ui/layer_list_panel.ts b/src/ui/layer_list_panel.ts index d3251143b8..5fe9597b48 100644 --- a/src/ui/layer_list_panel.ts +++ b/src/ui/layer_list_panel.ts @@ -72,7 +72,7 @@ export class LayerListPanelState implements Trackable { } } -class LayerVisibilityWidget extends RefCounted { +export class LayerVisibilityWidget extends RefCounted { element = document.createElement("div"); constructor(public layer: ManagedUserLayer) { super(); diff --git a/src/ui/layer_side_panel.ts b/src/ui/layer_side_panel.ts index 56136d6af1..86a1536d3b 100644 --- a/src/ui/layer_side_panel.ts +++ b/src/ui/layer_side_panel.ts @@ -250,8 +250,6 @@ class LayerSidePanel extends SidePanel { handleTabElement: (id: string, element: HTMLElement) => { element.draggable = true; element.addEventListener("dragstart", (event: DragEvent) => { - event.stopPropagation(); - event.dataTransfer!.setData("neuroglancer-side-panel", ""); let message = "Drag tab to dock as new panel to the left/right/top/bottom of another panel"; const hasOtherPanel = panelState.panels.panels.find( @@ -262,7 +260,7 @@ class LayerSidePanel extends SidePanel { layer.managedLayer.name, )} panel`; } - pushDragStatus(element, "drag", message); + pushDragStatus(event, element, "drag", message); this.sidePanelManager.startDrag( { dropAsNewPanel: (location) => { @@ -271,6 +269,10 @@ class LayerSidePanel extends SidePanel { ...location, }); }, + getNewPanelDropEffect: () => ({ + description: "tab", + dropEffect: "move", + }), canDropAsTabs: (target) => { if ( target instanceof LayerSidePanel && @@ -292,8 +294,7 @@ class LayerSidePanel extends SidePanel { ); }); element.addEventListener("dragend", (event: DragEvent) => { - event; - popDragStatus(element, "drag"); + popDragStatus(event, element, "drag"); this.sidePanelManager.endDrag(); }); }, @@ -352,14 +353,15 @@ class LayerSidePanel extends SidePanel { if (!numTabs) return; element.classList.add(DRAG_OVER_CLASSNAME); pushDragStatus( + event, element, "drop", `Move ${numTabs} ${numTabs === 1 ? "tab" : "tabs"} to this panel`, ); event.preventDefault(); }); - element.addEventListener("dragleave", () => { - popDragStatus(element, "drop"); + element.addEventListener("dragleave", (event) => { + popDragStatus(event, element, "drop"); element.classList.remove(DRAG_OVER_CLASSNAME); }); element.addEventListener("dragover", (event) => { @@ -368,7 +370,7 @@ class LayerSidePanel extends SidePanel { event.preventDefault(); }); element.addEventListener("drop", (event) => { - popDragStatus(element, "drop"); + popDragStatus(event, element, "drop"); const { dragSource } = this.sidePanelManager; if (!dragSource?.canDropAsTabs?.(this)) return; element.classList.remove(DRAG_OVER_CLASSNAME); diff --git a/src/ui/layer_side_panel_state.ts b/src/ui/layer_side_panel_state.ts index 1f60e08ae9..79b8c591c3 100644 --- a/src/ui/layer_side_panel_state.ts +++ b/src/ui/layer_side_panel_state.ts @@ -47,10 +47,11 @@ export const LAYER_SIDE_PANEL_DEFAULT_LOCATION = { }; export class UserLayerSidePanelState extends RefCounted { - layer = this.panels.layer; + layer: UserLayer; location = new TrackableSidePanelLocation(LAYER_SIDE_PANEL_DEFAULT_LOCATION); constructor(public panels: UserLayerSidePanelsState) { super(); + this.layer = this.panels.layer; } initialize() { diff --git a/src/ui/segment_list.ts b/src/ui/segment_list.ts index ccadae84a4..6ae8db3592 100644 --- a/src/ui/segment_list.ts +++ b/src/ui/segment_list.ts @@ -107,7 +107,6 @@ abstract class SegmentListSource // explicit uint64 ids, and the `matches`, list, specifying the indices into the // `segmentPropertyMap` of the matching segments. explicitSegments: Uint64[] | undefined; - explicitSegmentsVisible = false; debouncedUpdate = debounce(() => this.update(), 0); @@ -136,8 +135,6 @@ abstract class SegmentListSource } class StarredSegmentsListSource extends SegmentListSource { - explicitSegmentsVisible: true; - constructor( public segmentationDisplayState: SegmentationDisplayState, public parentElement: HTMLElement, @@ -194,7 +191,6 @@ class SegmentQueryListSource extends SegmentListSource { matchStatusTextPrefix = ""; selectedSegmentsGeneration = -1; visibleSegmentsGeneration = -1; - explicitSegmentsVisible = false; get numMatches() { return this.queryResult.value?.count ?? 0; @@ -218,7 +214,7 @@ class SegmentQueryListSource extends SegmentListSource { let matchStatusTextPrefix = ""; const unconstrained = isQueryUnconstrained(queryResult.query); if (!unconstrained) { - if (this.explicitSegments !== undefined && this.explicitSegmentsVisible) { + if (this.explicitSegments !== undefined) { splices.push({ deleteCount: this.explicitSegments.length, retainCount: 0, @@ -232,7 +228,7 @@ class SegmentQueryListSource extends SegmentListSource { const { explicitIds } = queryResult; if (explicitIds !== undefined) { this.explicitSegments = explicitIds; - } else if (!this.explicitSegmentsVisible) { + } else { this.explicitSegments = undefined; } diff --git a/src/ui/segmentation_display_options_tab.ts b/src/ui/segmentation_display_options_tab.ts index a37b4339a7..b145d4a398 100644 --- a/src/ui/segmentation_display_options_tab.ts +++ b/src/ui/segmentation_display_options_tab.ts @@ -123,9 +123,12 @@ export class DisplayOptionsTab extends Tab { } class ShaderCodeOverlay extends Overlay { - codeWidget = this.registerDisposer(makeSkeletonShaderCodeWidget(this.layer)); + codeWidget: ShaderCodeWidget; constructor(public layer: SegmentationUserLayer) { super(); + this.codeWidget = this.registerDisposer( + makeSkeletonShaderCodeWidget(layer), + ); this.content.classList.add( "neuroglancer-segmentation-layer-skeleton-shader-overlay", ); diff --git a/src/ui/side_panel.ts b/src/ui/side_panel.ts index a0e9c285f7..14d97c437a 100644 --- a/src/ui/side_panel.ts +++ b/src/ui/side_panel.ts @@ -18,10 +18,15 @@ import "#src/ui/side_panel.css"; import type { DisplayContext } from "#src/display_context.js"; import { popDragStatus, pushDragStatus } from "#src/ui/drag_and_drop.js"; -import type { Side } from "#src/ui/side_panel_location.js"; +import type { Side, SidePanelLocation } from "#src/ui/side_panel_location.js"; import { TrackableSidePanelLocation } from "#src/ui/side_panel_location.js"; import { RefCounted } from "#src/util/disposable.js"; import { updateChildren } from "#src/util/dom.js"; +import { + getDropEffect, + getDropEffectFromModifiers, + setDropEffect, +} from "#src/util/drag_and_drop.js"; import { startRelativeMouseDrag } from "#src/util/mouse_drag.js"; import { Signal } from "#src/util/signal.js"; import { WatchableVisibilityPriority } from "#src/visibility_priority/frontend.js"; @@ -87,6 +92,11 @@ export class SidePanel extends RefCounted { visibility = new WatchableVisibilityPriority( WatchableVisibilityPriority.VISIBLE, ); + + getDragDropDescription() { + return "side panel"; + } + constructor( public sidePanelManager: SidePanelManager, public location: TrackableSidePanelLocation = new TrackableSidePanelLocation(), @@ -101,26 +111,55 @@ export class SidePanel extends RefCounted { setTimeout(() => { element.style.backgroundColor = ""; }, 0); - pushDragStatus(element, "drag", () => { - return document.createTextNode( - "Drag side panel to move it to the left/right/top/bottom of another panel", - ); - }); + pushDragStatus( + event, + element, + "drag", + `Drag ${this.getDragDropDescription()} to move it to the left/right/top/bottom of another panel`, + ); }); element.addEventListener("dragend", (event: DragEvent) => { - event; this.sidePanelManager.endDrag(); - popDragStatus(element, "drag"); + popDragStatus(event, element, "drag"); }); } + canCopy() { + return false; + } + + copyToNewLocation(location: SidePanelLocation) { + location; + } + makeDragSource(): DragSource { return { - dropAsNewPanel: (location) => { + dropAsNewPanel: (location, dropEffect) => { const oldLocation = this.location.value; - this.location.value = { ...oldLocation, ...location }; + const newLocation: SidePanelLocation = { ...oldLocation, ...location }; + console.log({ oldLocation, newLocation }); + if (dropEffect === "copy") { + this.copyToNewLocation(newLocation); + return; + } + this.location.value = newLocation; this.location.locationChanged.dispatch(); }, + getNewPanelDropEffect: (event) => { + const description = this.getDragDropDescription(); + if (this.canCopy()) { + const result = getDropEffectFromModifiers( + event, + /*defaultDropEffect=*/ "move", + /*moveAllowed=*/ true, + ); + return { + description, + ...result, + }; + } + return { description, dropEffect: "move" }; + }, }; } @@ -193,7 +232,16 @@ export interface SidePanelDropLocation { export interface DragSource { canDropAsTabs?: (target: SidePanel) => number; dropAsTab?: (target: SidePanel) => void; - dropAsNewPanel: (location: SidePanelDropLocation) => void; + dropAsNewPanel: ( + location: SidePanelDropLocation, + dropEffect: DataTransfer["dropEffect"], + ) => void; + getNewPanelDropEffect: (event: DragEvent) => { + dropEffect: DataTransfer["dropEffect"]; + description: string; + dropEffectMessage?: string; + leaveHandler?: () => void; + }; } export interface RegisteredSidePanel { @@ -307,33 +355,46 @@ export class SidePanelManager extends RefCounted { element.style.position = "relative"; element.style[MARGIN_FOR_SIDE[OPPOSITE_SIDE[zoneSide]]] = `-${size}px`; } + + const update = (event: DragEvent) => { + const { dragSource } = this; + if (dragSource === undefined) return false; + event.preventDefault(); + const { dropEffect, description, dropEffectMessage, leaveHandler } = + dragSource.getNewPanelDropEffect(event); + setDropEffect(event, dropEffect); + let message = `Drop to ${dropEffect} ${description} to new ${zoneFlexDirection}`; + if (dropEffectMessage) message += ` (${dropEffectMessage})`; + pushDragStatus(event, element, "drop", message, leaveHandler); + return true; + }; element.addEventListener("dragenter", (event) => { - if (!this.hasDroppablePanel()) return; + if (!update(event)) return; element.classList.add(DRAG_OVER_CLASSNAME); event.preventDefault(); - pushDragStatus(element, "drop", () => - document.createTextNode(`Drop side panel as new ${zoneFlexDirection}`), - ); }); - element.addEventListener("dragleave", () => { - popDragStatus(element, "drop"); + element.addEventListener("dragleave", (event) => { + popDragStatus(event, element, "drop"); element.classList.remove(DRAG_OVER_CLASSNAME); }); element.addEventListener("dragover", (event) => { - if (!this.hasDroppablePanel()) return; + if (!update(event)) return; event.preventDefault(); }); element.addEventListener("drop", (event) => { const { dragSource } = this; if (dragSource === undefined) return; - popDragStatus(element, "drop"); + popDragStatus(event, element, "drop"); element.classList.remove(DRAG_OVER_CLASSNAME); const flexDirection = FLEX_DIRECTION_FOR_SIDE[side]; - dragSource.dropAsNewPanel({ - side, - row: flexDirection === "column" ? flexIndex : crossIndex, - col: flexDirection === "row" ? flexIndex : crossIndex, - }); + dragSource.dropAsNewPanel( + { + side, + row: flexDirection === "column" ? flexIndex : crossIndex, + col: flexDirection === "row" ? flexIndex : crossIndex, + }, + getDropEffect() ?? "none", + ); this.dragSource = undefined; event.preventDefault(); event.stopPropagation(); @@ -421,6 +482,7 @@ export class SidePanelManager extends RefCounted { const minSize = flexGroup.minSize; const updateMessage = () => { pushDragStatus( + event, gutter, "drag", `Drag to resize, current ${SIZE_FOR_DIRECTION[direction]} is ${flexGroup.crossSize}px`, @@ -436,8 +498,8 @@ export class SidePanelManager extends RefCounted { updateMessage(); this.invalidateLayout(); }, - () => { - popDragStatus(gutter, "drag"); + (event) => { + popDragStatus(event, gutter, "drag"); }, ); }); @@ -479,8 +541,9 @@ export class SidePanelManager extends RefCounted { } if (nextFlexIndex === cells.length) return; const nextCell = cells[nextFlexIndex]; - const updateMessage = () => { + const updateMessage = (event: MouseEvent) => { pushDragStatus( + event, gutter, "drag", `Drag to resize, current ${SIZE_FOR_DIRECTION[direction]} ratio is ` + @@ -488,7 +551,7 @@ export class SidePanelManager extends RefCounted { `${nextCell.registeredPanel.location.value.flex}`, ); }; - updateMessage(); + updateMessage(event); startRelativeMouseDrag( event, (newEvent) => { @@ -519,13 +582,13 @@ export class SidePanelManager extends RefCounted { ...secondLocation, flex: Math.round((1 - firstFraction) * existingFlexSum * 100) / 100, }; - updateMessage(); + updateMessage(newEvent); cell.registeredPanel.location.locationChanged.dispatch(); nextCell.registeredPanel.location.locationChanged.dispatch(); this.invalidateLayout(); }, - () => { - popDragStatus(gutter, "drag"); + (event) => { + popDragStatus(event, gutter, "drag"); }, ); }); diff --git a/src/ui/tool.ts b/src/ui/tool.ts index c422e430ff..44bc9d5b22 100644 --- a/src/ui/tool.ts +++ b/src/ui/tool.ts @@ -24,9 +24,19 @@ import { debounce } from "lodash-es"; import type { MouseSelectionState, UserLayer } from "#src/layer/index.js"; import { StatusMessage } from "#src/status.js"; import type { TrackableValueInterface } from "#src/trackable_value.js"; +import { popDragStatus, pushDragStatus } from "#src/ui/drag_and_drop.js"; +import type { ToolDragSource } from "#src/ui/tool_drag_and_drop.js"; +import { beginToolDrag, endToolDrag } from "#src/ui/tool_drag_and_drop.js"; +import type { + MultiToolPaletteState, + ToolPalettePanel, +} from "#src/ui/tool_palette.js"; +import type { Query, QueryTerm } from "#src/ui/tool_query.js"; +import { matchesTerms, matchPredicate } from "#src/ui/tool_query.js"; import { animationFrameDebounce } from "#src/util/animation_frame_debounce.js"; import type { Borrowed, Owned } from "#src/util/disposable.js"; import { RefCounted } from "#src/util/disposable.js"; +import { getDropEffectFromModifiers } from "#src/util/drag_and_drop.js"; import type { ActionEvent, EventActionMap, @@ -73,7 +83,10 @@ export class ToolActivation extends RefCounted { export abstract class Tool extends RefCounted { changed = new Signal(); + unbound = new Signal(); + keyBinding: string | undefined = undefined; + savedJsonString: string | undefined = undefined; get context() { return this.localBinder.context; @@ -90,6 +103,11 @@ export abstract class Tool extends RefCounted { super(); } abstract activate(activation: ToolActivation): void; + renderInPalette(context: RefCounted): HTMLElement | undefined { + context; + return undefined; + } + abstract toJSON(): any; abstract description: string; unbind() { @@ -97,6 +115,7 @@ export abstract class Tool extends RefCounted { if (keyBinding !== undefined) { this.localBinder.set(keyBinding, undefined); } + this.unbound.dispatch(); } } @@ -157,9 +176,9 @@ export function restoreTool( while (true) { prototype = Object.getPrototypeOf(prototype); if (prototype === null) { - throw new Error(`Invalid tool type: ${JSON.stringify(obj)}.`); + return undefined; } - getter = toolsForPrototype.get(prototype)?.get(type); + getter = toolsForPrototype.get(prototype)?.get(type)?.getter; if (getter !== undefined) break; } return getter(context, obj); @@ -186,13 +205,21 @@ export type ToolGetter = ( options: any, ) => Owned | undefined; +export type ToolLister = ( + context: Context, + onChange?: () => void, +) => any[]; + export type LegacyToolGetter = ( layer: LayerType, options: any, ) => Owned | undefined; const legacyTools = new Map(); -const toolsForPrototype = new Map>(); +const toolsForPrototype = new Map< + object, + Map +>(); export function registerLegacyTool(type: string, getter: LegacyToolGetter) { legacyTools.set(type, getter); @@ -202,6 +229,7 @@ export function registerTool( contextType: AnyConstructor, type: string, getter: ToolGetter, + lister?: ToolLister, ) { const { prototype } = contextType; let tools = toolsForPrototype.get(prototype); @@ -209,7 +237,7 @@ export function registerTool( tools = new Map(); toolsForPrototype.set(prototype, tools); } - tools.set(type, getter); + tools.set(type, { getter, lister }); } export class SelectedLegacyTool @@ -277,7 +305,13 @@ export class GlobalToolBinder extends RefCounted { }, 100), ); - constructor(private inputEventMapBinder: InputEventMapBinder) { + localBinders = new Set(); + localBindersChanged = new Signal(); + + constructor( + private inputEventMapBinder: InputEventMapBinder, + public toolPaletteState: MultiToolPaletteState, + ) { super(); } @@ -285,35 +319,78 @@ export class GlobalToolBinder extends RefCounted { return this.bindings.get(key); } + private deleteBinding(tool: Tool) { + const keyBinding = tool.keyBinding!; + tool.keyBinding = undefined; + this.bindings.delete(keyBinding); + const localToolBinder = tool.localBinder; + localToolBinder.bindings.delete(keyBinding); + const { jsonToKey } = localToolBinder; + const { savedJsonString } = tool; + if (jsonToKey.get(savedJsonString!) === keyBinding) { + jsonToKey.delete(savedJsonString!); + } + this.destroyTool(tool); + } + + private toolJsonMaybeChanged(tool: Tool) { + // Check if tool is still bound. + let { keyBinding } = tool; + if (keyBinding === undefined) return; + let newJson = JSON.stringify(tool.toJSON()); + if (newJson === tool.savedJsonString) return; + + const localToolBinder = tool.localBinder; + localToolBinder.jsonToKey.delete(tool.savedJsonString!); + + // In the case of `DimensionTool`, there may be a chain of bindings that + // have to be updated. + while (true) { + const nextKeyBinding = localToolBinder.jsonToKey.get(newJson); + localToolBinder.jsonToKey.set(newJson, keyBinding!); + tool.savedJsonString = newJson; + keyBinding = nextKeyBinding; + if (keyBinding === undefined) { + // End of chain, all conflicts resolved. + break; + } + tool = localToolBinder.bindings.get(keyBinding)!; + const nextJson = JSON.stringify(tool.toJSON()); + if (nextJson === newJson) { + // End of chain, conflict remains. + this.deleteBinding(tool); + break; + } + newJson = nextJson; + } + localToolBinder.changed.dispatch(); + this.changed.dispatch(); + } + set(key: string, tool: Owned | undefined) { const { bindings } = this; const existingTool = bindings.get(key); if (existingTool !== undefined) { - existingTool.keyBinding = undefined; - bindings.delete(key); - const localToolBinder = existingTool.localBinder; - localToolBinder.bindings.delete(key); - localToolBinder.jsonToKey.delete(JSON.stringify(existingTool.toJSON())); - this.destroyTool(existingTool); - localToolBinder.changed.dispatch(); + this.deleteBinding(existingTool); + existingTool.localBinder.changed.dispatch(); } if (tool !== undefined) { const localToolBinder = tool.localBinder; const json = JSON.stringify(tool.toJSON()); + tool.savedJsonString = json; const existingKey = localToolBinder.jsonToKey.get(json); if (existingKey !== undefined) { const existingTool = localToolBinder.bindings.get(existingKey)!; - existingTool.keyBinding = undefined; - bindings.delete(existingKey); - localToolBinder.bindings.delete(existingKey); - localToolBinder.jsonToKey.delete(json); - this.destroyTool(existingTool); + this.deleteBinding(existingTool); } localToolBinder.bindings.set(key, tool); tool.keyBinding = key; localToolBinder.jsonToKey.set(json, key); bindings.set(key, tool); localToolBinder.changed.dispatch(); + tool.changed.add(() => { + this.toolJsonMaybeChanged(tool); + }); } this.changed.dispatch(); } @@ -395,6 +472,9 @@ export class GlobalToolBinder extends RefCounted { disposed() { this.deactivate_(); super.disposed(); + for (const tool of this.bindings.values()) { + tool.dispose(); + } } deactivate_() { @@ -421,9 +501,17 @@ export class LocalToolBinder< public globalBinder: GlobalToolBinder, ) { super(); + globalBinder.localBinders.add(this); + globalBinder.localBindersChanged.dispatch(); + } + + getSortOrder() { + return Number.NEGATIVE_INFINITY; } disposed() { + this.globalBinder.localBinders.delete(this); + this.globalBinder.localBindersChanged.dispatch(); this.clear(); super.disposed(); } @@ -458,6 +546,14 @@ export class LocalToolBinder< return obj; } + getCommonToolProperties(): any { + return {}; + } + + convertLocalJSONToPaletteJSON(toolJson: any) { + return toolJson; + } + clear() { const { globalBinder, bindings } = this; if (bindings.size !== 0) { @@ -491,14 +587,58 @@ export class LocalToolBinder< } } +export class LayerToolBinder< + LayerType extends UserLayer, +> extends LocalToolBinder { + getCommonToolProperties() { + return { + layer: this.context.managedLayer.name, + layerType: this.context.managedLayer.layer?.type, + }; + } + convertLocalJSONToPaletteJSON(toolJson: any) { + let j = toolJson; + if (typeof j === "string") { + j = { type: j }; + } + return { layer: this.context.managedLayer.name, ...j }; + } + + getSortOrder(): number { + const { managedLayer } = this.context; + managedLayer.manager.layerManager.updateNonArchivedLayerIndices(); + return this.context.managedLayer.nonArchivedLayerIndex; + } +} + +export function updateToolDragDropEffect( + dragSource: ToolDragSource, + dropEffect?: string, + dropSamePalette: boolean = false, +) { + const { paletteState, dragElement } = dragSource; + if (paletteState === undefined || dragElement === undefined) return; + const cssClass = "neuroglancer-tool-to-be-removed"; + if (dropEffect === "move" && dropSamePalette === false) { + dragElement.classList.add(cssClass); + } else { + dragElement.classList.remove(cssClass); + } +} + export class ToolBindingWidget extends RefCounted { element = document.createElement("div"); - private toolJsonString = JSON.stringify(this.toolJson); + private toolJsonString: string; constructor( public localBinder: LocalToolBinder, public toolJson: any, + public dragElement: HTMLElement | undefined, + public paletteState: + | { tool: Tool; palette: ToolPalettePanel } + | undefined = undefined, ) { super(); + this.toolJsonString = JSON.stringify(toolJson); const { element } = this; element.classList.add("neuroglancer-tool-key-binding"); this.registerDisposer( @@ -516,6 +656,63 @@ export class ToolBindingWidget extends RefCounted { addToolKeyBindHandlers(this, element, (key) => this.localBinder.setJson(key, this.toolJson), ); + if (dragElement !== undefined) { + dragElement.draggable = true; + dragElement.addEventListener("dragstart", (event: DragEvent) => { + pushDragStatus( + event, + dragElement, + "drag", + "Drag tool to another tool palette, " + + "or to the left/top/right/bottom edge of a layer group to create a new tool palette", + ); + beginToolDrag(this); + const { toolPaletteState } = this.localBinder.globalBinder; + const self = this; + toolPaletteState.viewer.sidePanelManager.startDrag( + { + dropAsNewPanel: (location, dropEffect) => { + const palette = toolPaletteState.addNew({ location }); + palette.tools.insert( + this.localBinder.convertLocalJSONToPaletteJSON(toolJson), + ); + if (dropEffect === "move") { + const { paletteState } = this; + if (paletteState?.palette.state.queryDefined.value === false) { + paletteState.palette.state.tools.remove(paletteState.tool); + } + } + }, + getNewPanelDropEffect: (event) => { + const inExplicitPalette = + this.paletteState?.palette.state.queryDefined.value === false; + const result = getDropEffectFromModifiers( + event, + /*defaultDropEffect=*/ inExplicitPalette ? "move" : "copy", + /*moveAllowed=*/ inExplicitPalette, + ); + updateToolDragDropEffect( + self, + result.dropEffect, + /*dropSamePalette=*/ false, + ); + const leaveHandler = () => { + updateToolDragDropEffect(self); + }; + return { ...result, description: "tool", leaveHandler }; + }, + }, + event, + ); + }); + dragElement.addEventListener("dragend", (event: DragEvent) => { + popDragStatus(event, dragElement, "drag"); + endToolDrag(this); + const { toolPaletteState } = this.localBinder.globalBinder; + toolPaletteState.viewer.sidePanelManager.endDrag(); + event.stopPropagation(); + }); + } } private updateView() { @@ -575,13 +772,22 @@ export function addToolKeyBindHandlers( export function makeToolButton( context: RefCounted, localBinder: LocalToolBinder, - options: { toolJson: any; label?: string; title?: string }, + options: { + toolJson: any; + label?: string; + title?: string; + dragElement?: HTMLElement; + }, ) { const element = document.createElement("div"); element.classList.add("neuroglancer-tool-button"); element.appendChild( context.registerDisposer( - new ToolBindingWidget(localBinder, options.toolJson), + new ToolBindingWidget( + localBinder, + options.toolJson, + options.dragElement ?? element, + ), ).element, ); const labelElement = document.createElement("div"); @@ -632,3 +838,112 @@ export function makeToolActivationStatusMessageWithHeader( content.appendChild(body); return { message, body, header }; } + +function* getToolsFromListerMatchingTerms( + localBinder: LocalToolBinder, + lister: ToolLister, + terms: QueryTerm[], + commonProperties: { [key: string]: string }, + onChange: (() => void) | undefined, +) { + for (const tool of lister(localBinder.context, onChange)) { + if (matchesTerms(tool, terms)) { + yield { + ...localBinder.convertLocalJSONToPaletteJSON(tool), + ...commonProperties, + }; + } + } +} + +function* getToolsMatchingTerms( + localBinder: LocalToolBinder, + terms: QueryTerm[], + onChange?: () => void, +) { + const typePredicate = terms.find( + (term) => term.property === "type", + )?.predicate; + const typeEquals = + typePredicate !== undefined && "equals" in typePredicate + ? typePredicate.equals + : undefined; + const commonProperties = localBinder.getCommonToolProperties(); + for (const term of terms) { + const { property } = term; + if (property in commonProperties) { + if (!matchPredicate(term.predicate, commonProperties[property])) { + return; + } + } + } + const remainingTerms = terms.filter( + (term) => !(term.property in commonProperties) && term.property !== "type", + ); + + const { context } = localBinder; + let prototype = context; + while (true) { + prototype = Object.getPrototypeOf(prototype); + if (prototype === null) { + break; + } + const toolMap = toolsForPrototype.get(prototype); + if (toolMap === undefined) continue; + if (typeEquals !== undefined) { + const lister = toolMap.get(typeEquals)?.lister; + if (lister === undefined) continue; + yield* getToolsFromListerMatchingTerms( + localBinder, + lister, + remainingTerms, + commonProperties, + onChange, + ); + break; + } + for (const [type, { lister }] of toolMap) { + if (lister === undefined) continue; + if (typePredicate !== undefined && !matchPredicate(typePredicate, type)) { + continue; + } + yield* getToolsFromListerMatchingTerms( + localBinder, + lister, + remainingTerms, + commonProperties, + onChange, + ); + } + } +} + +export function getMatchingTools( + globalBinder: GlobalToolBinder, + query: Query, + onChange?: () => void, +): Map { + const matchingTools = new Map(); + + const localBinders = Array.from(globalBinder.localBinders); + localBinders.sort((a, b) => a.getSortOrder() - b.getSortOrder()); + + for (const localBinder of localBinders) { + for (const { include, terms } of query.clauses) { + for (const toolJson of getToolsMatchingTerms( + localBinder, + terms, + onChange, + )) { + const identifier = JSON.stringify(toolJson); + if (include) { + matchingTools.set(identifier, toolJson); + } else { + matchingTools.delete(identifier); + } + } + } + } + + return matchingTools; +} diff --git a/src/ui/tool_drag_and_drop.ts b/src/ui/tool_drag_and_drop.ts new file mode 100644 index 0000000000..baab0c27b1 --- /dev/null +++ b/src/ui/tool_drag_and_drop.ts @@ -0,0 +1,42 @@ +/** + * @license + * Copyright 2024 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { LocalToolBinder, Tool } from "#src/ui/tool.js"; +import type { ToolPalettePanel } from "#src/ui/tool_palette.js"; + +export interface ToolDragSource { + readonly localBinder: LocalToolBinder; + readonly toolJson: any; + dragElement?: HTMLElement | undefined; + paletteState?: + | { + tool: Tool; + palette: ToolPalettePanel; + } + | undefined; +} + +export let toolDragSource: ToolDragSource | undefined = undefined; + +export function beginToolDrag(source: ToolDragSource) { + toolDragSource = source; +} + +export function endToolDrag(source: ToolDragSource) { + if (toolDragSource === source) { + toolDragSource = undefined; + } +} diff --git a/src/ui/tool_palette.css b/src/ui/tool_palette.css new file mode 100644 index 0000000000..1b414a271f --- /dev/null +++ b/src/ui/tool_palette.css @@ -0,0 +1,205 @@ +/** + * @license + * Copyright 2024 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +.neuroglancer-tool-palette-button-container { + display: inline-flex; + flex-direction: row; +} + +.neuroglancer-tool-palette-button-container { + border-radius: 20%; + border: 1px solid transparent; +} + +.neuroglancer-tool-palette-button-container:hover { + background-color: #484848; +} + +.neuroglancer-tool-palette-button { + position: relative; + display: flex; + flex-direction: row; +} + +.neuroglancer-tool-palette-dropdown { + position: absolute; + z-index: 100; + min-width: min(50vw, 300px); + border: 1px solid #aaa; + background-color: black; + padding: 2px; +} + +.neuroglancer-tool-palette-name { + flex: 1; + background-color: transparent; + border: 0px; + color: white; + outline: 0px; + /* ensure if name gets too long it doesn't push buttons over */ + width: 0px; + min-width: 0px; +} + +.neuroglancer-tool-palette-dropdown > ul { + overflow-y: auto; + padding: 0px; + margin: 0px; +} + +.neuroglancer-tool-palette-dropdown + > ul + > li:not(.neuroglancer-tool-palette-dropdown-separator) { + display: flex; + flex-direction: row; + list-style-type: none; + padding: 2px; + font: 10pt sans-serif; +} + +.neuroglancer-tool-palette-dropdown + > ul + > li:not(.neuroglancer-tool-palette-dropdown-separator):hover { + background-color: #333; +} + +.neuroglancer-tool-palette-dropdown-canned-item { + cursor: pointer; +} + +.neuroglancer-tool-palette-dropdown-separator { + height: 1px; + margin-top: 3px; + margin-bottom: 3px; + padding: 0px; + background-color: #ccc; +} + +.neuroglancer-tool-palette-drop-zone { + display: block; + flex: 1; +} + +.neuroglancer-tool-palette-items { + display: flex; + flex-direction: column; + flex-grow: 1; + flex-shrink: 1; + flex-basis: 0px; + font: 10pt sans-serif; + overflow-y: auto; + overflow-x: hidden; +} + +.neuroglancer-tool-palette-tool-container { + display: grid; + grid-template-columns: auto 1fr; + align-items: center; + padding-top: 2px; + padding-bottom: 2px; +} + +.neuroglancer-tool-palette-tool-container:hover { + background-color: #282828; +} + +.neuroglancer-tool-palette-tool-container + > .neuroglancer-tool-palette-tool-content { + grid-row: 1; + grid-column: 2; +} + +.neuroglancer-tool-palette-tool-container + > .neuroglancer-tool-palette-tool-properties { + grid-row: 2; + grid-column: 1/3; +} + +.neuroglancer-tool-palette-tool-container > .neuroglancer-tool-key-binding { + grid-row: 1; + grid-column: 1; +} + +.neuroglancer-tool-palette-tool-delete { + visibility: hidden; +} + +.neuroglancer-tool-palette-tool-container:hover + > .neuroglancer-tool-palette-tool-delete { + visibility: inherit; +} + +.neuroglancer-tool-palette-layer-group-header { + display: flex; + flex-direction: row; + background-color: #181818; + margin-bottom: 2px; + position: sticky; + top: 0px; + z-index: 1; +} + +.neuroglancer-tool-palette-layer-group:hover + > .neuroglancer-tool-palette-layer-group-header { + background-color: #282828; +} + +.neuroglancer-tool-palette-layer-group { + border-left: 2px solid #181818; +} + +.neuroglancer-tool-palette-layer-group:hover { + border-left: 2px solid #ccc; +} + +.neuroglancer-tool-palette-body { + display: flex; + flex-direction: column; + flex: 1; +} + +.neuroglancer-tool-palette-body .neuroglancer-multiline-autocomplete-dropdown { + z-index: 2; +} + +.neuroglancer-tool-palette-query-errors { + margin: 0px; + padding: 0px; + margin-bottom: 2px; +} + +.neuroglancer-tool-palette-query-errors > li { + list-style-type: none; + padding: 2px; + font: 10pt sans-serif; + color: red; +} + +.neuroglancer-tool-palette-tool-properties { + display: none; + color: #f9f; + font-style: italic; + user-select: text; +} + +.neuroglancer-tool-palette-show-properties + .neuroglancer-tool-palette-tool-properties { + display: block; +} + +.neuroglancer-tool-to-be-removed { + opacity: 50%; +} diff --git a/src/ui/tool_palette.ts b/src/ui/tool_palette.ts new file mode 100644 index 0000000000..d48764fe3f --- /dev/null +++ b/src/ui/tool_palette.ts @@ -0,0 +1,1310 @@ +/** + * @license + * Copyright 2024 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import "#src/ui/tool_palette.css"; + +import svg_search from "ikonate/icons/search.svg?raw"; +import svg_tool from "ikonate/icons/tool.svg?raw"; +import { debounce } from "lodash-es"; +import type { UserLayer } from "#src/layer/index.js"; +import { + ElementVisibilityFromTrackableBoolean, + TrackableBooleanCheckbox, +} from "#src/trackable_boolean.js"; +import { + makeCachedDerivedWatchableValue, + makeCachedLazyDerivedWatchableValue, + TrackableValue, + WatchableValue, +} from "#src/trackable_value.js"; +import { popDragStatus, pushDragStatus } from "#src/ui/drag_and_drop.js"; +import { LayerVisibilityWidget } from "#src/ui/layer_list_panel.js"; +import { LayerNameWidget } from "#src/ui/layer_side_panel.js"; +import type { + RegisteredSidePanel, + SidePanelManager, +} from "#src/ui/side_panel.js"; +import { SidePanel } from "#src/ui/side_panel.js"; +import type { SidePanelLocation } from "#src/ui/side_panel_location.js"; +import { + DEFAULT_SIDE_PANEL_LOCATION, + TrackableSidePanelLocation, +} from "#src/ui/side_panel_location.js"; +import type { Tool } from "#src/ui/tool.js"; +import { + getMatchingTools, + LayerToolBinder, + restoreTool, + ToolBindingWidget, + updateToolDragDropEffect, +} from "#src/ui/tool.js"; +import type { ToolDragSource } from "#src/ui/tool_drag_and_drop.js"; +import { toolDragSource } from "#src/ui/tool_drag_and_drop.js"; +import { + getPropertyNameCompletions, + getPropertyValueCompletions, + getQueryTermToComplete, + parsePartialToolQuery, + parseToolQuery, +} from "#src/ui/tool_query.js"; +import { animationFrameDebounce } from "#src/util/animation_frame_debounce.js"; +import { arraysEqual } from "#src/util/array.js"; +import type { Owned } from "#src/util/disposable.js"; +import { RefCounted } from "#src/util/disposable.js"; +import { + updateChildren, + removeFromParent, + removeChildren, +} from "#src/util/dom.js"; +import { + getDropEffectFromModifiers, + getDropEffect, + setDropEffect, +} from "#src/util/drag_and_drop.js"; +import { positionRelativeDropdown } from "#src/util/dropdown.js"; +import { + parseArray, + verifyObject, + verifyOptionalObjectProperty, + verifyString, +} from "#src/util/json.js"; +import { NullarySignal } from "#src/util/signal.js"; +import type { Trackable } from "#src/util/trackable.js"; +import { CompoundTrackable, getCachedJson } from "#src/util/trackable.js"; +import type { Viewer } from "#src/viewer.js"; +import { CheckboxIcon } from "#src/widget/checkbox_icon.js"; +import { makeDeleteButton } from "#src/widget/delete_button.js"; +import { DependentViewWidget } from "#src/widget/dependent_view_widget.js"; +import type { + CompletionResult, + CompletionWithDescription, +} from "#src/widget/multiline_autocomplete.js"; +import { + AutocompleteTextInput, + makeCompletionElementWithDescription, +} from "#src/widget/multiline_autocomplete.js"; +import { TextInputWidget } from "#src/widget/text_input.js"; + +const DEFAULT_TOOL_PALETTE_PANEL_LOCATION: SidePanelLocation = { + ...DEFAULT_SIDE_PANEL_LOCATION, + side: "right", + row: 0, + visible: true, +}; + +function getToolFromJson(viewer: Viewer, toolJson: unknown): Tool | undefined { + verifyObject(toolJson); + const layerName = verifyOptionalObjectProperty( + toolJson, + "layer", + verifyString, + ); + if (layerName !== undefined) { + const { layer: _ignoredLayer, ...adjustedToolJson } = toolJson as any; + const managedLayer = viewer.layerManager.getLayerByName(layerName); + if (managedLayer === undefined) { + return undefined; + } + const userLayer = managedLayer.layer; + if (userLayer === null) { + return undefined; + } + return restoreTool(userLayer, adjustedToolJson); + } else { + return restoreTool(viewer, toolJson); + } +} + +export class TrackableToolList extends RefCounted implements Trackable { + tools: Tool[] = []; + + changed = new NullarySignal(); + + constructor(private viewer: Viewer) { + super(); + } + + get value() { + return this.tools; + } + + reset() { + const { tools } = this; + if (tools.length === 0) return; + for (const tool of tools) { + tool.dispose(); + } + tools.length = 0; + this.changed.dispatch(); + } + + private makeTool(toolJson: unknown): Tool | undefined { + const tool = getToolFromJson(this.viewer, toolJson); + if (tool === undefined) return undefined; + this.initializeTool(tool); + return tool; + } + + private initializeTool(tool: Tool) { + tool.unbound.add(() => { + this.remove(tool); + }); + } + + restoreState(obj: unknown) { + const tools: Tool[] = []; + this.tools = tools; + parseArray(obj, (j) => { + const tool = this.makeTool(j); + if (tool === undefined) return; + tools.push(tool); + }); + this.changed.dispatch(); + } + + insert( + toolJson: unknown, + before: Tool | undefined = undefined, + ): Tool | undefined { + let insertIndex: number; + const { tools } = this; + if (before === undefined) { + insertIndex = tools.length; + } else { + insertIndex = tools.indexOf(before); + } + const tool = this.makeTool(toolJson); + if (tool === undefined) return undefined; + tools.splice(insertIndex, 0, tool); + this.changed.dispatch(); + return tool; + } + + move(source: Tool, before: Tool | undefined) { + const { tools } = this; + const sourceIndex = tools.indexOf(source); + if (sourceIndex === -1) return false; + let targetIndex: number; + if (before === undefined) { + targetIndex = tools.length; + } else { + targetIndex = tools.indexOf(before); + if (targetIndex === -1) return false; + } + if (targetIndex === sourceIndex) return true; + tools.splice(sourceIndex, 1); + if (targetIndex > sourceIndex) { + --targetIndex; + } + tools.splice(targetIndex, 0, source); + this.changed.dispatch(); + return true; + } + + remove(tool: Tool): boolean { + const { tools } = this; + const index = tools.indexOf(tool); + if (index === -1) return false; + tools.splice(index, 1); + tool.dispose(); + this.changed.dispatch(); + return true; + } + + toJSON() { + const { tools } = this; + if (tools.length === 0) return undefined; + return Array.from(tools, (tool) => { + return tool.localBinder.convertLocalJSONToPaletteJSON(tool.toJSON()); + }); + } + + addTools(newTools: Tool[]) { + for (const tool of newTools) { + this.initializeTool(tool); + } + this.tools.push(...newTools); + this.changed.dispatch(); + } + + disposed() { + super.disposed(); + for (const tool of this.tools) { + tool.dispose(); + } + } +} + +export class ToolPaletteState extends RefCounted implements Trackable { + location = new TrackableSidePanelLocation( + DEFAULT_TOOL_PALETTE_PANEL_LOCATION, + ); + + name = new TrackableValue("", verifyString); + + tools: TrackableToolList; + + query = new TrackableValue("", verifyString); + + parsedQuery = this.registerDisposer( + makeCachedLazyDerivedWatchableValue((query) => { + return parseToolQuery(query); + }, this.query), + ); + + queryDefined; + + private trackable = new CompoundTrackable(); + + get changed() { + return this.trackable.changed; + } + + constructor(public viewer: Viewer) { + super(); + this.tools = this.registerDisposer(new TrackableToolList(viewer)); + this.location.changed.add(this.changed.dispatch); + this.name.changed.add(this.changed.dispatch); + this.trackable.add("tools", this.tools); + this.trackable.add("query", this.query); + this.queryDefined = this.registerDisposer( + makeCachedDerivedWatchableValue( + (value) => value.length === 0, + [this.tools], + ), + ); + } + + restoreState(obj: unknown) { + this.location.restoreState(obj); + this.trackable.restoreState(obj); + if (this.query.value !== "") { + this.tools.reset(); + } + } + + reset() { + this.location.reset(); + this.trackable.reset(); + } + + toJSON() { + return { ...this.location.toJSON(), ...this.trackable.toJSON() }; + } +} + +class RenderedLayerGroup extends RefCounted { + element = document.createElement("div"); + header = document.createElement("div"); + content = document.createElement("div"); + firstTool: Tool | undefined; + constructor(public layer: UserLayer) { + super(); + const { element, header, content } = this; + element.classList.add("neuroglancer-tool-palette-layer-group"); + element.appendChild(header); + element.appendChild(content); + header.classList.add("neuroglancer-tool-palette-layer-group-header"); + content.classList.add("neuroglancer-tool-palette-layer-group-content"); + header.appendChild( + this.registerDisposer(new LayerVisibilityWidget(layer.managedLayer)) + .element, + ); + header.appendChild( + this.registerDisposer(new LayerNameWidget(layer.managedLayer)).element, + ); + } +} + +class QueryResults extends RefCounted { + changed = new NullarySignal(); + + private results: Tool[] = []; + private jsonToTool = new Map(); + + constructor(public state: ToolPaletteState) { + super(); + + this.registerDisposer(state.query.changed.add(this.debouncedUpdateResults)); + this.registerDisposer( + state.viewer.globalToolBinder.localBindersChanged.add( + this.debouncedUpdateResults, + ), + ); + + this.updateResults(); + } + + disposed() { + for (const tool of this.jsonToTool.values()) { + tool.dispose(); + } + super.dispose(); + } + + private debouncedUpdateResults = this.registerCancellable( + debounce(() => { + this.updateResults(); + }), + ); + + private getMatches(): Map | undefined { + let triggered = false; + const onChange = () => { + if (triggered) return; + triggered = true; + this.debouncedUpdateResults(); + }; + const parsedQuery = this.state.parsedQuery.value; + if (parsedQuery === undefined) return undefined; + if (!("query" in parsedQuery)) { + return undefined; + } + const matches = getMatchingTools( + this.state.viewer.globalToolBinder, + parsedQuery.query, + onChange, + ); + return matches; + } + + private updateResults() { + const matches = this.getMatches() ?? new Map(); + const { results, jsonToTool } = this; + const newResults: Tool[] = []; + for (const [key, toolJson] of matches) { + let tool = jsonToTool.get(key); + if (tool === undefined) { + tool = getToolFromJson(this.state.viewer, toolJson); + if (tool === undefined) { + continue; + } + jsonToTool.set(key, tool); + } + newResults.push(tool); + } + + for (const [key, tool] of jsonToTool) { + if (!matches.has(key)) { + tool.dispose(); + jsonToTool.delete(key); + } + } + if (!arraysEqual(results, newResults)) { + this.results = newResults; + this.changed.dispatch(); + } + } + + convertToExplicitPalette() { + this.debouncedUpdateResults.flush(); + this.state.query.value = ""; + this.state.tools.addTools(this.results); + this.results.length = 0; + this.jsonToTool.clear(); + } + + get value() { + return this.results; + } +} + +class RenderedTool extends RefCounted { + layerGroup: RenderedLayerGroup | undefined; + element = document.createElement("label")!; + private context: RefCounted | undefined = undefined; + + constructor( + public tool: Tool, + public palette: ToolPalettePanel, + ) { + super(); + const { element } = this; + element.classList.add("neuroglancer-tool-palette-tool-container"); + element.addEventListener("dblclick", () => { + this.tool.unbind(); + }); + element.append( + this.registerDisposer( + new ToolBindingWidget(tool.localBinder, tool.toJSON(), element, { + tool, + palette, + }), + ).element, + ); + this.updateView(); + this.updateTooltip(); + + this.registerDisposer(tool.changed.add(this.debouncedUpdateTooltip)); + this.registerDisposer( + palette.state.queryDefined.changed.add(this.debouncedUpdateTooltip), + ); + } + + private debouncedUpdateView = this.registerCancellable( + animationFrameDebounce(() => this.updateView()), + ); + + private debouncedUpdateTooltip = this.registerCancellable( + animationFrameDebounce(() => this.updateTooltip()), + ); + + private updateTooltip() { + let toolJson = this.tool.toJSON(); + if (typeof toolJson === "string") { + toolJson = { type: toolJson }; + } + let text = Object.entries(toolJson) + .map(([key, value]) => `${key}:${value}`) + .join(" "); + if (!this.palette.state.queryDefined.value) { + text += "\nDrag to move/copy, dblclick to remove"; + } else { + text += "\nDrag to copy to another palette"; + } + this.element.title = text; + } + + private updateView() { + let { context } = this; + const { element } = this; + if (context !== undefined) { + context.dispose(); + element.removeChild(element.lastElementChild as Element); + } + this.context = context = new RefCounted(); + const { tool } = this; + let toolElement = this.tool.renderInPalette(context); + if (toolElement === undefined) { + toolElement = document.createElement("div"); + toolElement.textContent = "Loading..."; + if (tool.localBinder instanceof LayerToolBinder) { + context.registerDisposer( + tool.localBinder.context.managedLayer.layerChanged.add( + this.debouncedUpdateView, + ), + ); + } + } + toolElement.classList.add("neuroglancer-tool-palette-tool-content"); + element.appendChild(toolElement); + } + + disposed() { + this.context?.dispose(); + this.layerGroup?.dispose(); + super.disposed(); + } +} + +export class ToolPalettePanel extends SidePanel { + private itemContainer = document.createElement("div"); + private dropZone = document.createElement("div"); + private renderedTools = new Map(); + private dragState: + | { dragSource: ToolDragSource; ephemeralTool: Tool } + | undefined = undefined; + private dragEnterCount = 0; + private queryResults: QueryResults; + + private clearDragState() { + const { dragState } = this; + if (dragState === undefined) return; + this.dragState = undefined; + this.state.tools.remove(dragState.ephemeralTool); + } + + get hasQuery() { + return this.state.query.value !== ""; + } + + private registerDropHandlers( + element: HTMLElement, + getTool: () => Tool | undefined, + ) { + const isDragSourceSupported = () => { + return ( + toolDragSource?.localBinder.globalBinder === + this.manager.state.viewer.globalToolBinder + ); + }; + + const update = (event: DragEvent, updateDropEffect: boolean) => { + if (!isDragSourceSupported()) { + return undefined; + } + if (this.hasQuery) { + this.clearDragState(); + const otherPalette = toolDragSource?.paletteState?.palette; + if ( + updateDropEffect && + otherPalette !== undefined && + otherPalette !== this + ) { + pushDragStatus( + event, + this.itemContainer, + "drop", + "Tools cannot be dropped into a query-defined palette. To allow dropping tools into this palette, first click the magnifying glass icon in the panel titlebar to convert it to a manually-defined palette.", + ); + } + updateToolDragDropEffect(toolDragSource!, "none", false); + return "none"; + } + if (this.dragState?.dragSource !== toolDragSource) { + this.clearDragState(); + } + let dropEffect: "copy" | "move"; + let message: string = ""; + if (updateDropEffect) { + const explicitPaletteSource = + toolDragSource!.paletteState?.palette.state.queryDefined.value === + false; + const result = getDropEffectFromModifiers( + event, + /*defaultDropEffect=*/ explicitPaletteSource ? "move" : "copy", + /*moveAllowed=*/ explicitPaletteSource, + ); + dropEffect = result.dropEffect; + setDropEffect(event, dropEffect); + message = `Drop to ${dropEffect} the tool`; + if (result.dropEffectMessage) { + message += ` (${result.dropEffectMessage})`; + } + } else { + dropEffect = getDropEffect() as "copy" | "move"; + } + + const tool = getTool(); + + const samePalette = toolDragSource!.paletteState?.palette === this; + + if (dropEffect === "copy" || !samePalette) { + const { dragState } = this; + if (dragState === undefined) { + const sourceToolJson = + toolDragSource!.localBinder.convertLocalJSONToPaletteJSON( + toolDragSource!.toolJson, + ); + const ephemeralTool = this.state.tools.insert(sourceToolJson, tool); + if (ephemeralTool === undefined) { + // Unexpected failure + console.error("Failed to create tool: ", toolDragSource!.toolJson); + return undefined; + } + this.dragState = { dragSource: toolDragSource!, ephemeralTool }; + } else { + this.state.tools.move(dragState.ephemeralTool, tool); + } + } else { + this.clearDragState(); + this.state.tools.move(toolDragSource!.paletteState!.tool, tool); + } + + if (updateDropEffect) { + const source = toolDragSource!; + const leaveHandler = () => { + updateToolDragDropEffect(source); + }; + pushDragStatus( + event, + this.itemContainer, + "drop", + message, + leaveHandler, + ); + updateToolDragDropEffect(source, dropEffect, samePalette); + } + return dropEffect; + }; + + const handleDragOver = (event: DragEvent) => { + const updateResult = update(event, /*updateDropEffect=*/ true); + if (updateResult === undefined) { + popDragStatus(event, this.itemContainer, "drop"); + return; + } + event.preventDefault(); + event.stopPropagation(); + }; + element.addEventListener("dragover", handleDragOver); + element.addEventListener("dragenter", (event: DragEvent) => { + ++this.dragEnterCount; + handleDragOver(event); + }); + element.addEventListener("dragleave", (event: DragEvent) => { + if (--this.dragEnterCount !== 0) return; + popDragStatus(event, this.itemContainer, "drop"); + this.clearDragState(); + event.stopPropagation(); + }); + element.addEventListener("drop", (event: DragEvent) => { + event.preventDefault(); + this.dragEnterCount = 0; + popDragStatus(event, this.itemContainer, "drop"); + const updateResult = update(event, /*updateDropEffect=*/ false); + if (updateResult === undefined) { + this.clearDragState(); + return; + } + event.stopPropagation(); + // The "ephemeral tool", if any, is no longer ephemeral. + this.dragState = undefined; + if (updateResult === "move") { + const { paletteState } = toolDragSource!; + if (paletteState !== undefined && paletteState.palette !== this) { + paletteState.palette.state.tools.remove(paletteState.tool); + } + } + }); + } + + constructor( + private manager: MultiToolPaletteManager, + sidePanelManager: SidePanelManager, + public state: ToolPaletteState, + ) { + super(sidePanelManager, state.location); + const { titleBar } = this.addTitleBar({}); + titleBar.appendChild( + this.registerDisposer(new PaletteNameWidget(state.name)).element, + ); + this.queryResults = this.registerDisposer(new QueryResults(state)); + const hasQuery = this.registerDisposer( + makeCachedDerivedWatchableValue((value) => value !== "", [state.query]), + ); + const self = this; + const searchButton = this.registerDisposer( + new CheckboxIcon( + { + changed: hasQuery.changed, + get value() { + return hasQuery.value; + }, + set value(newValue: boolean) { + if (newValue === false && hasQuery.value !== false) { + self.queryResults.convertToExplicitPalette(); + } + }, + }, + { + svg: svg_search, + disableTitle: "Convert query results to an explicit tool palette", + }, + ), + ); + titleBar.appendChild(searchButton.element); + this.registerDisposer( + new ElementVisibilityFromTrackableBoolean(hasQuery, searchButton.element), + ); + const deleteButton = makeDeleteButton({ title: "Delete tool palette" }); + deleteButton.addEventListener("click", () => { + state.dispose(); + }); + titleBar.appendChild(deleteButton); + + const body = document.createElement("div"); + body.classList.add("neuroglancer-tool-palette-body"); + const { itemContainer } = this; + itemContainer.classList.add("neuroglancer-tool-palette-items"); + body.appendChild( + this.registerDisposer( + new DependentViewWidget( + self.state.queryDefined, + (hasQuery: boolean, parent, context) => { + if (!hasQuery) return; + parent.appendChild( + context.registerDisposer(new ToolQueryWidget(state)).element, + ); + }, + ), + ).element, + ); + body.appendChild(itemContainer); + this.addBody(body); + + const { dropZone } = this; + dropZone.classList.add("neuroglancer-tool-palette-drop-zone"); + this.registerDropHandlers(dropZone, () => undefined); + const debouncedRender = this.registerCancellable( + animationFrameDebounce(() => this.render()), + ); + this.registerDisposer(this.state.tools.changed.add(debouncedRender)); + this.registerDisposer(this.queryResults.changed.add(debouncedRender)); + this.visibility.changed.add(debouncedRender); + this.render(); + } + + private getRenderedTool(tool: Tool) { + const { renderedTools } = this; + let renderedTool = renderedTools.get(tool); + if (renderedTool === undefined) { + renderedTool = new RenderedTool(tool, this); + this.registerDropHandlers(renderedTool.element, () => tool); + renderedTools.set(tool, renderedTool); + } + return renderedTool; + } + + override getDragDropDescription() { + return "tool palette"; + } + + override canCopy() { + return true; + } + + override copyToNewLocation(location: SidePanelLocation) { + const newPalette = this.manager.state.addNew({ + location: { ...this.state.location.value, ...location }, + name: this.state.name.value, + }); + newPalette.tools.restoreState(this.state.tools.toJSON() ?? []); + newPalette.query.value = this.state.query.value; + } + + render() { + const self = this; + function* getItems() { + const tools = self.state.queryDefined.value + ? self.queryResults.value + : self.state.tools.tools; + const { renderedTools } = self; + const seenTools = new Set(tools); + const numTools = tools.length; + const seenLayerGroups = new Set(); + for (let toolIndex = 0; toolIndex < numTools; ) { + let tool = tools[toolIndex]; + const { localBinder } = tool; + if (localBinder instanceof LayerToolBinder) { + const layer: UserLayer = localBinder.context; + + let renderedTool = self.getRenderedTool(tool); + + let { layerGroup } = renderedTool; + if (seenLayerGroups.has(layerGroup) || layerGroup === undefined) { + layerGroup = new RenderedLayerGroup(layer); + self.registerDropHandlers( + layerGroup.header, + () => layerGroup!.firstTool, + ); + layerGroup.firstTool = tool; + } else { + layerGroup.addRef(); + } + seenLayerGroups.add(layerGroup); + + // Fill layer group. + function* getGroupItems() { + while (true) { + renderedTool.layerGroup?.dispose(); + renderedTool.layerGroup = layerGroup!.addRef(); + yield renderedTool.element; + if ( + ++toolIndex === numTools || + (tool = tools[toolIndex]).localBinder !== localBinder + ) { + break; + } + renderedTool = self.getRenderedTool(tool); + } + } + updateChildren(layerGroup.content, getGroupItems()); + yield layerGroup.element; + layerGroup.dispose(); + } else { + const renderedTool = self.getRenderedTool(tool); + yield renderedTool.element; + ++toolIndex; + } + } + for (const [tool, renderedTool] of renderedTools) { + if (!seenTools.has(tool)) { + renderedTool.dispose(); + renderedTools.delete(tool); + } + } + + yield self.dropZone; + } + updateChildren(this.itemContainer, getItems()); + } + + disposed() {} +} + +class ToolQueryWidget extends RefCounted { + element = document.createElement("div"); + errorsElement = document.createElement("ul"); + constructor(public state: ToolPaletteState) { + super(); + + const textInput = this.registerDisposer( + new AutocompleteTextInput({ + completer: this.completeQuery.bind(this), + }), + ); + textInput.placeholder = "Enter tool query or drag in tools"; + textInput.element.classList.add("neuroglancer-tool-palette-query"); + textInput.value = state.query.value ?? ""; + + this.registerDisposer( + state.parsedQuery.changed.add( + this.registerCancellable(debounce(() => this.updateErrors(), 200)), + ), + ); + this.updateErrors(); + textInput.onCommit.add(() => { + state.query.value = textInput.value; + }); + state.query.changed.add(() => { + textInput.value = state.query.value ?? ""; + }); + const { element, errorsElement } = this; + element.appendChild(textInput.element); + element.appendChild(errorsElement); + errorsElement.classList.add("neuroglancer-tool-palette-query-errors"); + } + + private updateErrors() { + const { errorsElement } = this; + removeChildren(errorsElement); + const query = this.state.parsedQuery.value; + if (query === undefined || !("errors" in query)) return; + for (const error of query.errors) { + const element = document.createElement("li"); + element.textContent = error.message; + errorsElement.appendChild(element); + } + } + + private async completeQuery({ + value, + }: { + value: string; + }): Promise { + const parsed = parsePartialToolQuery(value); + const info = getQueryTermToComplete(parsed); + + const matches = getMatchingTools( + this.state.viewer.globalToolBinder, + info.completionQuery, + ); + + let completions: [string, number][]; + if (info.property === undefined) { + completions = getPropertyNameCompletions( + info.completionQuery, + matches, + info.prefix, + ); + } else { + completions = getPropertyValueCompletions(matches, info.property); + } + const completionEntries: CompletionWithDescription[] = []; + if (info.property === undefined && info.prefix === "") { + if ( + parsed.query.clauses.length > 0 && + parsed.query.clauses[parsed.query.clauses.length - 1].terms.length !== 0 + ) { + completionEntries.push({ + value: "+", + description: "New inclusion clause", + }); + completionEntries.push({ + value: "-", + description: "New exclusion clause", + }); + } + } + + for (const [value, count] of completions) { + completionEntries.push({ + value, + description: `${count} tool${count > 0 ? "s" : ""}`, + }); + } + return { + offset: info.offset, + completions: completionEntries, + makeElement: makeCompletionElementWithDescription, + }; + } +} + +export class MultiToolPaletteState implements Trackable { + changed = new NullarySignal(); + changedShallow = new NullarySignal(); + visibleStateChanged = new NullarySignal(); + palettes = new Set(); + + constructor(public viewer: Viewer) {} + + add(palette: Owned) { + this.palettes.add(palette); + palette.registerDisposer(palette.changed.add(this.changed.dispatch)); + palette.registerDisposer( + palette.location.watchableVisible.changed.add( + this.visibleStateChanged.dispatch, + ), + ); + palette.registerDisposer( + palette.name.changed.add(() => this.checkTitles(palette)), + ); + palette.registerDisposer(() => { + this.palettes.delete(palette); + this.changedShallow.dispatch(); + this.visibleStateChanged.dispatch(); + this.changed.dispatch(); + }); + this.changedShallow.dispatch(); + this.changed.dispatch(); + } + + toJSON() { + const { palettes } = this; + if (palettes.size === 0) { + return undefined; + } + const json: any = {}; + for (const palette of palettes) { + json[palette.name.value] = getCachedJson(palette).value; + } + return json; + } + + reset() { + const { palettes } = this; + if (palettes.size !== 0) { + for (const palette of palettes) { + palette.dispose(); + } + } + } + + restoreState(obj: unknown) { + if (obj === undefined) { + return; + } + verifyObject(obj); + const { viewer } = this; + const names = new Map(); + for (const palette of this.palettes) { + names.set(palette.name.value, palette); + } + for (const [name, json] of Object.entries(obj as object)) { + const existing = names.get(name); + if (existing !== undefined) { + existing.restoreState(json); + continue; + } + const palette = new ToolPaletteState(viewer); + palette.name.value = name; + palette.restoreState(json); + names.set(name, palette); + this.add(palette); + } + } + + addNew( + options: { location?: Partial; name?: string } = {}, + ) { + const palette = new ToolPaletteState(this.viewer); + const { location, name = "Palette" } = options; + palette.name.value = name; + this.checkTitles(palette); + palette.location.value = { + ...DEFAULT_TOOL_PALETTE_PANEL_LOCATION, + ...location, + }; + palette.location.locationChanged.dispatch(); + this.add(palette); + return palette; + } + + // Ensures all palette titles are unique. + private checkingTitles = false; + private checkTitles(changedPalette: ToolPaletteState) { + if (this.checkingTitles) return; + try { + this.checkingTitles = true; + const titles = new Set(); + for (const palette of this.palettes) { + if (palette === changedPalette) continue; + titles.add(palette.name.value); + } + const title = changedPalette.name.value; + if (!titles.has(title)) return; + let suffix = 0; + while (true) { + const modifiedTitle = title + ++suffix; + if (!titles.has(modifiedTitle)) { + changedPalette.name.value = modifiedTitle; + return; + } + } + } finally { + this.checkingTitles = false; + } + } +} + +export class MultiToolPaletteManager extends RefCounted { + private panels = new Map(); + constructor( + private sidePanelManager: SidePanelManager, + public state: MultiToolPaletteState, + ) { + super(); + const debouncedUpdatePanels = this.registerCancellable( + animationFrameDebounce(() => this.updatePanels()), + ); + this.registerDisposer(this.state.changedShallow.add(debouncedUpdatePanels)); + this.updatePanels(); + } + + private updatePanels() { + const { panels } = this; + const { palettes } = this.state; + for (const [palette, panel] of panels) { + if (!palettes.has(palette)) { + this.sidePanelManager.unregisterPanel(panel); + panels.delete(palette); + } + } + + for (const palette of palettes) { + if (!panels.has(palette)) { + const panel = { + location: palette.location, + makePanel: () => + new ToolPalettePanel(this, this.sidePanelManager, palette), + }; + panels.set(palette, panel); + this.sidePanelManager.registerPanel(panel); + } + } + } + + disposed() { + super.disposed(); + for (const panel of this.panels.values()) { + this.sidePanelManager.unregisterPanel(panel); + } + } +} + +export class PaletteNameWidget extends TextInputWidget { + constructor(public name: TrackableValue) { + super(name); + const { element } = this; + element.classList.add("neuroglancer-tool-palette-name"); + element.title = "Rename tool palette"; + } +} + +export class PaletteListDropdownItem extends RefCounted { + element = document.createElement("li"); + constructor(public state: ToolPaletteState) { + super(); + const { element } = this; + element.appendChild( + this.registerDisposer( + new TrackableBooleanCheckbox(state.location.watchableVisible, { + enableTitle: "Show tool palette", + disableTitle: "Hide tool palette", + }), + ).element, + ); + element.appendChild( + this.registerDisposer(new PaletteNameWidget(state.name)).element, + ); + const deleteButton = makeDeleteButton({ title: "Delete tool palette" }); + deleteButton.addEventListener("click", () => { + state.dispose(); + }); + element.appendChild(deleteButton); + } +} + +interface CannedPalette { + name: string; + description?: string; + query: string; +} + +class PaletteListCannedDropdownItem { + element = document.createElement("li"); + constructor( + public state: MultiToolPaletteState, + public palette: CannedPalette, + ) { + const { element } = this; + element.classList.add("neuroglancer-tool-palette-dropdown-canned-item"); + element.textContent = palette.description ?? palette.name; + element.addEventListener("click", () => { + const newPalette = state.addNew({ name: palette.name }); + newPalette.query.value = palette.query; + }); + } +} + +export const CANNED_PALETTES: CannedPalette[] = [ + { name: "Palette", description: "New empty palette", query: "" }, + { name: "All controls", query: "+" }, + { name: "Shader controls", query: "type:shaderControl" }, +]; + +export class MultiToolPaletteDropdown extends RefCounted { + element = document.createElement("div"); + itemContainer = document.createElement("ul"); + items = new Map(); + cannedItems = new Map(); + cannedItemSeparator = document.createElement("li"); + constructor(private state: MultiToolPaletteState) { + super(); + const { element, itemContainer, cannedItemSeparator } = this; + element.classList.add("neuroglancer-tool-palette-dropdown"); + + cannedItemSeparator.classList.add( + "neuroglancer-tool-palette-dropdown-separator", + ); + + element.appendChild(itemContainer); + const debouncedUpdateView = this.registerCancellable( + animationFrameDebounce(() => this.updateView()), + ); + this.registerDisposer(this.state.changedShallow.add(debouncedUpdateView)); + this.updateView(); + } + + private updateView() { + const self = this; + function* getItems() { + const { palettes } = self.state; + const seenQueries = new Set(); + const { items } = self; + for (const palette of palettes) { + let item = items.get(palette); + if (item === undefined) { + item = new PaletteListDropdownItem(palette); + items.set(palette, item); + } + seenQueries.add(palette.query.value); + yield item.element; + } + let firstCannedItem = true; + const { cannedItems } = self; + for (const palette of CANNED_PALETTES) { + if (palette.query !== "" && seenQueries.has(palette.query)) { + continue; + } + let item = cannedItems.get(palette); + if (item === undefined) { + item = new PaletteListCannedDropdownItem(self.state, palette); + cannedItems.set(palette, item); + } + if (firstCannedItem) { + firstCannedItem = false; + if (palettes.size !== 0) { + yield self.cannedItemSeparator; + } + } + yield item.element; + } + for (const [palette, item] of items) { + if (!palettes.has(palette)) { + items.delete(palette); + item.dispose(); + } + } + } + updateChildren(this.itemContainer, getItems()); + } + + disposed() { + super.disposed(); + removeFromParent(this.element); + } +} + +export class MultiToolPaletteDropdownButton extends RefCounted { + countElement = document.createElement("div"); + dropdownVisible = new WatchableValue(false); + dropdown: MultiToolPaletteDropdown | undefined; + element = document.createElement("div"); + constructor(private state: MultiToolPaletteState) { + super(); + const { element, countElement } = this; + + const checkbox = this.registerDisposer( + new CheckboxIcon(this.dropdownVisible, { + svg: svg_tool, + enableTitle: "Show tool palette list (control+click to create new)", + disableTitle: "Hide tool palette list", + backgroundScheme: "dark", + }), + ).element; + element.appendChild(checkbox); + element.classList.add("neuroglancer-tool-palette-button"); + element.classList.add("neuroglancer-sticky-focus"); + element.tabIndex = -1; + + const debouncedUpdateView = this.registerCancellable( + animationFrameDebounce(() => this.updateView()), + ); + this.registerDisposer(state.changedShallow.add(debouncedUpdateView)); + this.registerDisposer(state.visibleStateChanged.add(debouncedUpdateView)); + + element.addEventListener("focusout", (event) => { + const { relatedTarget } = event; + if (relatedTarget instanceof Node && !element.contains(relatedTarget)) { + this.dropdownVisible.value = false; + } + }); + checkbox.insertAdjacentElement("afterbegin", countElement); + this.dropdownVisible.changed.add(() => { + const visible = this.dropdownVisible.value; + if (!visible) { + this.dropdown?.dispose(); + this.dropdown = undefined; + } else { + if (this.dropdown === undefined) { + this.dropdown = new MultiToolPaletteDropdown(this.state); + this.element.appendChild(this.dropdown.element); + positionRelativeDropdown(this.dropdown.element, this.element); + } + } + }); + this.updateView(); + } + + private updateView() { + const totalPalettes = this.state.palettes.size; + let visiblePalettes = 0; + for (const palette of this.state.palettes) { + if (palette.location.visible) ++visiblePalettes; + } + this.countElement.textContent = + visiblePalettes < totalPalettes + ? `${visiblePalettes}/${totalPalettes}` + : ""; + } + + disposed() { + this.dropdown?.dispose(); + } +} diff --git a/src/ui/tool_query.spec.ts b/src/ui/tool_query.spec.ts new file mode 100644 index 0000000000..3960bfca62 --- /dev/null +++ b/src/ui/tool_query.spec.ts @@ -0,0 +1,322 @@ +import { describe, test, expect } from "vitest"; +import { + getCompletionOffset, + getQueryTermToComplete, + parsePartialToolQuery, + parseToolQuery, +} from "#src/ui/tool_query.js"; + +describe("parseQuery", () => { + test("simple term", () => { + expect(parseToolQuery("type:shaderControl")).toMatchInlineSnapshot(` + { + "query": { + "clauses": [ + { + "include": true, + "range": { + "begin": 0, + "end": 18, + }, + "terms": [ + { + "predicate": { + "equals": "shaderControl", + }, + "property": "type", + "range": { + "begin": 0, + "end": 18, + }, + }, + ], + }, + ], + }, + } + `); + }); + + test("multiple terms", () => { + expect(parseToolQuery("+type:shaderControl layer:image")) + .toMatchInlineSnapshot(` + { + "query": { + "clauses": [ + { + "include": true, + "range": { + "begin": 0, + "end": 31, + }, + "terms": [ + { + "predicate": { + "equals": "shaderControl", + }, + "property": "type", + "range": { + "begin": 1, + "end": 19, + }, + }, + { + "predicate": { + "equals": "image", + }, + "property": "layer", + "range": { + "begin": 20, + "end": 31, + }, + }, + ], + }, + ], + }, + } + `); + }); + + test("multiple clauses", () => { + expect(parseToolQuery("+type:shaderControl -layer:image")) + .toMatchInlineSnapshot(` + { + "query": { + "clauses": [ + { + "include": true, + "range": { + "begin": 0, + "end": 19, + }, + "terms": [ + { + "predicate": { + "equals": "shaderControl", + }, + "property": "type", + "range": { + "begin": 1, + "end": 19, + }, + }, + ], + }, + { + "include": false, + "range": { + "begin": 20, + "end": 32, + }, + "terms": [ + { + "predicate": { + "equals": "image", + }, + "property": "layer", + "range": { + "begin": 21, + "end": 32, + }, + }, + ], + }, + ], + }, + } + `); + }); + + test("quoted value", () => { + expect(parseToolQuery(`type:"shaderControl"`)).toMatchInlineSnapshot(` + { + "query": { + "clauses": [ + { + "include": true, + "range": { + "begin": 0, + "end": 20, + }, + "terms": [ + { + "predicate": { + "equals": "shaderControl", + }, + "property": "type", + "range": { + "begin": 0, + "end": 20, + }, + }, + ], + }, + ], + }, + } + `); + }); + + test("regexp value", () => { + expect(parseToolQuery(`type:/shaderControl/`)).toMatchInlineSnapshot(` + { + "query": { + "clauses": [ + { + "include": true, + "range": { + "begin": 0, + "end": 20, + }, + "terms": [ + { + "predicate": { + "regexp": /shaderControl/i, + }, + "property": "type", + "range": { + "begin": 0, + "end": 20, + }, + }, + ], + }, + ], + }, + } + `); + }); + + test("invalid term", () => { + expect(parseToolQuery(`a`)).toMatchInlineSnapshot(` + { + "errors": [ + { + "message": "Invalid clause/term", + "range": { + "begin": 0, + "end": 1, + }, + }, + ], + } + `); + }); + + test("empty clause", () => { + expect(parseToolQuery(`+`)).toMatchInlineSnapshot(` + { + "query": { + "clauses": [ + { + "include": true, + "range": { + "begin": 0, + "end": 1, + }, + "terms": [], + }, + ], + }, + } + `); + }); + + test("duplicate property", () => { + expect(parseToolQuery("type:shaderControl type:shaderControl")) + .toMatchInlineSnapshot(` + { + "errors": [ + { + "message": "Property "type" cannot be constrained by more than one term in a clause", + "range": { + "begin": 19, + "end": 23, + }, + }, + ], + } + `); + }); +}); + +describe("getCompletionOffset", () => { + test("property value", () => { + expect( + getCompletionOffset(parsePartialToolQuery("layerType:im")), + ).toMatchInlineSnapshot(`0`); + }); +}); + +describe("getQueryTermToComplete", () => { + test("property value", () => { + expect(getQueryTermToComplete(parsePartialToolQuery("layerType:im"))) + .toMatchInlineSnapshot(` + { + "completionQuery": { + "clauses": [ + { + "include": true, + "range": { + "begin": -1, + "end": -1, + }, + "terms": [ + { + "predicate": { + "regexp": /\\^im/, + }, + "property": "layerType", + "range": { + "begin": -1, + "end": -1, + }, + }, + ], + }, + ], + }, + "include": true, + "offset": 10, + "prefix": "im", + "property": "layerType", + } + `); + }); + + test("property name after existing term", () => { + expect(getQueryTermToComplete(parsePartialToolQuery("layerType:image j"))) + .toMatchInlineSnapshot(` + { + "completionQuery": { + "clauses": [ + { + "include": true, + "range": { + "begin": -1, + "end": -1, + }, + "terms": [ + { + "predicate": { + "equals": "image", + }, + "property": "layerType", + "range": { + "begin": 0, + "end": 15, + }, + }, + ], + }, + ], + }, + "include": true, + "offset": 16, + "prefix": "j", + "property": undefined, + } + `); + }); +}); diff --git a/src/ui/tool_query.ts b/src/ui/tool_query.ts new file mode 100644 index 0000000000..6443895124 --- /dev/null +++ b/src/ui/tool_query.ts @@ -0,0 +1,353 @@ +/** + * @license + * Copyright 2024 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { escapeRegExp } from "lodash-es"; +import { defaultStringCompare } from "#src/util/string.js"; + +export type PropertyPredicate = { equals: string } | { regexp: RegExp }; + +export interface QueryRange { + begin: number; + end: number; +} + +export interface QueryTerm { + // Start offset in query string; + range: QueryRange; + property: string; + predicate: PropertyPredicate; +} + +// A clause specifies a conjunction (AND) of terms. All tools matching the +// clause are either included or excluded from the overall results. +export interface QueryClause { + // Indicates if this clause is an inclusion or an exclusion. + include: boolean; + range: QueryRange; + terms: QueryTerm[]; +} + +// A query specifies an ordered list of inclusion/exclusion clauses. +export interface Query { + clauses: QueryClause[]; +} + +export interface ParseError { + range: QueryRange; + message: string; +} + +const TOKEN_PATTERN = + /^(\s*)(?:(\+|-)|([a-zA-Z]+):(?:("(?:[^"\\]|\\.)*")|([^\s"/][^\s"]*)|\/((?:[^/\\]|\\.)*)\/)(?=$|\s))/; + +export interface PartialQuery { + raw: string; + query: Query; + errors: ParseError[]; + endOffset: number; +} + +export function parsePartialToolQuery(query: string): PartialQuery { + let offset = 0; + const raw = query; + + const parsedQuery: Query = { clauses: [] }; + let currentClause: QueryClause | undefined; + + const errors: ParseError[] = []; + + const endClause = () => { + if (currentClause === undefined) return; + if (currentClause.terms.length === 0) { + if (currentClause.include === false) { + errors.push({ + range: { begin: currentClause.range.begin, end: offset }, + message: "Exclusion clause must have at least one term", + }); + } + currentClause.range.end = offset; + parsedQuery.clauses.push(currentClause); + } else { + currentClause.range.end = + currentClause.terms[currentClause.terms.length - 1].range.end; + parsedQuery.clauses.push(currentClause); + } + }; + + for (let nextOffset: number; true; offset = nextOffset) { + // Parse include/exclude token. + const tokenMatch = query.match(TOKEN_PATTERN); + + if (tokenMatch === null) { + break; + } + + const matchLength = tokenMatch[0].length; + nextOffset = offset + matchLength; + query = query.substring(matchLength); + + const skipLength = tokenMatch[1].length; + + const includeExclude = tokenMatch[2]; + if (includeExclude !== undefined) { + // New clause + endClause(); + currentClause = { + range: { begin: offset + skipLength, end: -1 }, + include: includeExclude === "+", + terms: [], + }; + continue; + } + + const propertyName = tokenMatch[3]; + if (currentClause === undefined) { + currentClause = { + range: { begin: offset + skipLength, end: -1 }, + include: true, + terms: [], + }; + } else { + // Check that property is not already present in this clause. + if ( + currentClause.terms.find((term) => term.property === propertyName) !== + undefined + ) { + errors.push({ + range: { + begin: offset + skipLength, + end: offset + skipLength + propertyName.length, + }, + message: `Property ${JSON.stringify(propertyName)} cannot be constrained by more than one term in a clause`, + }); + } + } + + let predicate: PropertyPredicate; + + const quoted = tokenMatch[4]; + if (quoted !== undefined) { + predicate = { equals: JSON.parse(quoted) }; + } else { + const unquoted = tokenMatch[5]; + if (unquoted !== undefined) { + predicate = { equals: unquoted }; + } else { + try { + const regexp = new RegExp(tokenMatch[6], "i"); + predicate = { regexp }; + } catch (e) { + errors.push({ + range: { + begin: offset + skipLength + propertyName.length + 2, + end: nextOffset - 1, + }, + message: (e as SyntaxError).message, + }); + predicate = { equals: "" }; + } + } + } + + currentClause.terms.push({ + range: { begin: offset + skipLength, end: nextOffset }, + property: propertyName, + predicate, + }); + continue; + } + + endClause(); + + // Skip whitespace before ending parsing. + { + const m = query.match(/^\s*/); + if (m !== null) { + offset += m[0].length; + } + } + + return { raw, query: parsedQuery, errors, endOffset: offset }; +} + +export function parseToolQuery( + query: string, +): { query: Query } | { errors: ParseError[] } { + const result = parsePartialToolQuery(query); + if (result.endOffset !== query.length) { + result.errors.push({ + range: { begin: result.endOffset, end: query.length }, + message: "Invalid clause/term", + }); + } + if (result.errors.length > 0) { + return { errors: result.errors }; + } + return { query: result.query }; +} + +export function matchPredicate(predicate: PropertyPredicate, value: string) { + if ("equals" in predicate) { + return predicate.equals === value; + } else { + return value.match(predicate.regexp) !== null; + } +} + +export function matchesTerms(toolJson: any, terms: QueryTerm[]) { + for (const term of terms) { + const value = toolJson[term.property]; + if (typeof value !== "string") return false; + if (!matchPredicate(term.predicate, value)) return false; + } + return true; +} + +export interface QueryCompletion { + offset: number; + prefix: string; + property?: string; + include: boolean; + completionQuery: Query; +} + +export function getCompletionOffset(query: PartialQuery): number { + const { clauses } = query.query; + if (query.endOffset === query.raw.length && clauses.length !== 0) { + const { range, terms } = clauses[clauses.length - 1]; + if (range.end === query.endOffset && terms.length !== 0) { + const lastTerm = terms[terms.length - 1]; + // Remove last term since it will be completed. + terms.length = terms.length - 1; + return lastTerm.range.begin; + } + } + + return query.endOffset; +} + +const PARTIAL_TERM_PATTERN = /^([a-zA-Z]+):/; + +export function getQueryTermToComplete(query: PartialQuery): QueryCompletion { + const termOffset = getCompletionOffset(query); + let prefix = query.raw.substring(termOffset); + let property: string | undefined; + const m = prefix.match(PARTIAL_TERM_PATTERN); + + const include = + query.query.clauses.length == 0 || + query.query.clauses[query.query.clauses.length - 1].include; + let offset: number; + if (m === null) { + offset = termOffset; + } else { + offset = termOffset + m[1].length + 1; + property = m[1]; + prefix = prefix.substring(m[1].length + 1); + } + + const completionQuery: Query = { clauses: [] }; + + const { clauses } = query.query; + const currentTerms: QueryTerm[] = []; + if (clauses.length !== 0) { + currentTerms.push(...clauses[clauses.length - 1].terms); + } + if (property !== undefined) { + currentTerms.push({ + property, + predicate: { regexp: new RegExp("^" + escapeRegExp(prefix)) }, + range: { begin: -1, end: -1 }, + }); + } + + if (include) { + completionQuery.clauses.push({ + include: true, + terms: currentTerms, + range: { begin: -1, end: -1 }, + }); + + // All other clauses are inverted + for (let i = 0, numClauses = clauses.length - 1; i < numClauses; ++i) { + const clause = clauses[i]; + completionQuery.clauses.push({ + include: !clause.include, + terms: clause.terms, + range: clause.range, + }); + } + } else { + for (let i = 0, numClauses = clauses.length - 1; i < numClauses; ++i) { + const clause = clauses[i]; + let terms = clause.terms; + if (clause.include) { + terms = [...terms, ...currentTerms]; + } + completionQuery.clauses.push({ + include: clause.include, + terms, + range: clause.range, + }); + } + } + return { offset, prefix, property, include, completionQuery }; +} + +function getSortedCompletions(values: Map) { + const result = Array.from(values); + result.sort((a, b) => defaultStringCompare(a[0], b[0])); + return result; +} + +export function getPropertyNameCompletions( + completionQuery: Query, + matches: Map, + prefix: string, +) { + const existingPropertyNames = new Set( + Array.from(completionQuery.clauses[0].terms, (term) => term.property), + ); + const properties = new Map(); + for (const match of matches.values()) { + for (const property in match) { + if (!property.startsWith(prefix) || existingPropertyNames.has(property)) { + continue; + } + const value = property + ":"; + const existing = properties.get(value) ?? 0; + properties.set(value, existing + 1); + } + } + return getSortedCompletions(properties); +} + +export function getPropertyValueCompletions( + matches: Map, + property: string, +) { + const values = new Map(); + for (const match of matches.values()) { + const value = "" + match[property]; + const existing = values.get(value) ?? 0; + values.set(value, existing + 1); + } + return getSortedCompletions(values); +} + +export const INCLUDE_EVERYTHING_QUERY: Query = { + clauses: [{ include: true, terms: [], range: { begin: -1, end: -1 } }], +}; diff --git a/src/ui/url_hash_binding.ts b/src/ui/url_hash_binding.ts index 5c338cb5e7..978942494c 100644 --- a/src/ui/url_hash_binding.ts +++ b/src/ui/url_hash_binding.ts @@ -15,16 +15,11 @@ */ import { debounce } from "lodash-es"; -import type { CredentialsManager } from "#src/credentials_provider/index.js"; +import type { SharedKvStoreContext } from "#src/kvstore/frontend.js"; import { StatusMessage } from "#src/status.js"; import { WatchableValue } from "#src/trackable_value.js"; import { RefCounted } from "#src/util/disposable.js"; -import { responseJson } from "#src/util/http_request.js"; import { urlSafeParse, verifyObject } from "#src/util/json.js"; -import { - cancellableFetchSpecialOk, - parseSpecialUrl, -} from "#src/util/special_protocol_request.js"; import type { Trackable } from "#src/util/trackable.js"; import { getCachedJson } from "#src/util/trackable.js"; @@ -71,7 +66,7 @@ export class UrlHashBinding extends RefCounted { constructor( public root: Trackable, - public credentialsManager: CredentialsManager, + public sharedKvStoreContext: SharedKvStoreContext, options: UrlHashBindingOptions = {}, ) { super(); @@ -122,21 +117,15 @@ export class UrlHashBinding extends RefCounted { // Handle remote JSON state if (s.match(/^#!([a-z][a-z\d+-.]*):\/\//)) { const url = s.substring(2); - const { url: parsedUrl, credentialsProvider } = parseSpecialUrl( - url, - this.credentialsManager, - ); StatusMessage.forPromise( - cancellableFetchSpecialOk( - credentialsProvider, - parsedUrl, - {}, - responseJson, - ).then((json) => { - verifyObject(json); - this.root.reset(); - this.root.restoreState(json); - }), + this.sharedKvStoreContext.kvStoreContext + .read(url, { throwIfMissing: true }) + .then((response) => response.response.json()) + .then((json) => { + verifyObject(json); + this.root.reset(); + this.root.restoreState(json); + }), { initialMessage: `Loading state from ${url}`, errorPrefix: "Error loading state:", diff --git a/src/util/abort.spec.ts b/src/util/abort.spec.ts new file mode 100644 index 0000000000..06ca844922 --- /dev/null +++ b/src/util/abort.spec.ts @@ -0,0 +1,91 @@ +/** + * @license + * Copyright 2016 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { describe, expect, test } from "vitest"; +import { raceWithAbort, SharedAbortController } from "#src/util/abort.js"; + +describe("SharedAbortController", () => { + test("supports abort from two consumers", async () => { + const sharedController = new SharedAbortController(); + const controller1 = new AbortController(); + sharedController.addConsumer(controller1.signal); + const controller2 = new AbortController(); + sharedController.addConsumer(controller2.signal); + controller1.abort(); + expect(sharedController.signal.aborted).toBe(false); + expect(sharedController.signal.aborted).toBe(false); + controller2.abort(); + expect(sharedController.signal.aborted).toBe(true); + }); + + test("supports undefined AbortSignal", async () => { + const sharedController = new SharedAbortController(); + const controller1 = new AbortController(); + sharedController.addConsumer(controller1.signal); + sharedController.addConsumer(undefined); + controller1.abort(); + await Promise.resolve(); + expect(sharedController.signal.aborted).toBe(false); + }); + + test("supports dispose", async () => { + const controller1 = new AbortController(); + let called = false; + { + using sharedController = new SharedAbortController(); + sharedController.addConsumer(controller1.signal); + sharedController.signal.addEventListener("abort", () => { + called = true; + }); + } + expect(called).toBe(false); + controller1.abort(); + expect(called).toBe(false); + }); +}); + +describe("raceWithAbort", () => { + test("undefined signal", () => { + const promise = Promise.resolve(5); + expect(raceWithAbort(promise, undefined)).toBe(promise); + }); + + test("already aborted signal", async () => { + const controller = new AbortController(); + controller.abort(); + const promise = new Promise((_resolve, _reject) => {}); + await expect(() => + raceWithAbort(promise, controller.signal), + ).rejects.toThrowError(/aborted/); + }); + + test("not abort signal", async () => { + const controller = new AbortController(); + controller.abort(); + const promise = new Promise((_resolve, _reject) => {}); + await expect(() => + raceWithAbort(promise, controller.signal), + ).rejects.toThrowError(/aborted/); + }); + + test("aborted later signal", async () => { + const controller = new AbortController(); + const promise = new Promise((_resolve, _reject) => {}); + const wrappedPromise = raceWithAbort(promise, controller.signal); + controller.abort(); + await expect(() => wrappedPromise).rejects.toThrowError(/aborted/); + }); +}); diff --git a/src/util/abort.ts b/src/util/abort.ts new file mode 100644 index 0000000000..da3b37908f --- /dev/null +++ b/src/util/abort.ts @@ -0,0 +1,137 @@ +/** + * @license + * Copyright 2024 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export function scopedAbortCallback( + signal: AbortSignal | undefined, + callback: (reason: any) => void, +): Disposable | undefined { + if (signal === undefined) return undefined; + if (signal.aborted) { + callback(signal.reason); + return undefined; + } + function wrappedCallback(this: AbortSignal) { + callback(this.reason); + } + signal.addEventListener("abort", wrappedCallback, { once: true }); + return { + [Symbol.dispose]() { + signal.removeEventListener("abort", wrappedCallback); + }, + }; +} + +// Abort controller that aborts when *all* consumers have aborted. +export class SharedAbortController { + private consumers = new Map<(this: AbortSignal) => void, AbortSignal>(); + private controller = new AbortController(); + private retainCount = 0; + + get signal(): AbortSignal { + return this.controller.signal; + } + + addConsumer(signal: AbortSignal | undefined): void { + if (this.controller.signal.aborted) return undefined; + if (signal !== undefined) { + if (signal.aborted) return; + const self = this; + function wrappedCallback(this: AbortSignal) { + self.consumers.delete(wrappedCallback); + if (--self.retainCount === 0) { + self.controller.abort(); + self[Symbol.dispose](); + } + } + signal.addEventListener("abort", wrappedCallback, { once: true }); + } + ++this.retainCount; + } + + [Symbol.dispose](): void { + for (const [wrappedCallback, signal] of this.consumers) { + signal.removeEventListener("abort", wrappedCallback); + } + this.consumers.clear(); + this.retainCount = 0; + } + + // Marks this controller as started. Aborts if there are no consumers. + start(): void { + if (this.retainCount === 0) { + this.controller.abort(); + } + } +} + +export function promiseWithResolversAndAbortCallback( + signal: AbortSignal, + abortCallback: (reason: any) => void, +): { + promise: Promise; + resolve: (value: T) => void; + reject: (reason: any) => void; +} { + const { promise, resolve, reject } = Promise.withResolvers(); + const cleanup = scopedAbortCallback(signal, abortCallback); + return { + promise, + resolve: (value: T) => { + cleanup?.[Symbol.dispose](); + resolve(value); + }, + reject: (reason: any) => { + cleanup?.[Symbol.dispose](); + reject(reason); + }, + }; +} + +export function raceWithAbort( + promise: Promise, + signal: AbortSignal | undefined, +): Promise { + if (signal === undefined) return promise; + if (signal.aborted) return Promise.reject(signal.reason); + + return new Promise((resolve, reject) => { + const cleanup = scopedAbortCallback(signal, (reason) => { + reject(reason); + }); + promise.then( + (value) => { + cleanup?.[Symbol.dispose](); + resolve(value); + }, + (reason) => { + cleanup?.[Symbol.dispose](); + reject(reason); + }, + ); + }); +} + +export function abortPromise(signal: AbortSignal) { + return new Promise((_resolve, reject) => { + signal.addEventListener( + "abort", + () => { + reject(signal.reason); + }, + { once: true }, + ); + }); +} diff --git a/src/util/array.ts b/src/util/array.ts index c18e90cc87..64d30a29a2 100644 --- a/src/util/array.ts +++ b/src/util/array.ts @@ -63,35 +63,42 @@ export function filterArrayInplace( array.length = outIndex; } -export type TypedArrayConstructor = - | typeof Int8Array - | typeof Uint8Array - | typeof Int16Array - | typeof Uint16Array - | typeof Int32Array - | typeof Uint32Array - | typeof Float32Array - | typeof Float64Array; +export type TypedArrayConstructor< + TArrayBuffer extends ArrayBufferLike = ArrayBufferLike, +> = ( + | typeof Int8Array + | typeof Uint8Array + | typeof Int16Array + | typeof Uint16Array + | typeof Int32Array + | typeof Uint32Array + | typeof Float32Array + | typeof Float64Array +) & + (TArrayBuffer extends ArrayBuffer + ? { new (count: number): TypedArray } + : Record); -export type TypedArray = - | Int8Array - | Uint8Array - | Int16Array - | Uint16Array - | Int32Array - | Uint32Array - | Float32Array - | Float64Array; +export type TypedArray = + + | Int8Array + | Uint8Array + | Int16Array + | Uint16Array + | Int32Array + | Uint32Array + | Float32Array + | Float64Array; /** * Returns an array of size newSize that starts with the contents of array. * Either returns array if it has the correct size, or a new array with zero * padding at the end. */ -export function maybePadArray( - array: T, - newSize: number, -): T { +export function maybePadArray< + TArrayBuffer extends ArrayBufferLike, + T extends TypedArray, +>(array: T, newSize: number): T { if (array.length === newSize) { return array; } @@ -163,13 +170,13 @@ export function tile2dArray( return result; } -export function binarySearch( - haystack: ArrayLike, - needle: T, - compare: (a: T, b: T) => number, +export function binarySearch( + haystack: ArrayLike, + needle: Needle, + compare: (a: Needle, b: Hay) => number, low = 0, high = haystack.length, -) { +): number { while (low < high) { const mid = (low + high - 1) >> 1; const compareResult = compare(needle, haystack[mid]); diff --git a/src/util/byte_range_http_requests.ts b/src/util/byte_range_http_requests.ts deleted file mode 100644 index 440d9d0efc..0000000000 --- a/src/util/byte_range_http_requests.ts +++ /dev/null @@ -1,52 +0,0 @@ -/** - * @license - * Copyright 2019 Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import type { CancellationToken } from "#src/util/cancellation.js"; -import { - getByteRangeHeader, - responseArrayBuffer, -} from "#src/util/http_request.js"; -import type { SpecialProtocolCredentialsProvider } from "#src/util/special_protocol_request.js"; -import { cancellableFetchSpecialOk } from "#src/util/special_protocol_request.js"; -import type { Uint64 } from "#src/util/uint64.js"; - -/** - * On Chromium, multiple concurrent byte range requests to the same URL are serialized unless the - * cache is disabled. Disabling the cache works around the problem. - * - * https://bugs.chromium.org/p/chromium/issues/detail?id=969828 - */ -const cacheMode = - navigator.userAgent.indexOf("Chrome") !== -1 ? "no-store" : "default"; - -export function fetchSpecialHttpByteRange( - credentialsProvider: SpecialProtocolCredentialsProvider, - url: string, - startOffset: Uint64 | number, - endOffset: Uint64 | number, - cancellationToken: CancellationToken, -): Promise { - return cancellableFetchSpecialOk( - credentialsProvider, - url, - { - headers: getByteRangeHeader(startOffset, endOffset), - cache: cacheMode, - }, - responseArrayBuffer, - cancellationToken, - ); -} diff --git a/src/util/cancellation.spec.ts b/src/util/cancellation.spec.ts deleted file mode 100644 index f1f9cfad50..0000000000 --- a/src/util/cancellation.spec.ts +++ /dev/null @@ -1,175 +0,0 @@ -/** - * @license - * Copyright 2016 Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { describe, expect, it } from "vitest"; - -import { - CANCELED, - CancellationTokenSource, - makeCancelablePromise, - MultipleConsumerCancellationTokenSource, - throwIfCanceled, - uncancelableToken, -} from "#src/util/cancellation.js"; - -describe("cancellation", () => { - describe("CancellationTokenSource", () => { - it("supports cancel", () => { - const source = new CancellationTokenSource(); - expect(source.isCanceled).toBe(false); - source.cancel(); - expect(source.isCanceled).toBe(true); - source.cancel(); - expect(source.isCanceled).toBe(true); - }); - - it("supports add", () => { - const source = new CancellationTokenSource(); - const log: number[] = []; - const handler = () => { - log.push(1); - }; - source.add(handler); - source.cancel(); - expect(log).toEqual([1]); - source.cancel(); - expect(log).toEqual([1]); - }); - - it("supports add after cancel", () => { - const source = new CancellationTokenSource(); - source.cancel(); - const log: number[] = []; - const handler = () => { - log.push(1); - }; - source.add(handler); - expect(log).toEqual([1]); - }); - - it("supports remove", () => { - const source = new CancellationTokenSource(); - const log: number[] = []; - const handler = () => { - log.push(1); - }; - source.add(handler); - source.remove(handler); - source.cancel(); - expect(log).toEqual([]); - }); - - it("supports throwIfCanceled", () => { - const source = new CancellationTokenSource(); - expect(() => throwIfCanceled(source)).not.toThrow(); - source.cancel(); - expect(() => throwIfCanceled(source)).toThrow(CANCELED); - }); - }); - - describe("uncancelableToken", () => { - it("supports isCanceled", () => { - expect(uncancelableToken.isCanceled).toBe(false); - }); - - it("supports add", () => { - uncancelableToken.add(() => {}); - }); - - it("supports remove", () => { - const handler = () => {}; - uncancelableToken.add(handler); - uncancelableToken.remove(handler); - }); - }); - - describe("MultipleConsumerCancellationTokenSource", () => { - it("supports cancellation from two consumers", () => { - const multiToken = new MultipleConsumerCancellationTokenSource(); - const token1 = new CancellationTokenSource(); - multiToken.addConsumer(token1); - const token2 = new CancellationTokenSource(); - multiToken.addConsumer(token2); - token1.cancel(); - expect(multiToken.isCanceled).toBe(false); - token2.cancel(); - expect(multiToken.isCanceled).toBe(true); - }); - - it("supports cancellation from three consumers", () => { - const multiToken = new MultipleConsumerCancellationTokenSource(); - const token1 = new CancellationTokenSource(); - multiToken.addConsumer(token1); - const token2 = new CancellationTokenSource(); - multiToken.addConsumer(token2); - token1.cancel(); - expect(multiToken.isCanceled).toBe(false); - const token3 = new CancellationTokenSource(); - multiToken.addConsumer(token3); - token2.cancel(); - expect(multiToken.isCanceled).toBe(false); - token3.cancel(); - expect(multiToken.isCanceled).toBe(true); - }); - }); - - describe("makeCancellablePromise", () => { - it("supports basic resolve behavior", async () => { - const promise = makeCancelablePromise( - uncancelableToken, - (resolve, _reject, _token) => { - resolve(3); - }, - ); - expect(await promise).toBe(3); - }); - it("supports basic reject behavior", async () => { - const promise = makeCancelablePromise( - uncancelableToken, - (_resolve, reject, _token) => { - reject(new Error("abc")); - }, - ); - expect(promise).rejects.toThrow("abc"); - }); - - it("unregisters the cancellation handler when the promise is fulfilled", () => { - const source = new CancellationTokenSource(); - const log: string[] = []; - makeCancelablePromise(source, (resolve, _reject, token) => { - token.add(() => { - log.push("cancel called"); - }); - resolve(1); - source.cancel(); - expect(log).toEqual([]); - }); - }); - - it("unregisters the cancellation handler when the promise is rejected", () => { - const source = new CancellationTokenSource(); - const log: string[] = []; - makeCancelablePromise(source, (_resolve, reject, token) => { - token.add(() => { - log.push("cancel called"); - }); - reject(1); - source.cancel(); - expect(log).toEqual([]); - }).catch(() => null); - }); - }); -}); diff --git a/src/util/cancellation.ts b/src/util/cancellation.ts deleted file mode 100644 index e4e031b660..0000000000 --- a/src/util/cancellation.ts +++ /dev/null @@ -1,206 +0,0 @@ -/** - * @license - * Copyright 2016 Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @file - * Cancellation token system with similarity to the cancellation_token in Microsoft's PPL. - */ - -/** - * Interface used by cancelable operations to monitor whether cancellation has occurred. - * - * Note that this interface does not provide any way to trigger cancellation; for that, - * CancellationTokenSource is used. - */ -export interface CancellationToken { - /** - * Indicates whether cancellation has occurred. - */ - readonly isCanceled: boolean; - - /** - * Add a cancellation handler function. The handler will be invoked synchronously if - * this.isCanceled === true. Otherwise, it will be invoked synchronously upon cancellation, - * unless it is removed prior to cancellation. - * - * The handler function must not throw any exceptions when called. - * - * @precondition The handler function must not already be registered. - * - * @param handler The handler function to add. - * - * @return A function that unregisters the handler. - */ - add(handler: () => void): () => void; - - /** - * Unregister a cancellation handler function. If this.isCanceled, or the specified handler - * function has not been registered, then this function has no effect. - */ - remove(handler: () => void): void; -} - -export class CancellationError extends Error { - name = "CancellationError"; - message = "CANCELED"; - toString() { - return "CANCELED"; - } -} - -/** - * Singleton instance of CancellationError thrown to indicate cancellation. - */ -export const CANCELED = new CancellationError(); - -/** - * Throws CANCELED if token.isCanceled === true. - */ -export function throwIfCanceled(token: CancellationToken) { - if (token.isCanceled === true) { - throw CANCELED; - } -} - -const noopFunction = () => {}; - -/** - * CancellationToken that cannot be canceled. This can be passed to operations that require a - * CancellationToken but will not need to be canceled. - */ -export const uncancelableToken: CancellationToken = { - isCanceled: false, - add: () => noopFunction, - remove: noopFunction, -}; - -/** - * Class that can be used to trigger cancellation. - */ -export class CancellationTokenSource implements CancellationToken { - /** - * Trigger cancellation. - * - * If this.isCanceled === false, then each registered cancellation handler is invoked - * synchronously. - */ - cancel() { - const { handlers } = this; - if (handlers !== null) { - this.handlers = null; - if (handlers !== undefined) { - for (const handler of handlers) { - handler(); - } - } - } - } - - get isCanceled() { - return this.handlers === null; - } - - private handlers: Set<() => void> | undefined | null; - - add(handler: () => void) { - let { handlers } = this; - if (handlers === null) { - handler(); - return noopFunction; - } - if (handlers === undefined) { - handlers = this.handlers = new Set<() => void>(); - } - handlers.add(handler); - return () => { - this.remove(handler); - }; - } - - remove(handler: () => void) { - const { handlers } = this; - if (handlers != null) { - handlers.delete(handler); - } - } -} - -/** - * Creates a CancellationToken corresponding to an asynchronous process with multiple consumers. It - * is cancelled only when the cancellation tokens corresponding to all of the consumers have been - * cancelled. - */ -export class MultipleConsumerCancellationTokenSource extends CancellationTokenSource { - private consumers = new Set(); - - addConsumer(cancellationToken: CancellationToken = uncancelableToken) { - const { consumers } = this; - if (consumers.has(cancellationToken) || cancellationToken.isCanceled) { - return; - } - consumers.add(cancellationToken); - cancellationToken.add(() => { - consumers.delete(cancellationToken); - if (consumers.size === 0) { - this.cancel(); - } - }); - } -} - -/** - * Creates a promise and a dependent cancellation token. - * - * The dependent cancellation token will be canceled if the specified `cancellationToken` is - * canceled while the promise is pending. - * - * @param cancellationToken The token that provides notification of cancellation. - * @param executor The executor passed the resolve and reject functions for the promise, as well as - * the dependent cancellation token. If cancellation occurs after either resolve or reject is - * called, then the dependent token is not cancelled. - * - * @returns A new Promise. - */ -export function makeCancelablePromise( - cancellationToken: CancellationToken, - executor: ( - resolve: (value: T | Promise) => void, - reject: (error: any) => void, - token: CancellationToken, - ) => void, -) { - return new Promise((resolve, reject) => { - if (cancellationToken === uncancelableToken) { - executor(resolve, reject, uncancelableToken); - return; - } - const scopedToken = new CancellationTokenSource(); - const unregister = cancellationToken.add(() => { - scopedToken.cancel(); - }); - executor( - (value) => { - unregister(); - resolve(value); - }, - (error) => { - unregister(); - reject(error); - }, - scopedToken, - ); - }); -} diff --git a/src/util/completion.ts b/src/util/completion.ts index a406a70b0d..18fb332501 100644 --- a/src/util/completion.ts +++ b/src/util/completion.ts @@ -26,6 +26,12 @@ export interface CompletionWithDescription extends Completion { export interface BasicCompletionResult { completions: C[]; + // Default completion to show. + // + // If not specified, the longest common prefix of all completions is the + // "default completion" to show inline as a hint and to append if the user + // presses TAB. This option overrides that. + defaultCompletion?: string; offset: number; } diff --git a/src/util/data_type.ts b/src/util/data_type.ts index 3e478f4e15..8ce7db97e2 100644 --- a/src/util/data_type.ts +++ b/src/util/data_type.ts @@ -80,16 +80,18 @@ export const DATA_TYPE_JAVASCRIPT_ELEMENTS_PER_ARRAY_ELEMENT: Record< [DataType.FLOAT32]: 1, }; -export function makeDataTypeArrayView( +export function makeDataTypeArrayView( dataType: DataType, - buffer: ArrayBuffer, + buffer: TArrayBuffer, byteOffset = 0, byteLength: number = buffer.byteLength, -): ArrayBufferView { +): ArrayBufferView { const bytesPerElement = DATA_TYPE_BYTES[dataType]; const javascriptElementsPerArrayElement = DATA_TYPE_JAVASCRIPT_ELEMENTS_PER_ARRAY_ELEMENT[dataType]; - return new DATA_TYPE_ARRAY_CONSTRUCTOR[dataType]( + return new (DATA_TYPE_ARRAY_CONSTRUCTOR[ + dataType + ] as TypedArrayConstructor)( buffer, byteOffset, (byteLength / bytesPerElement) * javascriptElementsPerArrayElement, diff --git a/src/util/disposable.ts b/src/util/disposable.ts index dbcb95eea8..2ccedb327a 100644 --- a/src/util/disposable.ts +++ b/src/util/disposable.ts @@ -64,6 +64,9 @@ export class RefCounted implements Disposable { } this.refCountReachedZero(); } + [Symbol.dispose]() { + this.dispose(); + } protected refCountReachedZero() { this.disposed(); diff --git a/src/util/dom.ts b/src/util/dom.ts index 6a522923cd..b318034594 100644 --- a/src/util/dom.ts +++ b/src/util/dom.ts @@ -73,7 +73,7 @@ export function isInputTextTarget(target: EventTarget | null) { ) { return true; } - return false; + return target.closest(".neuroglancer-sticky-focus") !== null; } export function measureElementClone(element: HTMLElement) { diff --git a/src/util/drag_and_drop.ts b/src/util/drag_and_drop.ts index 5006c6fd4e..edf78c82cf 100644 --- a/src/util/drag_and_drop.ts +++ b/src/util/drag_and_drop.ts @@ -109,3 +109,39 @@ export function preventDrag(element: HTMLElement) { event.preventDefault(); }); } + +export function getDropEffectFromModifiers( + event: DragEvent, + defaultDropEffect: DropEffect, + moveAllowed: boolean, +): { dropEffect: DropEffect | "move" | "copy"; dropEffectMessage: string } { + let dropEffect: DropEffect | "move" | "copy"; + if (event.shiftKey) { + dropEffect = "copy"; + } else if (event.ctrlKey && moveAllowed) { + dropEffect = "move"; + } else { + dropEffect = defaultDropEffect; + } + let message = ""; + const addMessage = (msg: string) => { + if (message !== "") { + message += ", "; + } + message += msg; + }; + if (defaultDropEffect !== "none" && dropEffect !== defaultDropEffect) { + if (event.shiftKey) { + addMessage(`release SHIFT to ${defaultDropEffect}`); + } else { + addMessage(`release CONTROL to ${defaultDropEffect}`); + } + } + if (dropEffect !== "copy") { + addMessage("hold SHIFT to copy"); + } + if (dropEffect !== "move" && moveAllowed && defaultDropEffect !== "move") { + addMessage("hold CONTROL to move"); + } + return { dropEffect, dropEffectMessage: message }; +} diff --git a/src/util/dropdown.ts b/src/util/dropdown.ts index c79ca8a473..662b5312bb 100644 --- a/src/util/dropdown.ts +++ b/src/util/dropdown.ts @@ -62,6 +62,7 @@ export function positionDropdown( const distanceToBottom = viewportHeight - rect.bottom - bottomMargin; dropdownElement.style.left = `${rect.left}px`; dropdownElement.style.width = `${rect.width}px`; + dropdownElement.style.maxWidth = `${rect.width}px`; if (distanceToTop > distanceToBottom * 3) { dropdownElement.style.top = ""; dropdownElement.style.bottom = `${viewportHeight - rect.top}px`; @@ -77,3 +78,35 @@ export function positionDropdown( } } } + +export function positionRelativeDropdown( + dropdown: HTMLElement, + parent: HTMLElement, +) { + const rect = parent.getBoundingClientRect(); + const topMargin = 6; + const bottomMargin = 6; + + const { clientHeight: viewportWidth, clientWidth: viewportHeight } = + dropdown.ownerDocument!.documentElement!; + const distanceToTop = rect.top - topMargin; + const distanceToBottom = viewportHeight - rect.bottom - bottomMargin; + + if (rect.left < viewportWidth - rect.right) { + dropdown.style.left = "0px"; + dropdown.style.right = ""; + } else { + dropdown.style.right = "0px"; + dropdown.style.left = ""; + } + dropdown.style.maxWidth = `${rect.width}px`; + if (distanceToTop > distanceToBottom * 3) { + dropdown.style.top = ""; + dropdown.style.bottom = `${viewportHeight - rect.top}px`; + dropdown.style.maxHeight = distanceToTop + "px"; + } else { + dropdown.style.top = `${rect.bottom}px`; + dropdown.style.bottom = ""; + dropdown.style.maxHeight = distanceToBottom + "px"; + } +} diff --git a/src/util/error.ts b/src/util/error.ts index 3dd27e9554..64801ab29a 100644 --- a/src/util/error.ts +++ b/src/util/error.ts @@ -28,3 +28,19 @@ export function valueOrThrow(x: ValueOrError): T { if (x.error !== undefined) throw new Error(x.error); return x; } + +export function formatErrorMessage(error: unknown): string { + if (typeof error === "string") return error; + if (error instanceof Error) { + const { message, cause } = error; + if (cause !== undefined) { + return `${message}: ${formatErrorMessage(cause)}`; + } + return message; + } + try { + return "" + error; + } catch { + return "Unknown error"; + } +} diff --git a/src/util/float32array_builder.ts b/src/util/float32array_builder.ts index 271d5a6160..513e05e284 100644 --- a/src/util/float32array_builder.ts +++ b/src/util/float32array_builder.ts @@ -1,4 +1,4 @@ -// DO NOT EDIT. Generated from templates/neuroglancer/util/typedarray_builder.template.ts. +// DO NOT EDIT. Generated from templates/util/typedarray_builder.template.ts. /** * @license * Copyright 2016 Google Inc. @@ -17,9 +17,9 @@ export class Float32ArrayBuilder { length = 0; - data: Float32Array; + data: Float32Array; - constructor(initialCapacity = 16) { + constructor(initialCapacity: number = 16) { this.data = new Float32Array(initialCapacity); } @@ -35,7 +35,11 @@ export class Float32ArrayBuilder { get view() { const { data } = this; - return new Float32Array(data.buffer, data.byteOffset, this.length); + return new Float32Array( + data.buffer, + data.byteOffset, + this.length, + ); } shrinkToFit() { diff --git a/src/util/float64array_builder.ts b/src/util/float64array_builder.ts index 960c22afad..32ca2a5632 100644 --- a/src/util/float64array_builder.ts +++ b/src/util/float64array_builder.ts @@ -1,4 +1,4 @@ -// DO NOT EDIT. Generated from templates/neuroglancer/util/typedarray_builder.template.ts. +// DO NOT EDIT. Generated from templates/util/typedarray_builder.template.ts. /** * @license * Copyright 2016 Google Inc. @@ -17,9 +17,9 @@ export class Float64ArrayBuilder { length = 0; - data: Float64Array; + data: Float64Array; - constructor(initialCapacity = 16) { + constructor(initialCapacity: number = 16) { this.data = new Float64Array(initialCapacity); } @@ -35,7 +35,11 @@ export class Float64ArrayBuilder { get view() { const { data } = this; - return new Float64Array(data.buffer, data.byteOffset, this.length); + return new Float64Array( + data.buffer, + data.byteOffset, + this.length, + ); } shrinkToFit() { diff --git a/src/util/gcs_bucket_listing.ts b/src/util/gcs_bucket_listing.ts deleted file mode 100644 index 54de284571..0000000000 --- a/src/util/gcs_bucket_listing.ts +++ /dev/null @@ -1,92 +0,0 @@ -/** - * @license - * Copyright 2020 Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { fetchWithOAuth2Credentials } from "#src/credentials_provider/oauth2.js"; -import type { CancellationToken } from "#src/util/cancellation.js"; -import type { BasicCompletionResult } from "#src/util/completion.js"; -import { responseJson } from "#src/util/http_request.js"; -import { - parseArray, - verifyObject, - verifyObjectProperty, - verifyOptionalObjectProperty, - verifyString, - verifyStringArray, -} from "#src/util/json.js"; -import type { SpecialProtocolCredentialsProvider } from "#src/util/special_protocol_request.js"; - -export async function getGcsBucketListing( - credentialsProvider: SpecialProtocolCredentialsProvider, - bucket: string, - prefix: string, - delimiter: string, - cancellationToken: CancellationToken, -): Promise { - // Include origin as `neuroglancerOrigin` query string parameter. See comment in - // `special_protocol_request.ts` for details. - const response = await fetchWithOAuth2Credentials( - credentialsProvider, - `https://www.googleapis.com/storage/v1/b/${bucket}/o?` + - `delimiter=${encodeURIComponent(delimiter)}&prefix=${encodeURIComponent( - prefix, - )}&` + - `neuroglancerOrigin=${encodeURIComponent(location.origin)}`, - {}, - responseJson, - cancellationToken, - ); - verifyObject(response); - const prefixes = verifyOptionalObjectProperty( - response, - "prefixes", - verifyStringArray, - [], - ); - const items = verifyOptionalObjectProperty( - response, - "items", - (items) => - parseArray(items, (item) => { - verifyObject(item); - return verifyObjectProperty(item, "name", verifyString); - }), - [], - ).filter((name) => !name.endsWith("_$folder$")); - return [...prefixes, ...items]; -} - -export async function getGcsPathCompletions( - credentialsProvider: SpecialProtocolCredentialsProvider, - enteredBucketUrl: string, - bucket: string, - path: string, - cancellationToken: CancellationToken, -): Promise { - const prefix = path; - if (!prefix.startsWith("/")) throw null; - const paths = await getGcsBucketListing( - credentialsProvider, - bucket, - path.substring(1), - "/", - cancellationToken, - ); - const offset = path.lastIndexOf("/"); - return { - offset: offset + enteredBucketUrl.length + 1, - completions: paths.map((x) => ({ value: x.substring(offset) })), - }; -} diff --git a/src/util/google_oauth2.ts b/src/util/google_oauth2.ts index 8aee6576d8..50e8f6241f 100644 --- a/src/util/google_oauth2.ts +++ b/src/util/google_oauth2.ts @@ -18,20 +18,18 @@ import { CredentialsProvider, makeCredentialsGetter, } from "#src/credentials_provider/index.js"; -import { StatusMessage } from "#src/status.js"; -import type { CancellationToken } from "#src/util/cancellation.js"; import { - CANCELED, - CancellationTokenSource, - uncancelableToken, -} from "#src/util/cancellation.js"; -import { RefCounted } from "#src/util/disposable.js"; + getCredentialsWithStatus, + monitorAuthPopupWindow, +} from "#src/credentials_provider/interactive_credentials_provider.js"; +import { raceWithAbort } from "#src/util/abort.js"; import { removeFromParent } from "#src/util/dom.js"; import { verifyObject, verifyObjectProperty, verifyString, } from "#src/util/json.js"; +import { ProgressSpan } from "#src/util/progress_listener.js"; import { getRandomHexString } from "#src/util/random.js"; export const EMAIL_SCOPE = "email"; @@ -63,62 +61,57 @@ function extractEmailFromIdToken(idToken: string): string { } } -async function waitForAuthResponseMessage( +// Note: `signal` is guaranteed to be aborted once the operation completes. +function waitForAuthResponseMessage( source: Window, state: string, - cancellationToken: CancellationToken, + signal: AbortSignal, ): Promise { - const context = new RefCounted(); - try { - return await new Promise((resolve, reject) => { - context.registerDisposer(cancellationToken.add(() => reject(CANCELED))); - context.registerEventListener( - window, - "message", - (event: MessageEvent) => { - if (event.origin !== location.origin) { - return; - } + return new Promise((resolve, reject) => { + window.addEventListener( + "message", + (event: MessageEvent) => { + if (event.origin !== location.origin) { + return; + } - if (event.source !== source) return; + if (event.source !== source) return; - try { - const obj = verifyObject(event.data); - const receivedState = verifyObjectProperty( + try { + const obj = verifyObject(event.data); + const receivedState = verifyObjectProperty( + obj, + "state", + verifyString, + ); + if (receivedState !== state) { + throw new Error("invalid state"); + } + const idToken = verifyObjectProperty(obj, "id_token", verifyString); + const token: OAuth2Token = { + accessToken: verifyObjectProperty( obj, - "state", + "access_token", verifyString, - ); - if (receivedState !== state) { - throw new Error("invalid state"); - } - const idToken = verifyObjectProperty(obj, "id_token", verifyString); - const token: OAuth2Token = { - accessToken: verifyObjectProperty( - obj, - "access_token", - verifyString, - ), - tokenType: verifyObjectProperty(obj, "token_type", verifyString), - expiresIn: verifyObjectProperty(obj, "expires_in", verifyString), - scope: verifyObjectProperty(obj, "scope", verifyString), - email: extractEmailFromIdToken(idToken), - }; - resolve(token); - } catch (parseError) { - reject( - new Error( - `Received unexpected authentication response: ${parseError.message}`, - ), - ); - console.error("Response received: ", event.data); - } - }, - ); - }); - } finally { - context.dispose(); - } + ), + tokenType: verifyObjectProperty(obj, "token_type", verifyString), + expiresIn: verifyObjectProperty(obj, "expires_in", verifyString), + scope: verifyObjectProperty(obj, "scope", verifyString), + email: extractEmailFromIdToken(idToken), + }; + resolve(token); + } catch (parseError) { + reject( + new Error( + `Received unexpected authentication response: ${parseError.message}`, + ), + ); + console.error("Response received: ", event.data); + } + }, + { signal: signal }, + ); + }); } function makeAuthRequestUrl(options: { @@ -129,6 +122,7 @@ function makeAuthRequestUrl(options: { state?: string; loginHint?: string; authUser?: number; + includeGrantedScopes?: boolean; immediate?: boolean; }) { let url = `${AUTH_SERVER}?client_id=${encodeURIComponent(options.clientId)}`; @@ -141,7 +135,9 @@ function makeAuthRequestUrl(options: { responseType = "token%20id_token"; } url += `&response_type=${responseType}`; - url += "&include_granted_scopes=true"; + if (options.includeGrantedScopes === true) { + url += "&include_granted_scopes=true"; + } url += `&scope=${encodeURIComponent(scopes.join(" "))}`; if (options.state) { url += `&state=${options.state}`; @@ -161,6 +157,30 @@ function makeAuthRequestUrl(options: { return url; } +function createAuthIframe( + url: string, + abortController: AbortController, +): Window { + const iframe = document.createElement("iframe"); + iframe.src = url; + iframe.style.display = "none"; + iframe.addEventListener( + "load", + () => { + if (iframe.contentDocument == null) { + // Error received + abortController.abort(new Error("Immediate authentication failed")); + } + }, + { signal: abortController.signal }, + ); + document.body.appendChild(iframe); + abortController.signal.addEventListener("abort", () => { + removeFromParent(iframe); + }); + return iframe.contentWindow!; +} + /** * Obtain a Google OAuth2 authentication token. * @return A Promise that resolves to an authentication token. @@ -174,7 +194,7 @@ export async function authenticateGoogleOAuth2( immediate?: boolean; authUser?: number; }, - cancellationToken = uncancelableToken, + signal: AbortSignal, ) { const state = getRandomHexString(); const nonce = getRandomHexString(); @@ -188,52 +208,26 @@ export async function authenticateGoogleOAuth2( immediate: options.immediate, authUser: options.authUser, }); - let source: Window; - let cleanup: (() => void) | undefined; - const extraPromises: Array> = []; - if (options.immediate) { - // For immediate mode auth, we can wait until the relay is ready, since we aren't opening a new - // window. - const iframe = document.createElement("iframe"); - iframe.src = url; - iframe.style.display = "none"; - extraPromises.push( - new Promise((_resolve, reject) => { - iframe.addEventListener("load", () => { - console.log("iframe loaded", iframe.contentDocument); - if (iframe.contentDocument == null) { - // Error received - reject(new Error("Immediate authentication failed")); - } - }); - }), - ); - document.body.appendChild(iframe); - source = iframe.contentWindow!; - cleanup = () => { - removeFromParent(iframe); - }; - } else { - const newWindow = open(url); - source = newWindow!; - if (newWindow !== null) { - cleanup = () => { - try { - newWindow.close(); - } catch { - // Ignore error closing window. - } - }; - } - } - + const abortController = new AbortController(); + signal = AbortSignal.any([abortController.signal, signal]); try { - return await Promise.race([ - ...extraPromises, - waitForAuthResponseMessage(source, state, cancellationToken), - ]); + let source: Window; + if (options.immediate) { + source = createAuthIframe(url, abortController); + } else { + const newWindow = open(url); + if (newWindow === null) { + throw new Error("Failed to create authentication popup window"); + } + monitorAuthPopupWindow(newWindow, abortController); + source = newWindow!; + } + return await raceWithAbort( + waitForAuthResponseMessage(source, state, abortController.signal), + signal, + ); } finally { - cleanup?.(); + abortController.abort(); } } @@ -244,76 +238,26 @@ export class GoogleOAuth2CredentialsProvider extends CredentialsProvider { - const { options } = this; - const status = new StatusMessage(/*delay=*/ true); - let cancellationSource: CancellationTokenSource | undefined; - return new Promise((resolve, reject) => { - const dispose = () => { - cancellationSource = undefined; - status.dispose(); - }; - cancellationToken.add(() => { - if (cancellationSource !== undefined) { - cancellationSource.cancel(); - cancellationSource = undefined; - status.dispose(); - reject(CANCELED); - } - }); - function writeLoginStatus( - msg = `${options.description} authorization required.`, - linkMessage = "Request authorization.", - ) { - status.setText(msg + " "); - const button = document.createElement("button"); - button.textContent = linkMessage; - status.element.appendChild(button); - button.addEventListener("click", () => { - login(/*immediate=*/ false); - }); - status.setVisible(true); - } - function login(immediate: boolean) { - if (cancellationSource !== undefined) { - cancellationSource.cancel(); - } - cancellationSource = new CancellationTokenSource(); - writeLoginStatus( - `Waiting for ${options.description} authorization...`, - "Retry", - ); - authenticateGoogleOAuth2( - { - clientId: options.clientId, - scopes: options.scopes, - immediate: immediate, - authUser: 0, - }, - cancellationSource, - ).then( - (token) => { - if (cancellationSource !== undefined) { - dispose(); - resolve(token); - } - }, - (reason) => { - if (cancellationSource !== undefined) { - cancellationSource = undefined; - if (immediate) { - writeLoginStatus(); - } else { - writeLoginStatus( - `${options.description} authorization failed: ${reason}.`, - "Retry", - ); - } - } - }, - ); - } - login(/*immediate=*/ true); + get = makeCredentialsGetter(async (options) => { + using _span = new ProgressSpan(options.progressListener, { + message: `Requesting ${this.options.description} OAuth2 access token`, }); + return await getCredentialsWithStatus( + { + description: this.options.description, + supportsImmediate: true, + get: (signal, immediate) => + authenticateGoogleOAuth2( + { + clientId: this.options.clientId, + scopes: this.options.scopes, + immediate: immediate, + authUser: 0, + }, + signal, + ), + }, + options.signal, + ); }); } diff --git a/src/util/gzip.ts b/src/util/gzip.ts index 35ab3cfad3..4b412bf5ca 100644 --- a/src/util/gzip.ts +++ b/src/util/gzip.ts @@ -15,11 +15,41 @@ */ /** - * Detects gzip format based on the 2 magic bytes at the start. + * Detects gzip format based on the 3 magic bytes at the start. */ export function isGzipFormat(data: ArrayBufferView) { const view = new Uint8Array(data.buffer, data.byteOffset, data.byteLength); - return view.length > 2 && view[0] === 0x1f && view[1] === 0x8b; + return ( + view.length >= 3 && view[0] === 0x1f && view[1] === 0x8b && view[2] === 0x08 + ); +} + +export async function decodeGzip( + data: ArrayBuffer | ArrayBufferView | Response, + format: CompressionFormat, + signal?: AbortSignal, +) { + try { + const decompressedStream = decodeGzipStream( + data instanceof Response ? data : new Response(data), + format, + signal, + ); + return await new Response(decompressedStream).arrayBuffer(); + } catch { + signal?.throwIfAborted(); + throw new Error(`Failed to decode ${format}`); + } +} + +export function decodeGzipStream( + response: Response, + format: CompressionFormat, + signal?: AbortSignal, +): ReadableStream { + return response.body!.pipeThrough(new DecompressionStream(format), { + signal: signal, + }); } /** @@ -33,7 +63,7 @@ export async function maybeDecompressGzip(data: ArrayBuffer | ArrayBufferView) { byteView = new Uint8Array(data.buffer, data.byteOffset, data.byteLength); } if (isGzipFormat(byteView)) { - return (await import("pako")).inflate(byteView); + return new Uint8Array(await decodeGzip(byteView, "gzip")); } return byteView; } diff --git a/src/util/hash.ts b/src/util/hash.ts index 70ed1de192..964c6283af 100644 --- a/src/util/hash.ts +++ b/src/util/hash.ts @@ -143,3 +143,56 @@ export function murmurHash3_x86_128Hash64Bits( out.high = h2; return out; } + +export function murmurHash3_x86_128Hash64Bits_Bigint( + seed: number, + input: bigint, +): bigint { + let h1 = seed; + let h2 = seed; + let h3 = seed; + let h4 = seed; + const c1 = 0x239b961b; + const c2 = 0xab0e9789; + const c3 = 0x38b34ae5; + // const c4 = 0xa1e38b93; + + let k2 = Math.imul(Number(input >> BigInt(32)), c2); + k2 = rotl32(k2, 16); + k2 = Math.imul(k2, c3); + h2 ^= k2; + + let k1 = Math.imul(Number(input & BigInt(0xffffffff)), c1); + k1 = rotl32(k1, 15); + k1 = Math.imul(k1, c2); + h1 ^= k1; + + const len = 8; + + h1 ^= len; + h2 ^= len; + h3 ^= len; + h4 ^= len; + + h1 = (h1 + h2) >>> 0; + h1 = (h1 + h3) >>> 0; + h1 = (h1 + h4) >>> 0; + h2 = (h2 + h1) >>> 0; + h3 = (h3 + h1) >>> 0; + h4 = (h4 + h1) >>> 0; + + h1 = murmurHash3_x86_128Mix(h1); + h2 = murmurHash3_x86_128Mix(h2); + h3 = murmurHash3_x86_128Mix(h3); + h4 = murmurHash3_x86_128Mix(h4); + + h1 = (h1 + h2) >>> 0; + h1 = (h1 + h3) >>> 0; + h1 = (h1 + h4) >>> 0; + h2 = (h2 + h1) >>> 0; + + // h3 = (h3 + h1) >>> 0; + // h4 = (h4 + h1) >>> 0; + + return BigInt(h1) | (BigInt(h2) << BigInt(32)); +} diff --git a/src/util/http_path_completion.ts b/src/util/http_path_completion.ts deleted file mode 100644 index 93743b7597..0000000000 --- a/src/util/http_path_completion.ts +++ /dev/null @@ -1,199 +0,0 @@ -/** - * @license - * Copyright 2019 Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import type { CredentialsManager } from "#src/credentials_provider/index.js"; -import type { CancellationToken } from "#src/util/cancellation.js"; -import type { - BasicCompletionResult, - Completion, - CompletionWithDescription, -} from "#src/util/completion.js"; -import { getPrefixMatchesWithDescriptions } from "#src/util/completion.js"; -import { getGcsPathCompletions } from "#src/util/gcs_bucket_listing.js"; -import { parseUrl } from "#src/util/http_request.js"; -import { getS3PathCompletions } from "#src/util/s3.js"; -import { getS3CompatiblePathCompletions } from "#src/util/s3_bucket_listing.js"; -import type { SpecialProtocolCredentialsProvider } from "#src/util/special_protocol_request.js"; -import { - cancellableFetchSpecialOk, - parseSpecialUrl, -} from "#src/util/special_protocol_request.js"; - -/** - * Obtains a directory listing from a server that supports HTML directory listings. - */ -export async function getHtmlDirectoryListing( - url: string, - cancellationToken: CancellationToken, - credentialsProvider?: SpecialProtocolCredentialsProvider, -): Promise { - const { text, contentType } = await cancellableFetchSpecialOk( - credentialsProvider, - url, - /*init=*/ { headers: { accept: "text/html" } }, - async (x) => ({ - text: await x.text(), - contentType: x.headers.get("content-type"), - }), - cancellationToken, - ); - if (contentType === null || /\btext\/html\b/i.exec(contentType) === null) { - return []; - } - const doc = new DOMParser().parseFromString(text, "text/html"); - const nodes = doc.evaluate( - "//a/@href", - doc, - null, - XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, - null, - ); - const results: string[] = []; - for (let i = 0, n = nodes.snapshotLength; i < n; ++i) { - const node = nodes.snapshotItem(i)!; - const href = node.textContent; - if (href) { - results.push(new URL(href, url).toString()); - } - } - return results; -} - -export async function getHtmlPathCompletions( - url: string, - cancellationToken: CancellationToken, - credentialsProvider?: SpecialProtocolCredentialsProvider, -): Promise { - console.log("getHtmlPathCompletions"); - const m = url.match(/^([a-z]+:\/\/.*\/)([^/?#]*)$/); - if (m === null) throw null; - const entries = await getHtmlDirectoryListing( - m[1], - cancellationToken, - credentialsProvider, - ); - const offset = m[1].length; - const matches: Completion[] = []; - for (const entry of entries) { - if (!entry.startsWith(url)) continue; - matches.push({ value: entry.substring(offset) }); - } - return { - offset, - completions: matches, - }; -} - -const specialProtocolEmptyCompletions: CompletionWithDescription[] = [ - { value: "gs://", description: "Google Cloud Storage (JSON API)" }, - { value: "gs+xml://", description: "Google Cloud Storage (XML API)" }, - { - value: "gs+ngauth+http://", - description: "Google Cloud Storage (JSON API) authenticated via ngauth", - }, - { - value: "gs+ngauth+https://", - description: "Google Cloud Storage (JSON API) authenticated via ngauth", - }, - { - value: "gs+xml+ngauth+http://", - description: "Google Cloud Storage (XML API) authenticated via ngauth", - }, - { - value: "gs+xml+ngauth+https://", - description: "Google Cloud Storage (XML API) authenticated via ngauth", - }, - { value: "s3://", description: "Amazon Simple Storage Service (S3)" }, - { value: "https://" }, - { value: "http://" }, -]; - -export async function completeHttpPath( - credentialsManager: CredentialsManager, - url: string, - cancellationToken: CancellationToken, -): Promise> { - if (!url.includes("://")) { - return { - offset: 0, - completions: getPrefixMatchesWithDescriptions( - url, - specialProtocolEmptyCompletions, - (x) => x.value, - (x) => x.description, - ), - }; - } - const { url: parsedUrl, credentialsProvider } = parseSpecialUrl( - url, - credentialsManager, - ); - const offset = url.length - parsedUrl.length; - let result; - try { - result = parseUrl(parsedUrl); - } catch { - throw null; - } - const { protocol, host, path } = result; - const completions = await (async () => { - if (protocol === "gs+xml" && path.length > 0) { - return await getS3CompatiblePathCompletions( - credentialsProvider, - `${protocol}://${host}`, - `https://storage.googleapis.com/${host}`, - path, - cancellationToken, - ); - } - if (protocol === "gs" && path.length > 0) { - return await getGcsPathCompletions( - credentialsProvider, - `${protocol}://${host}`, - host, - path, - cancellationToken, - ); - } - if (protocol === "s3" && path.length > 0) { - return await getS3PathCompletions(host, path, cancellationToken); - } - const s3Match = parsedUrl.match( - /^((?:http|https):\/\/(?:storage\.googleapis\.com\/[^/]+|[^/]+\.storage\.googleapis\.com|[^/]+\.s3(?:[^./]+)?\.amazonaws.com))(\/.*)$/, - ); - if (s3Match !== null) { - return await getS3CompatiblePathCompletions( - credentialsProvider, - s3Match[1], - s3Match[1], - s3Match[2], - cancellationToken, - ); - } - if ((protocol === "http" || protocol === "https") && path.length > 0) { - return await getHtmlPathCompletions( - parsedUrl, - cancellationToken, - credentialsProvider, - ); - } - throw null; - })(); - return { - offset: offset + completions.offset, - completions: completions.completions, - }; -} diff --git a/src/util/http_request.ts b/src/util/http_request.ts index dbfef9c38c..293cc68119 100644 --- a/src/util/http_request.ts +++ b/src/util/http_request.ts @@ -14,9 +14,7 @@ * limitations under the License. */ -import type { CancellationToken } from "#src/util/cancellation.js"; -import { CANCELED, uncancelableToken } from "#src/util/cancellation.js"; -import { Uint64 } from "#src/util/uint64.js"; +import type { ProgressListener } from "#src/util/progress_listener.js"; export class HttpError extends Error { url: string; @@ -29,6 +27,7 @@ export class HttpError extends Error { status: number, statusText: string, response?: Response, + options?: { cause: any }, ) { let message = `Fetching ${JSON.stringify( url, @@ -37,7 +36,7 @@ export class HttpError extends Error { message += `: ${statusText}`; } message += "."; - super(message); + super(message, options); this.name = "HttpError"; this.message = message; this.url = url; @@ -65,7 +64,9 @@ export class HttpError extends Error { } else { url = input.url; } - return new HttpError(url, 0, "Network or CORS error"); + return new HttpError(url, 0, "Network or CORS error", undefined, { + cause: error, + }); } return error; } @@ -99,12 +100,10 @@ export function pickDelay(attemptNumber: number): number { */ export async function fetchOk( input: RequestInfo, - init?: RequestInit, + init?: RequestInitWithProgress, ): Promise { for (let requestAttempt = 0; ; ) { - if (init?.signal?.aborted) { - throw CANCELED; - } + init?.signal?.throwIfAborted(); let response: Response; try { response = await fetch(input, init); @@ -130,78 +129,14 @@ export async function fetchOk( } } -export function responseArrayBuffer(response: Response): Promise { - return response.arrayBuffer(); -} - -export function responseJson(response: Response): Promise { - return response.json(); +export interface RequestInitWithProgress extends RequestInit { + progressListener?: ProgressListener; } -export type ResponseTransform = (response: Response) => Promise; - -/** - * Issues a `fetch` request in the same way as `fetchOk`, and returns the result of the promise - * returned by `transformResponse`. - * - * Additionally, the request may be cancelled through `cancellationToken`. - * - * The `transformResponse` function should not do anything with the `Response` object after its - * result becomes ready; otherwise, cancellation may not work as expected. - */ -export async function cancellableFetchOk( +export type FetchOk = ( input: RequestInfo, - init: RequestInit, - transformResponse: ResponseTransform, - cancellationToken: CancellationToken = uncancelableToken, -): Promise { - if (cancellationToken === uncancelableToken) { - const response = await fetchOk(input, init); - return await transformResponse(response); - } - const abortController = new AbortController(); - const unregisterCancellation = cancellationToken.add(() => - abortController.abort(), - ); - try { - const response = await fetchOk(input, { - ...init, - signal: abortController.signal, - }); - return await transformResponse(response); - } finally { - unregisterCancellation(); - } -} - -const tempUint64 = new Uint64(); - -export function getByteRangeHeader( - startOffset: Uint64 | number, - endOffset: Uint64 | number, -) { - let endOffsetStr: string; - if (typeof endOffset === "number") { - endOffsetStr = `${endOffset - 1}`; - } else { - Uint64.decrement(tempUint64, endOffset); - endOffsetStr = tempUint64.toString(); - } - return { Range: `bytes=${startOffset}-${endOffsetStr}` }; -} - -export function parseUrl(url: string): { - protocol: string; - host: string; - path: string; -} { - const urlProtocolPattern = /^([^:/]+):\/\/([^/]+)((?:\/.*)?)$/; - const match = url.match(urlProtocolPattern); - if (match === null) { - throw new Error(`Invalid URL: ${JSON.stringify(url)}`); - } - return { protocol: match[1], host: match[2], path: match[3] }; -} + init?: RequestInitWithProgress, +) => Promise; export function isNotFoundError(e: any) { if (!(e instanceof HttpError)) return false; diff --git a/src/util/int16array_builder.ts b/src/util/int16array_builder.ts index 80e86a3504..80fb1c282c 100644 --- a/src/util/int16array_builder.ts +++ b/src/util/int16array_builder.ts @@ -1,4 +1,4 @@ -// DO NOT EDIT. Generated from templates/neuroglancer/util/typedarray_builder.template.ts. +// DO NOT EDIT. Generated from templates/util/typedarray_builder.template.ts. /** * @license * Copyright 2016 Google Inc. @@ -17,9 +17,9 @@ export class Int16ArrayBuilder { length = 0; - data: Int16Array; + data: Int16Array; - constructor(initialCapacity = 16) { + constructor(initialCapacity: number = 16) { this.data = new Int16Array(initialCapacity); } @@ -35,7 +35,11 @@ export class Int16ArrayBuilder { get view() { const { data } = this; - return new Int16Array(data.buffer, data.byteOffset, this.length); + return new Int16Array( + data.buffer, + data.byteOffset, + this.length, + ); } shrinkToFit() { diff --git a/src/util/int32array_builder.ts b/src/util/int32array_builder.ts index 035c022596..31778b442f 100644 --- a/src/util/int32array_builder.ts +++ b/src/util/int32array_builder.ts @@ -1,4 +1,4 @@ -// DO NOT EDIT. Generated from templates/neuroglancer/util/typedarray_builder.template.ts. +// DO NOT EDIT. Generated from templates/util/typedarray_builder.template.ts. /** * @license * Copyright 2016 Google Inc. @@ -17,9 +17,9 @@ export class Int32ArrayBuilder { length = 0; - data: Int32Array; + data: Int32Array; - constructor(initialCapacity = 16) { + constructor(initialCapacity: number = 16) { this.data = new Int32Array(initialCapacity); } @@ -35,7 +35,11 @@ export class Int32ArrayBuilder { get view() { const { data } = this; - return new Int32Array(data.buffer, data.byteOffset, this.length); + return new Int32Array( + data.buffer, + data.byteOffset, + this.length, + ); } shrinkToFit() { diff --git a/src/util/int8array_builder.ts b/src/util/int8array_builder.ts index 923b97ba1d..5ff5d37d28 100644 --- a/src/util/int8array_builder.ts +++ b/src/util/int8array_builder.ts @@ -1,4 +1,4 @@ -// DO NOT EDIT. Generated from templates/neuroglancer/util/typedarray_builder.template.ts. +// DO NOT EDIT. Generated from templates/util/typedarray_builder.template.ts. /** * @license * Copyright 2016 Google Inc. @@ -17,9 +17,9 @@ export class Int8ArrayBuilder { length = 0; - data: Int8Array; + data: Int8Array; - constructor(initialCapacity = 16) { + constructor(initialCapacity: number = 16) { this.data = new Int8Array(initialCapacity); } @@ -35,7 +35,11 @@ export class Int8ArrayBuilder { get view() { const { data } = this; - return new Int8Array(data.buffer, data.byteOffset, this.length); + return new Int8Array( + data.buffer, + data.byteOffset, + this.length, + ); } shrinkToFit() { diff --git a/src/util/linked_list.0.ts b/src/util/linked_list.0.ts index 2de7c5595d..0561c54970 100644 --- a/src/util/linked_list.0.ts +++ b/src/util/linked_list.0.ts @@ -1,4 +1,4 @@ -// DO NOT EDIT. Generated from templates/neuroglancer/util/linked_list.template.ts. +// DO NOT EDIT. Generated from templates/util/linked_list.template.ts. /** * @license * Copyright 2016 Google Inc. diff --git a/src/util/linked_list.1.ts b/src/util/linked_list.1.ts index e7163da435..6a6ce2416b 100644 --- a/src/util/linked_list.1.ts +++ b/src/util/linked_list.1.ts @@ -1,4 +1,4 @@ -// DO NOT EDIT. Generated from templates/neuroglancer/util/linked_list.template.ts. +// DO NOT EDIT. Generated from templates/util/linked_list.template.ts. /** * @license * Copyright 2016 Google Inc. diff --git a/src/util/memoize.ts b/src/util/memoize.ts index c9da1cfbf4..fd2826b78e 100644 --- a/src/util/memoize.ts +++ b/src/util/memoize.ts @@ -14,9 +14,12 @@ * limitations under the License. */ +import { raceWithAbort, SharedAbortController } from "#src/util/abort.js"; import type { RefCounted } from "#src/util/disposable.js"; import { RefCountedValue } from "#src/util/disposable.js"; import { stableStringify } from "#src/util/json.js"; +import type { ProgressOptions } from "#src/util/progress_listener.js"; +import { MultiConsumerProgressListener } from "#src/util/progress_listener.js"; export class Memoize { private map = new Map(); @@ -51,4 +54,107 @@ export class StringMemoize extends Memoize { getUncounted(x: any, getter: () => T) { return this.get(x, () => new RefCountedValue(getter())).value; } + + getAsync( + x: any, + options: Partial, + getter: (options: ProgressOptions) => Promise, + ) { + return this.getUncounted(x, () => asyncMemoizeWithProgress(getter))( + options, + ); + } +} + +export interface AsyncMemoize { + (options: { signal?: AbortSignal }): Promise; +} + +export interface AsyncMemoizeWithProgress { + (options: Partial): Promise; +} + +export function asyncMemoize( + getter: (options: { signal: AbortSignal }) => Promise, +): AsyncMemoize { + let abortController: SharedAbortController | undefined; + let promise: Promise | undefined; + let completed: boolean = false; + + return (options: { signal?: AbortSignal }): Promise => { + if (completed) { + return promise!; + } + if (promise === undefined || abortController!.signal.aborted) { + abortController = new SharedAbortController(); + promise = (async () => { + try { + return await getter({ + signal: abortController!.signal, + }); + } catch (e) { + if (abortController!.signal.aborted) { + promise = undefined; + } + throw e; + } finally { + if (promise !== undefined) { + completed = true; + } + abortController![Symbol.dispose](); + abortController = undefined; + } + })(); + } + abortController!.addConsumer(options.signal); + return raceWithAbort(promise, options.signal); + }; +} + +export function asyncMemoizeWithProgress( + getter: (options: ProgressOptions) => Promise, +): AsyncMemoizeWithProgress { + let progressListener: MultiConsumerProgressListener | undefined; + let abortController: SharedAbortController | undefined; + let promise: Promise | undefined; + let completed: boolean = false; + + return async (options: Partial): Promise => { + if (completed) { + return promise!; + } + if (promise === undefined || abortController!.signal.aborted) { + progressListener = new MultiConsumerProgressListener(); + abortController = new SharedAbortController(); + promise = (async () => { + try { + return await getter({ + signal: abortController!.signal, + progressListener: progressListener!, + }); + } catch (e) { + if (abortController!.signal.aborted) { + promise = undefined; + } + throw e; + } finally { + if (promise !== undefined) { + completed = true; + } + progressListener = undefined; + abortController![Symbol.dispose](); + abortController = undefined; + } + })(); + } + abortController!.addConsumer(options.signal); + const curProgressListener = progressListener!; + curProgressListener.addListener(options.progressListener); + + try { + return await raceWithAbort(promise, options.signal); + } finally { + curProgressListener.removeListener(options.progressListener); + } + }; } diff --git a/src/util/npy.spec.ts b/src/util/npy.spec.ts index f5c55557cd..cc61084bf2 100644 --- a/src/util/npy.spec.ts +++ b/src/util/npy.spec.ts @@ -48,6 +48,8 @@ describe("parseNpy", () => { "..", "..", "testdata", + "codec", + "npy", ); const example = JSON.parse( await fs.readFile(`${testDataDir}/npy_test.${json}.json`, { diff --git a/src/util/pairing_heap.0.ts b/src/util/pairing_heap.0.ts index 10e222c028..394730db37 100644 --- a/src/util/pairing_heap.0.ts +++ b/src/util/pairing_heap.0.ts @@ -1,4 +1,4 @@ -// DO NOT EDIT. Generated from templates/neuroglancer/util/pairing_heap.template.ts. +// DO NOT EDIT. Generated from templates/util/pairing_heap.template.ts. /** * @license * Copyright 2016 Google Inc. @@ -71,8 +71,7 @@ export default class Implementation> let head: T | null = null; while (true) { const curNext: T | null = cur.next0; - let next: T | null; - let m: T; + let next: T | null, m: T; if (curNext === null) { next = null; m = cur; diff --git a/src/util/pairing_heap.1.ts b/src/util/pairing_heap.1.ts index 3b4f5f3d66..e8cc96d86a 100644 --- a/src/util/pairing_heap.1.ts +++ b/src/util/pairing_heap.1.ts @@ -1,4 +1,4 @@ -// DO NOT EDIT. Generated from templates/neuroglancer/util/pairing_heap.template.ts. +// DO NOT EDIT. Generated from templates/util/pairing_heap.template.ts. /** * @license * Copyright 2016 Google Inc. @@ -71,8 +71,7 @@ export default class Implementation> let head: T | null = null; while (true) { const curNext: T | null = cur.next1; - let next: T | null; - let m: T; + let next: T | null, m: T; if (curNext === null) { next = null; m = cur; diff --git a/src/util/polyfills.ts b/src/util/polyfills.ts new file mode 100644 index 0000000000..3a6325369b --- /dev/null +++ b/src/util/polyfills.ts @@ -0,0 +1,2 @@ +import "core-js/actual/symbol/dispose.js"; +import "core-js/actual/symbol/async-dispose.js"; diff --git a/src/util/progress_listener.ts b/src/util/progress_listener.ts new file mode 100644 index 0000000000..6c95858faf --- /dev/null +++ b/src/util/progress_listener.ts @@ -0,0 +1,177 @@ +/** + * @license + * Copyright 2024 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export type ProgressSpanId = number; + +export interface ProgressSpanOptions { + message: string; + startTime?: number; + id?: ProgressSpanId; +} + +export class ProgressSpan implements Disposable { + id: ProgressSpanId; + startTime: number; + message: string; + + constructor( + public listener: ProgressListener, + options: ProgressSpanOptions, + ) { + const { id = Math.random(), startTime = Date.now(), message } = options; + this.id = id; + this.startTime = startTime; + this.message = message; + listener.addSpan(this); + } + + [Symbol.dispose]() { + this.listener.removeSpan(this.id); + } +} + +export interface ProgressListener { + addSpan(span: ProgressSpan): void; + removeSpan(spanId: ProgressSpanId): void; +} + +export class MultiSet { + private items = new Map(); + add(item: T): number { + const { items } = this; + const count = (items.get(item) ?? 0) + 1; + items.set(item, count); + return count; + } + + delete(item: T): number { + const { items } = this; + let count = items.get(item)!; + if (count > 1) { + count -= 1; + items.set(item, count); + return count; + } + items.delete(item); + return 0; + } + + has(item: T): boolean { + return this.items.has(item); + } + + keys() { + return this.items.keys(); + } + + entries() { + return this.items.entries(); + } + + [Symbol.iterator]() { + return this.items.keys(); + } +} + +export class KeyedMultiSet { + private items = new Map(); + constructor(private getKey: (value: T) => Key) {} + + add(item: T): number { + const { items } = this; + const key = this.getKey(item); + const obj = items.get(key); + if (obj === undefined) { + items.set(key, { value: item, count: 1 }); + return 1; + } else { + return (obj.count += 1); + } + } + + delete(item: T): number { + return this.deleteKey(this.getKey(item)); + } + + deleteKey(key: Key): number { + const { items } = this; + const obj = items.get(key); + if (obj !== undefined && obj.count > 1) { + return (obj.count -= 1); + } + items.delete(key); + return 0; + } + + has(item: T): boolean { + return this.items.has(this.getKey(item)); + } + + *[Symbol.iterator]() { + for (const obj of this.items.values()) { + yield obj.value; + } + } +} + +function getId(span: ProgressSpan) { + return span.id; +} + +export class ProgressSpanSet extends KeyedMultiSet { + constructor() { + super(getId); + } +} + +export class MultiConsumerProgressListener implements ProgressListener { + private spans = new ProgressSpanSet(); + private listeners = new MultiSet(); + addSpan(span: ProgressSpan) { + if (this.spans.add(span) !== 1) return; + for (const listener of this.listeners) { + listener.addSpan(span); + } + } + + removeSpan(spanId: ProgressSpanId) { + if (this.spans.deleteKey(spanId) !== 0) return; + for (const listener of this.listeners) { + listener.removeSpan(spanId); + } + } + + addListener(listener: ProgressListener | undefined) { + if (listener === undefined) return; + if (this.listeners.add(listener) !== 1) return; + for (const span of this.spans) { + listener.addSpan(span); + } + } + + removeListener(listener: ProgressListener | undefined) { + if (listener === undefined) return; + if (this.listeners.delete(listener) !== 0) return; + for (const span of this.spans) { + listener.removeSpan(span.id); + } + } +} + +export interface ProgressOptions { + signal: AbortSignal; + progressListener: ProgressListener; +} diff --git a/src/util/s3.ts b/src/util/s3.ts deleted file mode 100644 index e7be327c0e..0000000000 --- a/src/util/s3.ts +++ /dev/null @@ -1,52 +0,0 @@ -/** - * @license - * Copyright 2021 Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import type { CancellationToken } from "#src/util/cancellation.js"; -import { uncancelableToken } from "#src/util/cancellation.js"; -import type { ResponseTransform } from "#src/util/http_request.js"; -import { cancellableFetchOk } from "#src/util/http_request.js"; -import { getS3CompatiblePathCompletions } from "#src/util/s3_bucket_listing.js"; - -// Support for s3:// special protocol. - -export async function cancellableFetchS3Ok( - bucket: string, - path: string, - requestInit: RequestInit, - transformResponse: ResponseTransform, - cancellationToken: CancellationToken = uncancelableToken, -) { - return await cancellableFetchOk( - `https://${bucket}.s3.amazonaws.com${path}`, - requestInit, - transformResponse, - cancellationToken, - ); -} - -export async function getS3PathCompletions( - bucket: string, - path: string, - cancellationToken: CancellationToken, -) { - return await getS3CompatiblePathCompletions( - undefined, - `s3://${bucket}`, - `https://${bucket}.s3.amazonaws.com`, - path, - cancellationToken, - ); -} diff --git a/src/util/s3_bucket_listing.ts b/src/util/s3_bucket_listing.ts deleted file mode 100644 index 39540266d7..0000000000 --- a/src/util/s3_bucket_listing.ts +++ /dev/null @@ -1,88 +0,0 @@ -/** - * @license - * Copyright 2019 Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @file Provides file listing and completion for storage systems supporting the S3 XML API (e.g. S3 - * and GCS). - */ - -import { fetchWithOAuth2Credentials } from "#src/credentials_provider/oauth2.js"; -import type { CancellationToken } from "#src/util/cancellation.js"; -import type { BasicCompletionResult } from "#src/util/completion.js"; -import type { SpecialProtocolCredentialsProvider } from "#src/util/special_protocol_request.js"; - -export async function getS3BucketListing( - credentialsProvider: SpecialProtocolCredentialsProvider, - bucketUrl: string, - prefix: string, - delimiter: string, - cancellationToken: CancellationToken, -): Promise { - const response = await fetchWithOAuth2Credentials( - credentialsProvider, - `${bucketUrl}?prefix=${encodeURIComponent(prefix)}` + - `&delimiter=${encodeURIComponent(delimiter)}`, - /*init=*/ {}, - (x) => x.text(), - cancellationToken, - ); - const doc = new DOMParser().parseFromString(response, "application/xml"); - const commonPrefixNodes = doc.evaluate( - '//*[name()="CommonPrefixes"]/*[name()="Prefix"]', - doc, - null, - XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, - null, - ); - const results: string[] = []; - for (let i = 0, n = commonPrefixNodes.snapshotLength; i < n; ++i) { - results.push(commonPrefixNodes.snapshotItem(i)!.textContent || ""); - } - const contents = doc.evaluate( - '//*[name()="Contents"]/*[name()="Key"]', - doc, - null, - XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, - null, - ); - for (let i = 0, n = contents.snapshotLength; i < n; ++i) { - results.push(contents.snapshotItem(i)!.textContent || ""); - } - return results; -} - -export async function getS3CompatiblePathCompletions( - credentialsProvider: SpecialProtocolCredentialsProvider, - enteredBucketUrl: string, - bucketUrl: string, - path: string, - cancellationToken: CancellationToken, -): Promise { - const prefix = path; - if (!prefix.startsWith("/")) throw null; - const paths = await getS3BucketListing( - credentialsProvider, - bucketUrl, - path.substring(1), - "/", - cancellationToken, - ); - const offset = path.lastIndexOf("/"); - return { - offset: offset + enteredBucketUrl.length + 1, - completions: paths.map((x) => ({ value: x.substring(offset) })), - }; -} diff --git a/src/util/signal.ts b/src/util/signal.ts index 52ca03c34b..4a7031e013 100644 --- a/src/util/signal.ts +++ b/src/util/signal.ts @@ -61,6 +61,15 @@ export class Signal void> { }; } + addOnce(handler: Callable): void { + const { handlers } = this; + function onceWrapper(...args: any) { + handlers.delete(onceWrapper as any); + handler(...args); + } + handlers.add(onceWrapper as any); + } + /** * Remove a handler function. If `dispatch` is currently be called and the new handler has not * yet been called, then it will not be called. @@ -117,6 +126,7 @@ export class NullarySignal extends Signal<() => void> {} export interface ReadonlySignal { readonly count: number; add(handler: Callable): () => void; + addOnce(handler: Callable): void; remove(handler: Callable): boolean; } @@ -127,6 +137,7 @@ export const neverSignal: NullaryReadonlySignal = { add(_handler: any) { return () => {}; }, + addOnce(_handler: any) {}, remove(_handler: any) { return false; }, diff --git a/src/util/special_protocol_request.ts b/src/util/special_protocol_request.ts deleted file mode 100644 index f79590b789..0000000000 --- a/src/util/special_protocol_request.ts +++ /dev/null @@ -1,197 +0,0 @@ -/** - * @license - * Copyright 2020 Google Inc. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import pythonIntegration from "#python_integration_build"; -import type { - CredentialsManager, - MaybeOptionalCredentialsProvider, -} from "#src/credentials_provider/index.js"; -import { fetchWithOAuth2Credentials } from "#src/credentials_provider/oauth2.js"; -import type { CancellationToken } from "#src/util/cancellation.js"; -import { uncancelableToken } from "#src/util/cancellation.js"; -import type { ResponseTransform } from "#src/util/http_request.js"; -import { parseUrl } from "#src/util/http_request.js"; -import { getRandomHexString } from "#src/util/random.js"; -import { cancellableFetchS3Ok } from "#src/util/s3.js"; - -export type SpecialProtocolCredentials = any; -export type SpecialProtocolCredentialsProvider = - MaybeOptionalCredentialsProvider; - -function getMiddleAuthCredentialsProvider( - credentialsManager: CredentialsManager, - url: string, -): SpecialProtocolCredentialsProvider { - return credentialsManager.getCredentialsProvider( - "middleauthapp", - new URL(url).origin, - ); -} - -function getNgauthCredentialsProvider( - credentialsManager: CredentialsManager, - serverUrl: string, - path: string, -): SpecialProtocolCredentialsProvider { - const bucketPattern = /^\/([^/]+)/; - const m = path.match(bucketPattern); - if (m === null) return undefined; - return pythonIntegration - ? credentialsManager.getCredentialsProvider("gcs", { bucket: m[1] }) - : credentialsManager.getCredentialsProvider("ngauth_gcs", { - authServer: serverUrl, - bucket: m[1], - }); -} - -export function parseSpecialUrl( - url: string, - credentialsManager: CredentialsManager, -): { url: string; credentialsProvider: SpecialProtocolCredentialsProvider } { - const u = parseUrl(url); - switch (u.protocol) { - case "gs": - case "gs+xml": - return { - credentialsProvider: pythonIntegration - ? credentialsManager.getCredentialsProvider("gcs", { - bucket: u.host, - }) - : undefined, - url, - }; - case "gs+ngauth+http": - return { - credentialsProvider: getNgauthCredentialsProvider( - credentialsManager, - `http://${u.host}`, - u.path, - ), - url: "gs:/" + u.path, - }; - case "gs+ngauth+https": - return { - credentialsProvider: getNgauthCredentialsProvider( - credentialsManager, - `https://${u.host}`, - u.path, - ), - url: "gs:/" + u.path, - }; - case "gs+xml+ngauth+http": - return { - credentialsProvider: getNgauthCredentialsProvider( - credentialsManager, - `http://${u.host}`, - u.path, - ), - url: "gs+xml:/" + u.path, - }; - case "gs+xml+ngauth+https": - return { - credentialsProvider: getNgauthCredentialsProvider( - credentialsManager, - `https://${u.host}`, - u.path, - ), - url: "gs+xml:/" + u.path, - }; - case "middleauth+https": - url = url.substr("middleauth+".length); - return { - credentialsProvider: getMiddleAuthCredentialsProvider( - credentialsManager, - url, - ), - url: url, - }; - case "s3": - return { - credentialsProvider: undefined, - url, - }; - default: - return { - credentialsProvider: undefined, - url, - }; - } -} - -export async function cancellableFetchSpecialOk( - credentialsProvider: SpecialProtocolCredentialsProvider, - url: string, - init: RequestInit, - transformResponse: ResponseTransform, - cancellationToken: CancellationToken = uncancelableToken, -): Promise { - const u = parseUrl(url); - switch (u.protocol) { - case "gs": - // Include random query string parameter (ignored by GCS) to bypass GCS cache and ensure a - // cached response is never used. - // - // This addresses two issues related to GCS: - // - // 1. GCS fails to send an updated `Access-Control-Allow-Origin` header in 304 responses to - // cache revalidation requests. - // - // https://bugs.chromium.org/p/chromium/issues/detail?id=1214563#c2 - // - // The random query string parameter ensures cached responses are never used. - // - // Note: This issue does not apply to gs+xml because with the XML API, the - // Access-Control-Allow-Origin response header does not vary with the Origin. - // - // 2. If the object does not prohibit caching (e.g. public bucket and default `cache-control` - // metadata value), GCS may return stale responses. - // - return fetchWithOAuth2Credentials( - credentialsProvider, - `https://www.googleapis.com/storage/v1/b/${u.host}/o/` + - `${encodeURIComponent(u.path.substring(1))}?alt=media` + - `&neuroglancer=${getRandomHexString()}`, - init, - transformResponse, - cancellationToken, - ); - case "gs+xml": - return fetchWithOAuth2Credentials( - credentialsProvider, - `https://storage.googleapis.com/${u.host}${u.path}` + - `?neuroglancer=${getRandomHexString()}`, - init, - transformResponse, - cancellationToken, - ); - case "s3": - return cancellableFetchS3Ok( - u.host, - u.path, - init, - transformResponse, - cancellationToken, - ); - default: - return fetchWithOAuth2Credentials( - credentialsProvider, - url, - init, - transformResponse, - cancellationToken, - ); - } -} diff --git a/src/util/uint16array_builder.ts b/src/util/uint16array_builder.ts index 6383bca489..34606cb4b6 100644 --- a/src/util/uint16array_builder.ts +++ b/src/util/uint16array_builder.ts @@ -1,4 +1,4 @@ -// DO NOT EDIT. Generated from templates/neuroglancer/util/typedarray_builder.template.ts. +// DO NOT EDIT. Generated from templates/util/typedarray_builder.template.ts. /** * @license * Copyright 2016 Google Inc. @@ -17,9 +17,9 @@ export class Uint16ArrayBuilder { length = 0; - data: Uint16Array; + data: Uint16Array; - constructor(initialCapacity = 16) { + constructor(initialCapacity: number = 16) { this.data = new Uint16Array(initialCapacity); } @@ -35,7 +35,11 @@ export class Uint16ArrayBuilder { get view() { const { data } = this; - return new Uint16Array(data.buffer, data.byteOffset, this.length); + return new Uint16Array( + data.buffer, + data.byteOffset, + this.length, + ); } shrinkToFit() { diff --git a/src/util/uint32array_builder.ts b/src/util/uint32array_builder.ts index 3bc6b50ac4..856e0ef367 100644 --- a/src/util/uint32array_builder.ts +++ b/src/util/uint32array_builder.ts @@ -1,4 +1,4 @@ -// DO NOT EDIT. Generated from templates/neuroglancer/util/typedarray_builder.template.ts. +// DO NOT EDIT. Generated from templates/util/typedarray_builder.template.ts. /** * @license * Copyright 2016 Google Inc. @@ -17,9 +17,9 @@ export class Uint32ArrayBuilder { length = 0; - data: Uint32Array; + data: Uint32Array; - constructor(initialCapacity = 16) { + constructor(initialCapacity: number = 16) { this.data = new Uint32Array(initialCapacity); } @@ -35,7 +35,11 @@ export class Uint32ArrayBuilder { get view() { const { data } = this; - return new Uint32Array(data.buffer, data.byteOffset, this.length); + return new Uint32Array( + data.buffer, + data.byteOffset, + this.length, + ); } shrinkToFit() { diff --git a/src/util/uint64.ts b/src/util/uint64.ts index 7a05caddc3..fd9fb355f1 100644 --- a/src/util/uint64.ts +++ b/src/util/uint64.ts @@ -338,6 +338,10 @@ export class Uint64 { return this.low + this.high * 0x100000000; } + toBigInt() { + return BigInt(this.low) | (BigInt(this.high) << BigInt(32)); + } + setFromNumber(value: number) { value = Math.round(value); if (value < 0) { diff --git a/src/util/uint8array_builder.ts b/src/util/uint8array_builder.ts index 9519a8261c..78d27f9074 100644 --- a/src/util/uint8array_builder.ts +++ b/src/util/uint8array_builder.ts @@ -1,4 +1,4 @@ -// DO NOT EDIT. Generated from templates/neuroglancer/util/typedarray_builder.template.ts. +// DO NOT EDIT. Generated from templates/util/typedarray_builder.template.ts. /** * @license * Copyright 2016 Google Inc. @@ -17,9 +17,9 @@ export class Uint8ArrayBuilder { length = 0; - data: Uint8Array; + data: Uint8Array; - constructor(initialCapacity = 16) { + constructor(initialCapacity: number = 16) { this.data = new Uint8Array(initialCapacity); } @@ -35,7 +35,11 @@ export class Uint8ArrayBuilder { get view() { const { data } = this; - return new Uint8Array(data.buffer, data.byteOffset, this.length); + return new Uint8Array( + data.buffer, + data.byteOffset, + this.length, + ); } shrinkToFit() { diff --git a/src/util/zorder.spec.ts b/src/util/zorder.spec.ts index 16486518c5..c5d5b810b1 100644 --- a/src/util/zorder.spec.ts +++ b/src/util/zorder.spec.ts @@ -15,14 +15,13 @@ */ import { describe, it, expect } from "vitest"; -import { Uint64 } from "#src/util/uint64.js"; import { decodeZIndexCompressed, zorder3LessThan } from "#src/util/zorder.js"; describe("decodeZIndexCompressed", () => { it("works for repetitive pattern 21,21,21", () => { expect( decodeZIndexCompressed( - Uint64.parseString("111000100010001111000100010001111000100010001", 2), + 0b111000100010001111000100010001111000100010001n, 21, 21, 21, @@ -35,10 +34,7 @@ describe("decodeZIndexCompressed", () => { it("works for repetitive pattern 18,15,17", () => { expect( decodeZIndexCompressed( - Uint64.parseString( - "11101111000100010001111000100010001111000100010001", - 2, - ), + 0b11101111000100010001111000100010001111000100010001n, 18, 15, 17, diff --git a/src/util/zorder.ts b/src/util/zorder.ts index 7f8bb9dd5a..323646305b 100644 --- a/src/util/zorder.ts +++ b/src/util/zorder.ts @@ -15,7 +15,6 @@ */ import type { TypedArray } from "#src/util/array.js"; -import type { Uint64 } from "#src/util/uint64.js"; export function getOctreeChildIndex(x: number, y: number, z: number) { return (x & 1) | ((y << 1) & 2) | ((z << 2) & 4); @@ -29,73 +28,46 @@ export function getOctreeChildIndex(x: number, y: number, z: number) { * respectively, for `i` in `[0, xBits)`, `[0, yBits)`, `[0, zBits)`, respectively. */ export function decodeZIndexCompressed( - zindex: Uint64, + zindex: bigint, xBits: number, yBits: number, zBits: number, ): Uint32Array { const maxCoordBits = Math.max(xBits, yBits, zBits); let inputBit = 0; - let inputValue = zindex.low; let x = 0; let y = 0; let z = 0; for (let coordBit = 0; coordBit < maxCoordBits; ++coordBit) { if (coordBit < xBits) { - const bit = (inputValue >>> inputBit) & 1; + const bit = Number((zindex >> BigInt(inputBit++)) & BigInt(1)); x |= bit << coordBit; - if (inputBit === 31) { - inputBit = 0; - inputValue = zindex.high; - } else { - ++inputBit; - } } if (coordBit < yBits) { - const bit = (inputValue >>> inputBit) & 1; + const bit = Number((zindex >> BigInt(inputBit++)) & BigInt(1)); y |= bit << coordBit; - if (inputBit === 31) { - inputBit = 0; - inputValue = zindex.high; - } else { - ++inputBit; - } } if (coordBit < zBits) { - const bit = (inputValue >>> inputBit) & 1; + const bit = Number((zindex >> BigInt(inputBit++)) & BigInt(1)); z |= bit << coordBit; - if (inputBit === 31) { - inputBit = 0; - inputValue = zindex.high; - } else { - ++inputBit; - } } } return Uint32Array.of(x, y, z); } export function encodeZIndexCompressed3d( - zindex: Uint64, xBits: number, yBits: number, zBits: number, x: number, y: number, z: number, -): Uint64 { +): bigint { const maxBits = Math.max(xBits, yBits, zBits); let outputBit = 0; - let outputNum = 0; - let isHigh = false; + let zIndex = 0n; function writeBit(b: number): void { - outputNum |= (b & 1) << outputBit; - if (++outputBit === 32) { - zindex.low = outputNum >>> 0; - outputNum = 0; - outputBit = 0; - isHigh = true; - } + zIndex |= BigInt(b) << BigInt(outputBit++); } for (let bit = 0; bit < maxBits; ++bit) { if (bit < xBits) { @@ -108,32 +80,18 @@ export function encodeZIndexCompressed3d( writeBit((z >> bit) & 1); } } - if (isHigh) { - zindex.high = outputNum >>> 0; - } else { - zindex.high = 0; - zindex.low = outputNum >>> 0; - } - return zindex; + return zIndex; } export function encodeZIndexCompressed( - zindex: Uint64, position: TypedArray, shape: TypedArray, -): Uint64 { +): bigint { + let zIndex = 0n; let outputBit = 0; const rank = position.length; - let outputNum = 0; - let isHigh = false; function writeBit(b: number): void { - outputNum |= (b & 1) << outputBit; - if (++outputBit === 32) { - zindex.low = outputNum >>> 0; - outputNum = 0; - outputBit = 0; - isHigh = true; - } + zIndex |= BigInt(b & 1) << BigInt(outputBit++); } for (let bit = 0; bit < 32; ++bit) { @@ -143,13 +101,7 @@ export function encodeZIndexCompressed( } } } - if (isHigh) { - zindex.high = outputNum >>> 0; - } else { - zindex.high = 0; - zindex.low = outputNum >>> 0; - } - return zindex; + return zIndex; } function lessMsb(a: number, b: number) { diff --git a/src/viewer.ts b/src/viewer.ts index 73a72f171a..e921402388 100644 --- a/src/viewer.ts +++ b/src/viewer.ts @@ -22,20 +22,17 @@ import svg_layers from "ikonate/icons/layers.svg?raw"; import svg_list from "ikonate/icons/list.svg?raw"; import svg_settings from "ikonate/icons/settings.svg?raw"; import { debounce } from "lodash-es"; -import type { FrameNumberCounter } from "#src/chunk_manager/frontend.js"; -import { - CapacitySpecification, - ChunkManager, - ChunkQueueManager, -} from "#src/chunk_manager/frontend.js"; import { makeCoordinateSpace, TrackableCoordinateSpace, } from "#src/coordinate_transform.js"; -import { defaultCredentialsManager } from "#src/credentials_provider/default_manager.js"; +import { getDefaultCredentialsManager } from "#src/credentials_provider/default_manager.js"; +import type { CredentialsManager } from "#src/credentials_provider/index.js"; +import { SharedCredentialsManager } from "#src/credentials_provider/shared.js"; +import { DataManagementContext } from "#src/data_management_context.js"; import { InputEventBindings as DataPanelInputEventBindings } from "#src/data_panel_layout.js"; import { getDefaultDataSourceProvider } from "#src/datasource/default_provider.js"; -import type { DataSourceProviderRegistry } from "#src/datasource/index.js"; +import type { DataSourceRegistry } from "#src/datasource/index.js"; import { StateShare, stateShareEnabled } from "#src/datasource/state_share.js"; import type { DisplayContext } from "#src/display_context.js"; import { TrackableWindowedViewport } from "#src/display_context.js"; @@ -43,6 +40,7 @@ import { HelpPanelState, InputEventBindingHelpDialog, } from "#src/help/input_event_bindings.js"; +import { SharedKvStoreContext } from "#src/kvstore/frontend.js"; import { addNewLayer, LayerManager, @@ -94,6 +92,11 @@ import { SidePanelManager } from "#src/ui/side_panel.js"; import { StateEditorDialog } from "#src/ui/state_editor.js"; import { StatisticsDisplayState, StatisticsPanel } from "#src/ui/statistics.js"; import { GlobalToolBinder, LocalToolBinder } from "#src/ui/tool.js"; +import { + MultiToolPaletteDropdownButton, + MultiToolPaletteManager, + MultiToolPaletteState, +} from "#src/ui/tool_palette.js"; import { ViewerSettingsPanel, ViewerSettingsPanelState, @@ -127,7 +130,6 @@ import type { VisibilityPrioritySpecification, } from "#src/viewer_state.js"; import { WatchableVisibilityPriority } from "#src/visibility_priority/frontend.js"; -import type { GL } from "#src/webgl/context.js"; import { AnnotationToolStatusWidget } from "#src/widget/annotation_tool_status.js"; import { CheckboxIcon } from "#src/widget/checkbox_icon.js"; import { makeIcon } from "#src/widget/icon.js"; @@ -139,7 +141,6 @@ import { registerDimensionToolForViewer, } from "#src/widget/position_widget.js"; import { TrackableScaleBarOptions } from "#src/widget/scale_bar.js"; -import { RPC } from "#src/worker_rpc.js"; declare let NEUROGLANCER_OVERRIDE_DEFAULT_VIEWER_OPTIONS: any; @@ -150,60 +151,6 @@ interface CreditLink { declare let NEUROGLANCER_CREDIT_LINK: CreditLink | CreditLink[] | undefined; -export class DataManagementContext extends RefCounted { - worker: Worker; - chunkQueueManager: ChunkQueueManager; - chunkManager: ChunkManager; - - get rpc(): RPC { - return this.chunkQueueManager.rpc!; - } - - constructor( - public gl: GL, - public frameNumberCounter: FrameNumberCounter, - ) { - super(); - // Note: For compatibility with multiple bundlers, a browser-compatible URL - // must be used with `new URL`, which means a Node.js subpath import like - // "#src/chunk_worker.bundle.js" cannot be used. - this.worker = new Worker( - /* webpackChunkName: "neuroglancer_chunk_worker" */ - new URL("./chunk_worker.bundle.js", import.meta.url), - { type: "module" }, - ); - this.chunkQueueManager = this.registerDisposer( - new ChunkQueueManager( - new RPC(this.worker, /*waitUntilReady=*/ true), - this.gl, - this.frameNumberCounter, - { - gpuMemory: new CapacitySpecification({ - defaultItemLimit: 1e6, - defaultSizeLimit: 1e9, - }), - systemMemory: new CapacitySpecification({ - defaultItemLimit: 1e7, - defaultSizeLimit: 2e9, - }), - download: new CapacitySpecification({ - defaultItemLimit: 100, - defaultSizeLimit: Number.POSITIVE_INFINITY, - }), - compute: new CapacitySpecification({ - defaultItemLimit: 128, - defaultSizeLimit: 5e8, - }), - }, - ), - ); - this.chunkQueueManager.registerDisposer(() => this.worker.terminate()); - this.chunkManager = this.registerDisposer( - new ChunkManager(this.chunkQueueManager), - ); - } -} - export class InputEventBindings extends DataPanelInputEventBindings { global = new EventActionMap(); } @@ -212,6 +159,7 @@ export const VIEWER_TOP_ROW_CONFIG_OPTIONS = [ "showHelpButton", "showSettingsButton", "showEditStateButton", + "showToolPaletteButton", "showLayerListPanelButton", "showSelectionPanelButton", "showLayerSidePanelButton", @@ -262,7 +210,8 @@ export interface ViewerOptions VisibilityPrioritySpecification { dataContext: Owned; element: HTMLElement; - dataSourceProvider: Borrowed; + credentialsManager: CredentialsManager; + dataSourceProvider: Borrowed; uiConfiguration: ViewerUIConfiguration; showLayerDialog: boolean; inputEventBindings: InputEventBindings; @@ -328,6 +277,7 @@ class TrackableViewerState extends CompoundTrackable { this.add("partialViewport", viewer.partialViewport); this.add("selectedStateServer", viewer.selectedStateServer); this.add("toolBindings", viewer.toolBinder); + this.add("toolPalettes", viewer.toolPalettes); } restoreState(obj: any) { @@ -504,7 +454,7 @@ export class Viewer extends RefCounted implements ViewerState { visibility: WatchableVisibilityPriority; inputEventBindings: InputEventBindings; element: HTMLElement; - dataSourceProvider: Borrowed; + dataSourceProvider: Borrowed; uiConfiguration: ViewerUIConfiguration; @@ -549,14 +499,29 @@ export class Viewer extends RefCounted implements ViewerState { perspectiveView: new EventActionMap(), }, element = display.makeCanvasOverlayElement(), - dataSourceProvider = getDefaultDataSourceProvider({ - credentialsManager: defaultCredentialsManager, - }), + uiConfiguration = makeViewerUIConfiguration(), + dataSourceProvider = (() => { + const { credentialsManager = getDefaultCredentialsManager() } = options; + const sharedCredentialsManager = this.registerDisposer( + new SharedCredentialsManager(credentialsManager, dataContext.rpc), + ); + const kvStoreContext = this.registerDisposer( + new SharedKvStoreContext( + dataContext.chunkManager, + sharedCredentialsManager, + ), + ); + return getDefaultDataSourceProvider({ + credentialsManager: sharedCredentialsManager, + kvStoreContext, + }); + })(), } = options; this.visibility = visibility; this.inputEventBindings = inputEventBindings; this.element = element; + this.dataSourceProvider = dataSourceProvider; this.uiConfiguration = uiConfiguration; @@ -768,6 +733,20 @@ export class Viewer extends RefCounted implements ViewerState { topRow.appendChild(stateShare.element); } + { + const button = this.registerDisposer( + new MultiToolPaletteDropdownButton(this.toolPalettes), + ).element; + + this.registerDisposer( + new ElementVisibilityFromTrackableBoolean( + this.uiControlVisibility.showToolPaletteButton, + button, + ), + ); + topRow.appendChild(button); + } + { const { layerListPanelState } = this; const button = this.registerDisposer( @@ -988,6 +967,10 @@ export class Viewer extends RefCounted implements ViewerState { }), ); + this.registerDisposer( + new MultiToolPaletteManager(this.sidePanelManager, this.toolPalettes), + ); + const updateVisibility = () => { const shouldBeVisible = this.visibility.visible; if (shouldBeVisible !== this.visible) { @@ -1119,8 +1102,10 @@ export class Viewer extends RefCounted implements ViewerState { ); }; - private globalToolBinder = this.registerDisposer( - new GlobalToolBinder(this.toolInputEventMapBinder), + public toolPalettes = new MultiToolPaletteState(this); + + public globalToolBinder = this.registerDisposer( + new GlobalToolBinder(this.toolInputEventMapBinder, this.toolPalettes), ); public toolBinder = this.registerDisposer( diff --git a/src/volume_rendering/volume_render_layer.ts b/src/volume_rendering/volume_render_layer.ts index ee6064b678..51cf025338 100644 --- a/src/volume_rendering/volume_render_layer.ts +++ b/src/volume_rendering/volume_render_layer.ts @@ -74,7 +74,7 @@ import { drawBoxes, glsl_getBoxFaceVertexPosition, } from "#src/webgl/bounding_box.js"; -import type { Buffer } from "#src/webgl/buffer.js"; +import type { GLBuffer } from "#src/webgl/buffer.js"; import { getMemoizedBuffer } from "#src/webgl/buffer.js"; import { glsl_COLORMAPS } from "#src/webgl/colormaps.js"; import type { @@ -250,7 +250,7 @@ export class VolumeRenderingRenderLayer extends PerspectiveViewRenderLayer { return this.dataHistogramSpecifications.visibleHistograms; } - private histogramIndexBuffer: RefCountedValue; + private histogramIndexBuffer: RefCountedValue; constructor(options: VolumeRenderingRenderLayerOptions) { super(); diff --git a/src/webgl/buffer.ts b/src/webgl/buffer.ts index d976cde8de..bf4c18c64d 100644 --- a/src/webgl/buffer.ts +++ b/src/webgl/buffer.ts @@ -24,7 +24,7 @@ import type { AttributeIndex } from "#src/webgl/shader.js"; export type BufferType = number; export type WebGLDataType = number; export type WebGLBufferUsage = number; -export class Buffer implements Disposable { +export class GLBuffer implements Disposable { buffer: WebGLBuffer | null; constructor( public gl: WebGL2RenderingContext, @@ -98,7 +98,7 @@ export class Buffer implements Disposable { bufferType?: BufferType, usage?: WebGLBufferUsage, ) { - const buffer = new Buffer(gl, bufferType); + const buffer = new GLBuffer(gl, bufferType); buffer.setData(data, usage); return buffer; } @@ -118,7 +118,7 @@ export function getMemoizedBuffer( }), () => { const result = new RefCountedValue( - Buffer.fromData( + GLBuffer.fromData( gl, getter(...args), bufferType, diff --git a/src/webgl/context.ts b/src/webgl/context.ts index 5241781a6e..3da15d46e2 100644 --- a/src/webgl/context.ts +++ b/src/webgl/context.ts @@ -41,9 +41,13 @@ export function initializeWebGL(canvas: HTMLCanvasElement) { throw new Error("WebGL not supported."); } gl.memoize = new Memoize(); - gl.maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE); - gl.max3dTextureSize = gl.getParameter(gl.MAX_3D_TEXTURE_SIZE); - gl.maxTextureImageUnits = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS); + gl.maxTextureSize = gl.getParameter(WebGL2RenderingContext.MAX_TEXTURE_SIZE); + gl.max3dTextureSize = gl.getParameter( + WebGL2RenderingContext.MAX_3D_TEXTURE_SIZE, + ); + gl.maxTextureImageUnits = gl.getParameter( + WebGL2RenderingContext.MAX_TEXTURE_IMAGE_UNITS, + ); gl.tempTextureUnit = gl.maxTextureImageUnits - 1; // FIXME: verify that we received a stencil buffer diff --git a/src/webgl/empirical_cdf.ts b/src/webgl/empirical_cdf.ts index 71c35148ed..ebd5ffac08 100644 --- a/src/webgl/empirical_cdf.ts +++ b/src/webgl/empirical_cdf.ts @@ -105,24 +105,30 @@ const histogramSamples = 2 ** 14; * Generates a histogram from a single-channel uint8 texture. */ export class TextureHistogramGenerator extends RefCounted { - private shader = this.registerDisposer( - (() => { - const builder = new ShaderBuilder(this.gl); - builder.addOutputBuffer("vec4", "outputValue", 0); - builder.addAttribute("float", "aInput1"); - builder.addTextureSampler( - "sampler2D", - "uDataSampler", - histogramDataSamplerTextureUnit, - ); - builder.addTextureSampler( - "sampler2D", - "uDepthSampler", - histogramDepthTextureUnit, - ); - // builder.addUniform('float', 'uRandomSeed'); - builder.addVertexCode(glsl_simpleFloatHash); - builder.setVertexMain(` + private shader; + private inputIndexBuffer; + + constructor(public gl: GL) { + super(); + + this.shader = this.registerDisposer( + (() => { + const builder = new ShaderBuilder(this.gl); + builder.addOutputBuffer("vec4", "outputValue", 0); + builder.addAttribute("float", "aInput1"); + builder.addTextureSampler( + "sampler2D", + "uDataSampler", + histogramDataSamplerTextureUnit, + ); + builder.addTextureSampler( + "sampler2D", + "uDepthSampler", + histogramDepthTextureUnit, + ); + // builder.addUniform('float', 'uRandomSeed'); + builder.addVertexCode(glsl_simpleFloatHash); + builder.setVertexMain(` float uRandomSeed = 0.0; vec2 p = vec2(simpleFloatHash(vec2(aInput1 + float(gl_VertexID), uRandomSeed + float(gl_InstanceID))), simpleFloatHash(vec2(aInput1 + float(gl_VertexID) + 10.0, 5.0 + uRandomSeed + float(gl_InstanceID)))); @@ -135,23 +141,20 @@ if (stencilValue == 1.0) { } gl_PointSize = 1.0; `); - builder.setFragmentMain(` + builder.setFragmentMain(` outputValue = vec4(1.0, 1.0, 1.0, 1.0); `); - return builder.build(); - })(), - ); - - private inputIndexBuffer = this.registerDisposer( - getMemoizedBuffer( - this.gl, - WebGL2RenderingContext.ARRAY_BUFFER, - () => new Uint8Array(histogramSamplesPerInstance), - ), - ); + return builder.build(); + })(), + ); - constructor(public gl: GL) { - super(); + this.inputIndexBuffer = this.registerDisposer( + getMemoizedBuffer( + this.gl, + WebGL2RenderingContext.ARRAY_BUFFER, + () => new Uint8Array(histogramSamplesPerInstance), + ), + ); } static get(gl: GL) { diff --git a/src/webgl/index_emulation.ts b/src/webgl/index_emulation.ts index c1976599f6..c804937d53 100644 --- a/src/webgl/index_emulation.ts +++ b/src/webgl/index_emulation.ts @@ -15,7 +15,7 @@ */ import { RefCounted } from "#src/util/disposable.js"; -import { Buffer } from "#src/webgl/buffer.js"; +import { GLBuffer } from "#src/webgl/buffer.js"; import type { GL } from "#src/webgl/context.js"; import type { ShaderBuilder, ShaderProgram } from "#src/webgl/shader.js"; import { glsl_uint32 } from "#src/webgl/shader_lib.js"; @@ -23,11 +23,11 @@ import { glsl_uint32 } from "#src/webgl/shader_lib.js"; export class CountingBuffer extends RefCounted { length: number | undefined; webglType: number | undefined; - buffer: Buffer; + buffer: GLBuffer; constructor(public gl: GL) { super(); - this.buffer = this.registerDisposer(new Buffer(gl)); + this.buffer = this.registerDisposer(new GLBuffer(gl)); } resize(length: number) { @@ -115,7 +115,7 @@ export class IndexBufferAttributeHelper { builder.addAttribute("highp uint", this.name); } - bind(buffer: Buffer, shader: ShaderProgram) { + bind(buffer: GLBuffer, shader: ShaderProgram) { const attrib = shader.attribute(this.name); buffer.bindToVertexAttribI( attrib, @@ -130,7 +130,7 @@ export class IndexBufferAttributeHelper { } export function makeIndexBuffer(gl: WebGL2RenderingContext, data: Uint32Array) { - return Buffer.fromData( + return GLBuffer.fromData( gl, data, WebGL2RenderingContext.ARRAY_BUFFER, diff --git a/src/webgl/lerp.browser_test.ts b/src/webgl/lerp.browser_test.ts index c700d6761e..e925609bd5 100644 --- a/src/webgl/lerp.browser_test.ts +++ b/src/webgl/lerp.browser_test.ts @@ -15,6 +15,7 @@ */ import { expect, describe, it } from "vitest"; +import type { TypedArrayConstructor } from "#src/util/array.js"; import { DATA_TYPE_ARRAY_CONSTRUCTOR, DataType } from "#src/util/data_type.js"; import type { DataTypeInterval } from "#src/util/lerp.js"; import { @@ -39,7 +40,9 @@ function getRandomValue(dataType: DataType) { case DataType.INT16: case DataType.UINT32: case DataType.INT32: { - const buf = new DATA_TYPE_ARRAY_CONSTRUCTOR[dataType](1); + const buf = new (DATA_TYPE_ARRAY_CONSTRUCTOR[ + dataType + ] as TypedArrayConstructor)(1); getRandomValues(buf); return buf[0]; } diff --git a/src/webgl/offscreen.ts b/src/webgl/offscreen.ts index 12754a55c2..0a9e3f2bd1 100644 --- a/src/webgl/offscreen.ts +++ b/src/webgl/offscreen.ts @@ -110,9 +110,10 @@ export class DepthStencilRenderbuffer extends DepthRenderbuffer { export const StencilRenderbuffer = DepthStencilRenderbuffer; export class Framebuffer extends RefCounted { - framebuffer = this.gl.createFramebuffer(); + framebuffer; constructor(public gl: GL) { super(); + this.framebuffer = gl.createFramebuffer(); } disposed() { const { gl } = this; @@ -219,7 +220,7 @@ export class FramebufferConfiguration< depthBuffer: DepthBuffer | undefined; fullAttachmentList = new Array(); private attachmentVerified = false; - singleAttachmentList = [this.gl.COLOR_ATTACHMENT0]; + singleAttachmentList = [WebGL2RenderingContext.COLOR_ATTACHMENT0]; constructor( public gl: GL, @@ -352,9 +353,11 @@ export class OffscreenCopyHelper extends RefCounted { ) { super(); this.registerDisposer(shader); + this.copyVertexPositionsBuffer = getSquareCornersBuffer(gl); + this.copyTexCoordsBuffer = getSquareCornersBuffer(gl, 0, 0, 1, 1); } - private copyVertexPositionsBuffer = getSquareCornersBuffer(this.gl); - private copyTexCoordsBuffer = getSquareCornersBuffer(this.gl, 0, 0, 1, 1); + private copyVertexPositionsBuffer; + private copyTexCoordsBuffer; draw(...textures: (WebGLTexture | null)[]) { const { gl, shader } = this; diff --git a/src/webgl/shader.ts b/src/webgl/shader.ts index f87187c46b..ed2f4220db 100644 --- a/src/webgl/shader.ts +++ b/src/webgl/shader.ts @@ -186,12 +186,12 @@ export class ShaderProgram extends RefCounted { const vertexShader = (this.vertexShader = getShader( gl, vertexSource, - gl.VERTEX_SHADER, + WebGL2RenderingContext.VERTEX_SHADER, )); const fragmentShader = (this.fragmentShader = getShader( gl, fragmentSource, - gl.FRAGMENT_SHADER, + WebGL2RenderingContext.FRAGMENT_SHADER, )); const shaderProgram = gl.createProgram()!; diff --git a/src/webgl/shader_testing.ts b/src/webgl/shader_testing.ts index b65104a0cb..407f3b8cd7 100644 --- a/src/webgl/shader_testing.ts +++ b/src/webgl/shader_testing.ts @@ -117,10 +117,10 @@ export class FragmentShaderTester< Inputs extends FragmentShaderTestOutputs, Outputs extends FragmentShaderTestOutputs, > extends RefCounted { - builder = new ShaderBuilder(this.gl); + builder: ShaderBuilder; private shader_: ShaderProgram; offscreenFramebuffer: FramebufferConfiguration; - private vertexPositionsBuffer = getSquareCornersBuffer(this.gl, -1, -1, 1, 1); + private vertexPositionsBuffer; constructor( public gl: GL, @@ -128,8 +128,10 @@ export class FragmentShaderTester< public outputs: Outputs, ) { super(); - const { builder } = this; - this.offscreenFramebuffer = new FramebufferConfiguration(this.gl, { + const builder = (this.builder = new ShaderBuilder(gl)); + this.vertexPositionsBuffer = getSquareCornersBuffer(gl, -1, -1, 1, 1); + + this.offscreenFramebuffer = new FramebufferConfiguration(gl, { colorBuffers: makeTextureBuffersForOutputs(gl, outputs), }); builder.addAttribute("vec4", "shader_testing_aVertexPosition"); diff --git a/src/webgl/spheres.ts b/src/webgl/spheres.ts index e42e6790e2..e9a899a850 100644 --- a/src/webgl/spheres.ts +++ b/src/webgl/spheres.ts @@ -19,7 +19,7 @@ */ import { RefCounted } from "#src/util/disposable.js"; -import type { Buffer } from "#src/webgl/buffer.js"; +import type { GLBuffer } from "#src/webgl/buffer.js"; import { getMemoizedBuffer } from "#src/webgl/buffer.js"; import type { GL } from "#src/webgl/context.js"; import type { ShaderBuilder, ShaderProgram } from "#src/webgl/shader.js"; @@ -71,8 +71,8 @@ export function getSphereIndexArray( } export class SphereRenderHelper extends RefCounted { - private vertexBuffer: Buffer; - private indexBuffer: Buffer; + private vertexBuffer: GLBuffer; + private indexBuffer: GLBuffer; private numIndices: number; constructor(gl: GL, latitudeBands: number, longitudeBands: number) { diff --git a/src/webgl/texture_access.ts b/src/webgl/texture_access.ts index 82e225e999..a06061ef3f 100644 --- a/src/webgl/texture_access.ts +++ b/src/webgl/texture_access.ts @@ -495,8 +495,10 @@ ${shaderType} ${functionName}(${indexType} index) { } export class OneDimensionalTextureAccessHelper { - readTextureValue = `readTextureValue_${this.key}`; - constructor(public key: string) {} + readTextureValue: string; + constructor(public key: string) { + this.readTextureValue = `readTextureValue_${key}`; + } defineShader(builder: ShaderBuilder) { builder; } @@ -549,11 +551,13 @@ void ${this.readTextureValue}(highp ${samplerPrefix}sampler2D sampler, highp uin } export class TextureAccessHelper { - readTextureValue = `readTextureValue_${this.key}`; + readTextureValue: string; constructor( public key: string, public textureDims: number, - ) {} + ) { + this.readTextureValue = `readTextureValue_${key}`; + } getReadTextureValueCode( texelsPerElement: number, samplerPrefix: ShaderSamplerPrefix, diff --git a/src/webgl/vertex_id.ts b/src/webgl/vertex_id.ts index 9f20345679..7ca492268a 100644 --- a/src/webgl/vertex_id.ts +++ b/src/webgl/vertex_id.ts @@ -22,7 +22,7 @@ */ import { RefCounted } from "#src/util/disposable.js"; -import { Buffer } from "#src/webgl/buffer.js"; +import { GLBuffer } from "#src/webgl/buffer.js"; import type { GL } from "#src/webgl/context.js"; import type { ShaderBuilder } from "#src/webgl/shader.js"; @@ -40,11 +40,11 @@ int getVertexId () { export class VertexIdHelper extends RefCounted { size: number; - buffer: Buffer; + buffer: GLBuffer; constructor(gl: WebGL2RenderingContext) { super(); - this.buffer = new Buffer(gl); + this.buffer = new GLBuffer(gl); this.size = 0; } diff --git a/src/widget/channel_dimensions_widget.ts b/src/widget/channel_dimensions_widget.ts index 701f0b6a98..55ec155634 100644 --- a/src/widget/channel_dimensions_widget.ts +++ b/src/widget/channel_dimensions_widget.ts @@ -25,6 +25,7 @@ import { getDisplayLowerUpperBounds, insertDimensionAt, } from "#src/coordinate_transform.js"; +import type { WatchableValueInterface } from "#src/trackable_value.js"; import { animationFrameDebounce } from "#src/util/animation_frame_debounce.js"; import { arraysEqual } from "#src/util/array.js"; import { RefCounted } from "#src/util/disposable.js"; @@ -97,10 +98,11 @@ export class ChannelDimensionsWidget extends RefCounted { ); } - coordinateSpace = this.combiner.combined; + coordinateSpace: WatchableValueInterface; constructor(public combiner: CoordinateSpaceCombiner) { super(); + this.coordinateSpace = combiner.combined; const { element } = this; element.classList.add("neuroglancer-channel-dimensions-widget"); const debouncedUpdateView = this.registerCancellable( diff --git a/src/widget/invlerp.ts b/src/widget/invlerp.ts index 2543f49cfa..b56381eddc 100644 --- a/src/widget/invlerp.ts +++ b/src/widget/invlerp.ts @@ -347,20 +347,21 @@ class CdfPanel extends IndirectRenderedPanel { get drawOrder() { return 100; } - controller = this.registerDisposer( - new CdfController( - this.element, - this.parent.dataType, - () => this.parent.trackable.value, - (value: InvlerpParameters) => { - this.parent.trackable.value = value; - }, - ), - ); + controller; constructor(public parent: InvlerpWidget) { super(parent.display, document.createElement("div"), parent.visibility); const { element } = this; element.classList.add("neuroglancer-invlerp-cdfpanel"); + this.controller = this.registerDisposer( + new CdfController( + element, + parent.dataType, + () => parent.trackable.value, + (value: InvlerpParameters) => { + parent.trackable.value = value; + }, + ), + ); } private dataValuesBuffer = this.registerDisposer( @@ -730,10 +731,7 @@ export function adjustInvlerpBrightnessContrast( export class InvlerpWidget extends Tab { cdfPanel = this.registerDisposer(new CdfPanel(this)); - boundElements = { - range: createRangeBoundInputs("range", this.dataType, this.trackable), - window: createRangeBoundInputs("window", this.dataType, this.trackable), - }; + boundElements; invertArrows: HTMLElement[]; autoRangeFinder: AutoRangeFinder; get texture() { @@ -754,6 +752,11 @@ export class InvlerpWidget extends Tab { public legendShaderOptions: LegendShaderOptions | undefined, ) { super(visibility); + this.boundElements = { + range: createRangeBoundInputs("range", dataType, trackable), + window: createRangeBoundInputs("window", dataType, trackable), + }; + this.registerDisposer( histogramSpecifications.visibility.add(this.visibility), ); diff --git a/src/widget/layer_control.ts b/src/widget/layer_control.ts index d1c14a06f5..7497ee3006 100644 --- a/src/widget/layer_control.ts +++ b/src/widget/layer_control.ts @@ -100,6 +100,13 @@ function makeControl( visibility, }); controlElement.classList.add("neuroglancer-layer-control-control"); + + // Disable drag and drop on the control itself to avoid interference. + controlElement.draggable = true; + controlElement.addEventListener("dragstart", (event) => { + event.stopPropagation(); + event.preventDefault(); + }); controlContainer.appendChild(controlElement); return { controlContainer, @@ -119,7 +126,13 @@ export class LayerControlTool< ) { super(layer); } + + isLoading() { + return false; + } + activate(activation: ToolActivation) { + if (this.isLoading()) return; const { options } = this; const { layer } = this; const { isValid } = options; @@ -136,6 +149,19 @@ export class LayerControlTool< body.appendChild(controlContainer); options.activateTool(activation, control); } + renderInPalette(context: RefCounted) { + if (this.isLoading()) return undefined; + const { controlContainer } = makeControl( + context, + this.layer, + this.options, + new WatchableVisibilityPriority(WatchableVisibilityPriority.VISIBLE), + ); + controlContainer.classList.add( + "neuroglancer-layer-options-control-container", + ); + return controlContainer; + } get description() { const { options } = this; return options.toolDescription ?? options.label; @@ -162,7 +188,11 @@ function makeLayerControlToOptionsTab( ); label.prepend( context.registerDisposer( - new ToolBindingWidget(layer.toolBinder, options.toolJson), + new ToolBindingWidget( + layer.toolBinder, + options.toolJson, + controlContainer, + ), ).element, ); return controlContainer; @@ -202,5 +232,15 @@ export function registerLayerControl( layerType, toolId, (layer) => new LayerControlTool(layer, options), + (layer, onChange) => { + const isValid = options.isValid?.(layer); + if (isValid !== undefined && onChange !== undefined) { + isValid.changed.addOnce(onChange); + } + if (options.isValid?.(layer).value === false) { + return []; + } + return [{ type: toolId }]; + }, ); } diff --git a/src/widget/multiline_autocomplete.css b/src/widget/multiline_autocomplete.css index 8ff86179fd..86ad6b91ae 100644 --- a/src/widget/multiline_autocomplete.css +++ b/src/widget/multiline_autocomplete.css @@ -48,8 +48,9 @@ font-size: medium; } -.neuroglancer-multiline-autocomplete-dropdown { - color: #fff; +.neuroglancer-multiline-autocomplete-dropdown, +.neuroglancer-multiline-autocomplete-error, +.neuroglancer-multiline-autocomplete-progress { background-color: #181818; position: fixed; display: block; @@ -67,6 +68,19 @@ word-wrap: break-word; } +.neuroglancer-multiline-autocomplete-dropdown { + color: #fff; +} + +.neuroglancer-multiline-autocomplete-error { + color: red; +} + +.neuroglancer-multiline-autocomplete-progress { + font-style: italic; + color: #ccc; +} + .neuroglancer-multiline-autocomplete-completion:nth-child(even):not( .neuroglancer-multiline-autocomplete-completion-active ) { @@ -88,3 +102,8 @@ font-style: italic; color: #f9f; } + +.neuroglancer-multiline-autocomplete-linebreak::after { + content: "\a"; + white-space: pre; +} diff --git a/src/widget/multiline_autocomplete.ts b/src/widget/multiline_autocomplete.ts index 4a3f8c5a60..e2ce2b5a66 100644 --- a/src/widget/multiline_autocomplete.ts +++ b/src/widget/multiline_autocomplete.ts @@ -17,8 +17,6 @@ import "#src/widget/multiline_autocomplete.css"; import { debounce } from "lodash-es"; -import type { CancellationToken } from "#src/util/cancellation.js"; -import { CancellationTokenSource } from "#src/util/cancellation.js"; import type { BasicCompletionResult, Completion, @@ -27,13 +25,16 @@ import type { import { RefCounted } from "#src/util/disposable.js"; import { removeChildren, removeFromParent } from "#src/util/dom.js"; import { positionDropdown } from "#src/util/dropdown.js"; +import { formatErrorMessage } from "#src/util/error.js"; import { EventActionMap, KeyboardEventBinder, registerActionListener, } from "#src/util/keyboard_bindings.js"; import { longestCommonPrefix } from "#src/util/longest_common_prefix.js"; +import type { ProgressListener } from "#src/util/progress_listener.js"; import { Signal } from "#src/util/signal.js"; +import { ProgressListenerWidget } from "#src/widget/progress_listener.js"; import { VirtualList } from "#src/widget/virtual_list.js"; export type { @@ -58,19 +59,16 @@ export function makeDefaultCompletionElement(completion: Completion) { return element; } -function* splitByWordBreaks(value: string) { - while (value.length > 0) { - const m = value.match(/[:/_]+/); - if (m === null) { - yield value; - return; - } - const endOffset = m.index! + m[0].length; - yield value.substring(0, endOffset); - value = value.substring(endOffset); - } +export interface SyntaxHighlighter { + splitPattern: RegExp; + getSeparatorNode: (text: string) => HTMLElement; } +const DEFAULT_SYNTAX_HIGHLIGHTER: SyntaxHighlighter = { + splitPattern: /.*/gs, + getSeparatorNode: () => document.createElement("wbr"), +}; + export function makeCompletionElementWithDescription( completion: CompletionWithDescription, ) { @@ -96,9 +94,14 @@ const keyMap = EventActionMap.fromObject({ escape: { action: "cancel", preventDefault: false, stopPropagation: false }, }); +export interface CompletionRequest { + value: string; + selectionRange?: { begin: number; end: number } | undefined; +} export type Completer = ( - value: string, - cancellationToken: CancellationToken, + request: CompletionRequest, + signal: AbortSignal, + progressListener: ProgressListener, ) => Promise | null; const DEFAULT_COMPLETION_DELAY = 200; // milliseconds @@ -113,9 +116,11 @@ export class AutocompleteTextInput extends RefCounted { private prevInputValue: string | undefined = ""; private completionsVisible = false; private activeCompletionPromise: Promise | null = null; - private activeCompletionCancellationToken: - | CancellationTokenSource - | undefined = undefined; + private activeCompletionAbortController: AbortController | undefined = + undefined; + private activeCompletionProgressListener: ProgressListenerWidget | undefined = + undefined; + private completionErrorElement: HTMLElement | undefined; private hasFocus = false; private completionResult: CompletionResult | null = null; private dropdownContentsStale = true; @@ -160,14 +165,15 @@ export class AutocompleteTextInput extends RefCounted { ) { const completionDisabled = this.completionDisabled !== -1; this.onInput.dispatch(value); - const { inputElement } = this; + const { inputElement, syntaxHighlighter } = this; removeChildren(inputElement); let outputOffset = 0; const r = selection !== undefined ? document.createRange() : undefined; let isFirst = true; - for (const text of splitByWordBreaks(value)) { + for (const text of value.match(syntaxHighlighter.splitPattern)!) { + if (!text) continue; if (!isFirst) { - inputElement.appendChild(document.createElement("wbr")); + inputElement.appendChild(syntaxHighlighter.getSeparatorNode(text)); } isFirst = false; const newOutputOffset = outputOffset + text.length; @@ -215,30 +221,56 @@ export class AutocompleteTextInput extends RefCounted { completer: Completer; private resizeHandler = () => { - if (!this.completionsVisible) return; this.updateDropdownStyle(); }; private resizeObserver = new ResizeObserver(this.resizeHandler); - constructor(options: { completer: Completer; delay?: number }) { + private syntaxHighlighter: SyntaxHighlighter; + + constructor(options: { + completer: Completer; + syntaxHighlighter?: SyntaxHighlighter; + delay?: number; + }) { super(); this.completer = options.completer; - const { delay = DEFAULT_COMPLETION_DELAY } = options; + const { + delay = DEFAULT_COMPLETION_DELAY, + syntaxHighlighter = DEFAULT_SYNTAX_HIGHLIGHTER, + } = options; + this.syntaxHighlighter = syntaxHighlighter; const debouncedCompleter = (this.scheduleUpdateCompletions = debounce( () => { - const cancellationToken = (this.activeCompletionCancellationToken = - new CancellationTokenSource()); + const abortController = (this.activeCompletionAbortController = + new AbortController()); + const progressListener = this.makeCompletionProgressListener(); const activeCompletionPromise = (this.activeCompletionPromise = - this.completer(this.value, cancellationToken)); + this.completer( + { + value: this.value, + selectionRange: this.getSelectionRange(), + }, + abortController.signal, + progressListener, + )); if (activeCompletionPromise !== null) { - activeCompletionPromise.then((completionResult) => { - if (this.activeCompletionPromise === activeCompletionPromise) { - this.setCompletions(completionResult); - this.activeCompletionPromise = null; - } - }); + activeCompletionPromise.then( + (completionResult) => { + if (this.activeCompletionPromise === activeCompletionPromise) { + this.setCompletions(completionResult); + this.activeCompletionPromise = null; + this.removeProgressListener(); + } + }, + (reason) => { + if (this.activeCompletionPromise === activeCompletionPromise) { + this.removeProgressListener(); + this.showCompletionError(reason); + } + }, + ); } }, delay, @@ -256,9 +288,9 @@ export class AutocompleteTextInput extends RefCounted { inputElement.contentEditable = "true"; inputElement.spellcheck = false; - element.appendChild(document.createTextNode("\u200b")); // Prevent input area from collapsing element.appendChild(inputElement); element.appendChild(hintElement); + element.appendChild(document.createTextNode("\u200b")); // Prevent input area from collapsing inputElement.classList.add("neuroglancer-multiline-autocomplete-input"); hintElement.classList.add("neuroglancer-multiline-autocomplete-hint"); inputElement.addEventListener("input", () => { @@ -414,6 +446,34 @@ export class AutocompleteTextInput extends RefCounted { }); } + private removeProgressListener() { + if (this.activeCompletionProgressListener !== undefined) { + this.element.removeChild(this.activeCompletionProgressListener.element); + this.activeCompletionProgressListener = undefined; + } + } + + private makeCompletionProgressListener(): ProgressListenerWidget { + const widget = new ProgressListenerWidget(); + this.element.appendChild(widget.element); + widget.element.classList.add( + "neuroglancer-multiline-autocomplete-progress", + ); + this.activeCompletionProgressListener = widget; + this.updateDropdownStyle(); + return widget; + } + + private showCompletionError(reason: unknown) { + if (reason === null) return; + const element = document.createElement("div"); + this.completionErrorElement = element; + element.classList.add("neuroglancer-multiline-autocomplete-error"); + element.textContent = formatErrorMessage(reason); + this.element.appendChild(element); + this.updateDropdownStyle(); + } + private shouldAttemptCompletion() { const { inputElement } = this; if (document.activeElement !== inputElement) return false; @@ -496,9 +556,12 @@ export class AutocompleteTextInput extends RefCounted { } private updateDropdownStyle() { - const { completionsVirtualList, element } = this; - if (completionsVirtualList !== undefined) { - positionDropdown(completionsVirtualList.element, element, { + const widget = + this.completionsVirtualList?.element ?? + this.activeCompletionProgressListener?.element ?? + this.completionErrorElement; + if (widget !== undefined) { + positionDropdown(widget, this.element, { horizontal: false, }); } @@ -603,13 +666,15 @@ export class AutocompleteTextInput extends RefCounted { } else { this.hasResultForDropdown = true; // Check for a common prefix. - const commonResultPrefix = longestCommonPrefix( - (function* () { - for (const completion of completionResult.completions) { - yield completion.value; - } - })(), - ); + const commonResultPrefix = + completionResult.defaultCompletion ?? + longestCommonPrefix( + (function* () { + for (const completion of completionResult.completions) { + yield completion.value; + } + })(), + ); const commonPrefix = this.getCompletedValue(commonResultPrefix); if (commonPrefix.startsWith(value)) { this.commonPrefix = commonPrefix; @@ -628,12 +693,13 @@ export class AutocompleteTextInput extends RefCounted { hintValue = ""; } hintValue = hintValue.substring(value.length); - const { hintElement } = this; + const { hintElement, syntaxHighlighter } = this; removeChildren(hintElement); let isFirst = true; - for (const text of splitByWordBreaks(hintValue)) { + for (const text of hintValue.match(syntaxHighlighter.splitPattern)!) { + if (!text) continue; if (!isFirst) { - hintElement.appendChild(document.createElement("wbr")); + hintElement.appendChild(syntaxHighlighter.getSeparatorNode(text)); } isFirst = false; const node = document.createTextNode(text); @@ -764,20 +830,18 @@ export class AutocompleteTextInput extends RefCounted { private cancelActiveCompletion() { this.prevInputValue = undefined; - const token = this.activeCompletionCancellationToken; - if (token !== undefined) { - token.cancel(); - } - this.activeCompletionCancellationToken = undefined; + this.activeCompletionAbortController?.abort(); + this.activeCompletionAbortController = undefined; this.activeCompletionPromise = null; + this.removeProgressListener(); } private clearCompletions() { + this.dropdownContentsStale = true; + this.dropdownStyleStale = true; if (this.completionResult !== null) { this.activeIndex = -1; this.completionResult = null; - this.dropdownContentsStale = true; - this.dropdownStyleStale = true; this.commonPrefix = ""; const { completionsVirtualList } = this; if (completionsVirtualList !== undefined) { @@ -786,6 +850,12 @@ export class AutocompleteTextInput extends RefCounted { } this.updateDropdown(); } + + const { completionErrorElement } = this; + if (completionErrorElement !== undefined) { + this.element.removeChild(completionErrorElement); + this.completionErrorElement = undefined; + } } get value() { diff --git a/src/widget/position_plot.ts b/src/widget/position_plot.ts index 0138de285f..960c05c80c 100644 --- a/src/widget/position_plot.ts +++ b/src/widget/position_plot.ts @@ -98,9 +98,9 @@ export class PositionPlot extends RefCounted { visible = true; dragging = new WatchableValue(false); - tickWidth: number = this.orientation === "column" ? 10 : 5; - barWidth: number = this.orientation === "column" ? 15 : 10; - barRightMargin: number = this.orientation === "column" ? 10 : 2; + tickWidth: number; + barWidth: number; + barRightMargin: number; canvasWidth: number; constructor( @@ -109,6 +109,10 @@ export class PositionPlot extends RefCounted { public orientation: "row" | "column" = "column", ) { super(); + this.tickWidth = orientation === "column" ? 10 : 5; + this.barWidth = orientation === "column" ? 15 : 10; + this.barRightMargin = orientation === "column" ? 10 : 2; + this.canvasWidth = this.tickWidth + this.barWidth + this.barRightMargin; const plotElement = this.element; plotElement.classList.add("neuroglancer-position-dimension-plot"); @@ -173,6 +177,7 @@ export class PositionPlot extends RefCounted { this.visible = false; return; } + this.element.style.display = ""; this.visible = true; const { lowerBound, upperBound } = normalizedDimensionBounds; diff --git a/src/widget/position_widget.css b/src/widget/position_widget.css index 24eb022c1f..388fdfd8c0 100644 --- a/src/widget/position_widget.css +++ b/src/widget/position_widget.css @@ -226,8 +226,29 @@ interferes with our click handling. Setting `pointer-events: none;` avoids that height: 12px; } +.neuroglancer-position-tool-in-palette { + display: grid; +} + +.neuroglancer-position-tool-in-palette > .neuroglancer-position-widget { + grid-row: 1; + grid-column: 1; +} + +.neuroglancer-position-tool-in-palette > .neuroglancer-position-dimension-plot { + grid-row: 2; + grid-column: 1 / 10; +} + +.neuroglancer-position-tool-in-palette > .neuroglancer-checkbox-icon { + grid-row: 1; + grid-column: 9; +} + .neuroglancer-position-tool { background-color: #474747; + display: flex; + flex-direction: row; } .neuroglancer-position-dimension-playback-header { diff --git a/src/widget/position_widget.ts b/src/widget/position_widget.ts index 7dfb1eb6db..e985b8fdaa 100644 --- a/src/widget/position_widget.ts +++ b/src/widget/position_widget.ts @@ -24,6 +24,7 @@ import type { CoordinateSpace, CoordinateSpaceCombiner, DimensionId, + TrackableCoordinateSpace, } from "#src/coordinate_transform.js"; import { clampAndRoundCoordinateToVoxelCenter, @@ -44,6 +45,7 @@ import { makeCachedDerivedWatchableValue, WatchableValue, } from "#src/trackable_value.js"; +import { popDragStatus, pushDragStatus } from "#src/ui/drag_and_drop.js"; import type { LocalToolBinder, ToolActivation } from "#src/ui/tool.js"; import { makeToolActivationStatusMessage, @@ -51,6 +53,8 @@ import { registerTool, Tool, } from "#src/ui/tool.js"; +import type { ToolDragSource } from "#src/ui/tool_drag_and_drop.js"; +import { beginToolDrag, endToolDrag } from "#src/ui/tool_drag_and_drop.js"; import { animationFrameDebounce } from "#src/util/animation_frame_debounce.js"; import { arraysEqual, binarySearch } from "#src/util/array.js"; import { setClipboard } from "#src/util/clipboard.js"; @@ -151,6 +155,8 @@ class DimensionWidget { draggingPosition = false; hasFocus = false; + dimensionIndex: number; + constructor( public coordinateSpace: CoordinateSpace, public id: DimensionId, @@ -175,6 +181,7 @@ class DimensionWidget { container.draggable = true; container.tabIndex = -1; } + this.dimensionIndex = initialDimensionIndex; container.appendChild(nameContainer); container.appendChild(scaleElement); nameContainer.appendChild(nameElement); @@ -230,15 +237,17 @@ class DimensionWidget { ); if (allowFocus) { - nameContainer.addEventListener("dblclick", () => { + nameContainer.addEventListener("dblclick", (event) => { nameElement.disabled = false; nameElement.focus(); nameElement.select(); + event.stopPropagation(); }); - scaleContainer.addEventListener("dblclick", () => { + scaleContainer.addEventListener("dblclick", (event) => { scaleElement.disabled = false; scaleElement.focus(); scaleElement.select(); + event.stopPropagation(); }); coordinate.addEventListener("focus", () => { coordinate.select(); @@ -293,6 +302,7 @@ export class PositionWidget extends RefCounted { private getToolBinder: (() => LocalToolBinder | undefined) | undefined; private allowFocus: boolean; private showPlayback: boolean; + private showDropdown: boolean; private dimensionWidgets = new Map(); private dimensionWidgetList: DimensionWidget[] = []; @@ -470,11 +480,11 @@ export class PositionWidget extends RefCounted { dropdown.appendChild(entryElement); entries.push({ entryElement, coordinateElement, labelElement }); } - // const dropdownOwner = widget.dropdownOwner!; } private openDropdown(widget: DimensionWidget) { if (widget.dropdownOwner !== undefined) return; + if (!this.showDropdown) return; const dimensionIndex = this.getDimensionIndex(widget.id); if (dimensionIndex === -1) return; this.closeDropdown(); @@ -591,13 +601,43 @@ export class PositionWidget extends RefCounted { coordinateSpace, id, initialDimensionIndex, - { allowFocus: this.allowFocus, showPlayback: this.showPlayback }, + { + allowFocus: this.allowFocus, + showPlayback: this.showPlayback, + }, ); + let toolDragSource: ToolDragSource | undefined; + const localBinder = this.getToolBinder?.(); + if (localBinder !== undefined) { + const self = this; + toolDragSource = { + localBinder, + get toolJson() { + return { + type: DIMENSION_TOOL_ID, + dimension: + self.position.coordinateSpace.value.names[ + self.getDimensionIndex(id) + ], + }; + }, + }; + } if (this.singleDimensionId === undefined) { widget.container.addEventListener("dragstart", (event: DragEvent) => { this.dragSource = widget; event.stopPropagation(); event.dataTransfer!.setData("neuroglancer-dimension", ""); + pushDragStatus( + event, + widget.container, + "drag", + "Drag to reorder dimensions, to an existing tool palette, or to the " + + "left/right/top/bottom of another panel to create a new tool palette", + ); + if (toolDragSource !== undefined) { + beginToolDrag(toolDragSource); + } }); widget.container.addEventListener("dragenter", (event: DragEvent) => { const { dragSource } = this; @@ -610,10 +650,13 @@ export class PositionWidget extends RefCounted { this.reorderDimensionTo(targetIndex, sourceIndex); }); widget.container.addEventListener("dragend", (event: DragEvent) => { - event; if (this.dragSource === widget) { this.dragSource = undefined; } + popDragStatus(event, widget.container, "drag"); + if (toolDragSource !== undefined) { + endToolDrag(toolDragSource); + } }); } if (this.allowFocus) { @@ -832,7 +875,7 @@ export class PositionWidget extends RefCounted { coordinateSpace: { value: coordinateSpace }, }, } = this; - if (!coordinateSpace.valid) { + if (!coordinateSpace.valid && this.singleDimensionId === undefined) { coordinateSpace = emptyInvalidCoordinateSpace; } this.coordinateSpace = coordinateSpace; @@ -860,6 +903,7 @@ export class PositionWidget extends RefCounted { widget.maxPositionWidthSeen = maxPositionWidth; } else { widget.coordinateSpace = coordinateSpace; + widget.dimensionIndex = i; } widget.maxPositionWidth = maxPositionWidth; const name = names[i]; @@ -969,12 +1013,14 @@ export class PositionWidget extends RefCounted { private updateNameValidity() { const { dimensionWidgetList } = this; - const names = dimensionWidgetList.map((w) => w.nameElement.value); - const rank = names.length; + const names = Array.from(this.position.coordinateSpace.value.names); + for (const widget of dimensionWidgetList) { + names[widget.dimensionIndex] = widget.nameElement.value; + } const isValid = this.combiner.getRenameValidity(names); - for (let i = 0; i < rank; ++i) { - dimensionWidgetList[i].nameElement.dataset.isValid = - isValid[i] === false ? "false" : "true"; + for (const widget of dimensionWidgetList) { + widget.nameElement.dataset.isValid = + isValid[widget.dimensionIndex] === false ? "false" : "true"; } } @@ -993,6 +1039,7 @@ export class PositionWidget extends RefCounted { getToolBinder = undefined, allowFocus = true, showPlayback = true, + showDropdown = true, }: { copyButton?: boolean; velocity?: CoordinateSpacePlaybackVelocity; @@ -1000,6 +1047,7 @@ export class PositionWidget extends RefCounted { getToolBinder?: (() => LocalToolBinder | undefined) | undefined; allowFocus?: boolean; showPlayback?: boolean; + showDropdown?: boolean; } = {}, ) { super(); @@ -1009,6 +1057,7 @@ export class PositionWidget extends RefCounted { this.getToolBinder = getToolBinder; this.allowFocus = allowFocus; this.showPlayback = showPlayback; + this.showDropdown = showDropdown; this.registerDisposer( position.coordinateSpace.changed.add( this.registerCancellable( @@ -1117,15 +1166,13 @@ export class PositionWidget extends RefCounted { private updatePosition() { if (!this.allowFocus) return; - const { dimensionWidgetList } = this; const { position } = this; const { value: voxelCoordinates } = position; const coordinateSpace = position.coordinateSpace.value; if (voxelCoordinates === undefined) return; - const rank = dimensionWidgetList.length; let modified = false; - for (let i = 0; i < rank; ++i) { - const widget = dimensionWidgetList[i]; + for (const widget of this.dimensionWidgetList) { + const { dimensionIndex } = widget; if (!widget.modified) continue; widget.modified = false; modified = true; @@ -1137,11 +1184,11 @@ export class PositionWidget extends RefCounted { Number.isInteger(value) && !valueString.includes(".") && coordinateSpace !== undefined && - !coordinateSpace.bounds.voxelCenterAtIntegerCoordinates[i] + !coordinateSpace.bounds.voxelCenterAtIntegerCoordinates[dimensionIndex] ) { value += 0.5; } - voxelCoordinates[i] = value; + voxelCoordinates[dimensionIndex] = value; } if (modified) { position.value = voxelCoordinates; @@ -1155,7 +1202,10 @@ export class PositionWidget extends RefCounted { position: { coordinateSpace }, } = this; const existing = coordinateSpace.value; - const names = dimensionWidgetList.map((x) => x.nameElement.value); + const names = Array.from(existing.names); + for (const widget of dimensionWidgetList) { + names[widget.dimensionIndex] = widget.nameElement.value; + } if (this.combiner.getRenameValidity(names).includes(false)) return false; const existingNames = existing.names; if (arraysEqual(existingNames, names)) return false; @@ -1174,17 +1224,18 @@ export class PositionWidget extends RefCounted { position: { coordinateSpace }, } = this; const existing = coordinateSpace.value; - const scalesAndUnits = dimensionWidgetList.map((x) => - parseScale(x.scaleElement.value), - ); - if (scalesAndUnits.includes(undefined)) { - return false; - } - const newScales = Float64Array.from(scalesAndUnits, (x) => x!.scale); - const newUnits = Array.from(scalesAndUnits, (x) => x!.unit); const { scales, units } = existing; - if (arraysEqual(scales, newScales) && arraysEqual(units, newUnits)) + const newScales = Float64Array.from(scales); + const newUnits = Array.from(units); + for (const { dimensionIndex, scaleElement } of dimensionWidgetList) { + const result = parseScale(scaleElement.value); + if (result === undefined) return false; + newScales[dimensionIndex] = result.scale; + newUnits[dimensionIndex] = result.unit; + } + if (arraysEqual(scales, newScales) && arraysEqual(units, newUnits)) { return false; + } const timestamps = existing.timestamps.map((t, i) => newScales[i] === scales[i] && newUnits[i] === units[i] ? t : Date.now(), ); @@ -1215,22 +1266,23 @@ export class PositionWidget extends RefCounted { this.updateDimensions(); const { position: { value: voxelCoordinates }, - dimensionWidgetList, } = this; - const rank = dimensionWidgetList.length; if (voxelCoordinates === undefined) { return; } const coordinateSpace = this.coordinateSpace!; const { velocity } = this; - for (let i = 0; i < rank; ++i) { - const widget = dimensionWidgetList[i]; + for (const widget of this.dimensionWidgetList) { + const { dimensionIndex } = widget; const inputElement = widget.coordinate; - const newCoord = Math.floor(voxelCoordinates[i]); + const newCoord = Math.floor(voxelCoordinates[dimensionIndex]); const newValue = newCoord.toString(); updateCoordinateFieldWidth(widget, newValue); inputElement.value = newValue; - const coordinateArray = getCoordinateArray(coordinateSpace, i); + const coordinateArray = getCoordinateArray( + coordinateSpace, + dimensionIndex, + ); let label = ""; if (coordinateArray != null) { const { coordinates } = coordinateArray; @@ -1242,7 +1294,7 @@ export class PositionWidget extends RefCounted { const labelElement = widget.coordinateLabel; labelElement.textContent = label; if (this.showPlayback) { - const velocityInfo = velocity?.value?.[i]; + const velocityInfo = velocity?.value?.[dimensionIndex]; if (velocityInfo !== undefined) { const paused = velocityInfo.paused; widget.playButton.style.display = paused ? "" : "none"; @@ -1328,11 +1380,68 @@ class DimensionTool extends Tool { return this.viewer.coordinateSpaceCombiner.combined; } + private adjustDimensionHandler( + actionEvent: ActionEvent, + positionWidget: PositionWidget, + ) { + actionEvent.stopPropagation(); + const event = actionEvent.detail; + const { deltaY } = event; + if (deltaY === 0) { + return; + } + positionWidget.adjustDimensionPosition(this.dimensionId, Math.sign(deltaY)); + } + + private adjustVelocityHandler( + actionEvent: ActionEvent, + viewer: SupportsDimensionTool, + ) { + actionEvent.stopPropagation(); + const factor = getWheelZoomAmount(actionEvent.detail); + viewer.velocity.multiplyVelocity(this.dimensionId, factor); + } + activate(activation: ToolActivation) { const { viewer } = this; const { content } = makeToolActivationStatusMessage(activation); - content.classList.add("neuroglancer-position-tool"); + const { positionWidget } = this.makeTool( + activation, + content, + /*inPalette=*/ false, + ); activation.bindInputEventMap(TOOL_INPUT_EVENT_MAP); + activation.bindAction( + "adjust-position-via-wheel", + (actionEvent) => this.adjustDimensionHandler(actionEvent, positionWidget), + ); + activation.bindAction( + "adjust-velocity-via-wheel", + (actionEvent) => this.adjustVelocityHandler(actionEvent, viewer), + ); + activation.bindAction("toggle-playback", (event) => { + event.stopPropagation(); + viewer.velocity.togglePlayback(this.dimensionId); + }); + } + + renderInPalette(context: RefCounted) { + const content = document.createElement("div"); + this.makeTool(context, content, /*inPalette=*/ true); + return content; + } + + private makeTool( + activation: RefCounted, + content: HTMLElement, + inPalette: boolean, + ) { + const { viewer } = this; + if (inPalette) { + content.classList.add("neuroglancer-position-tool-in-palette"); + } else { + content.classList.add("neuroglancer-position-tool"); + } const positionWidget = new PositionWidget( viewer.position, viewer.coordinateSpaceCombiner, @@ -1340,8 +1449,9 @@ class DimensionTool extends Tool { velocity: viewer.velocity, singleDimensionId: this.dimensionId, copyButton: false, - allowFocus: false, + allowFocus: inPalette, showPlayback: false, + showDropdown: false, }, ); positionWidget.element.style.userSelect = "none"; @@ -1351,21 +1461,6 @@ class DimensionTool extends Tool { ); plot.element.style.flex = "1"; content.appendChild(plot.element); - activation.bindAction( - "adjust-position-via-wheel", - (actionEvent) => { - actionEvent.stopPropagation(); - const event = actionEvent.detail; - const { deltaY } = event; - if (deltaY === 0) { - return; - } - positionWidget.adjustDimensionPosition( - this.dimensionId, - Math.sign(deltaY), - ); - }, - ); const watchableVelocity = this.velocity.dimensionVelocity( activation, @@ -1470,49 +1565,53 @@ class DimensionTool extends Tool { ).element, ); - activation.bindAction( + this.registerDisposer(new MouseEventBinder(plot.element, inputEventMap)); + + registerActionListener( + plot.element, + "adjust-via-wheel", + (actionEvent) => this.adjustDimensionHandler(actionEvent, positionWidget), + ); + + registerActionListener( + plot.element, "adjust-velocity-via-wheel", - (actionEvent) => { - actionEvent.stopPropagation(); - const factor = getWheelZoomAmount(actionEvent.detail); - viewer.velocity.multiplyVelocity(this.dimensionId, factor); - }, + (actionEvent) => this.adjustVelocityHandler(actionEvent, viewer), ); - activation.bindAction("toggle-playback", (event) => { - event.stopPropagation(); - viewer.velocity.togglePlayback(this.dimensionId); - }); + + return { positionWidget }; + } + + private savedDimensionName: string = ""; + + get dimensionName(): string | undefined { + const { dimensionId } = this; + const coordinateSpace = this.coordinateSpace.value; + const i = coordinateSpace.ids.indexOf(dimensionId); + if (i === -1) return undefined; + return coordinateSpace.names[i]; } get description() { return `dim ${this.dimensionName}`; } - dimensionIndex: number; - dimensionName: string; - constructor( public viewer: SupportsDimensionTool, public dimensionId: DimensionId, ) { super(viewer.toolBinder); - const coordinateSpace = this.coordinateSpace.value; - const i = (this.dimensionIndex = coordinateSpace.ids.indexOf(dimensionId)); - this.dimensionName = coordinateSpace.names[i]; + this.savedDimensionName = this.dimensionName!; this.registerDisposer( this.coordinateSpace.changed.add(() => { - const coordinateSpace = this.coordinateSpace.value; - const i = (this.dimensionIndex = - this.coordinateSpace.value.ids.indexOf(dimensionId)); - if (i === -1) { + const dimensionName = this.dimensionName; + if (dimensionName === undefined) { this.unbind(); return; } - const newName = coordinateSpace.names[i]; - if (this.dimensionName !== newName) { - this.dimensionName = newName; - this.changed.dispatch(); - } + if (dimensionName === this.savedDimensionName) return; + this.savedDimensionName = dimensionName; + this.changed.dispatch(); }), ); } @@ -1535,34 +1634,56 @@ function makeDimensionTool(viewer: SupportsDimensionTool, obj: unknown) { return new DimensionTool(viewer, coordinateSpace.ids[dimensionIndex]); } +function listDimensionTools( + coordinateSpace: TrackableCoordinateSpace, + onChange?: () => void, +) { + if (onChange !== undefined) { + coordinateSpace.changed.addOnce(onChange); + } + return coordinateSpace.value.names.map((name) => ({ + type: DIMENSION_TOOL_ID, + dimension: name, + })); +} + export function registerDimensionToolForViewer(contextType: typeof Viewer) { - registerTool(contextType, DIMENSION_TOOL_ID, (viewer, obj) => - makeDimensionTool( - { - position: viewer.position, - velocity: viewer.velocity, - coordinateSpaceCombiner: - viewer.layerSpecification.coordinateSpaceCombiner, - toolBinder: viewer.toolBinder, - }, - obj, - ), + registerTool( + contextType, + DIMENSION_TOOL_ID, + (viewer, obj) => + makeDimensionTool( + { + position: viewer.position, + velocity: viewer.velocity, + coordinateSpaceCombiner: + viewer.layerSpecification.coordinateSpaceCombiner, + toolBinder: viewer.toolBinder, + }, + obj, + ), + (viewer, onChange) => listDimensionTools(viewer.coordinateSpace, onChange), ); } export function registerDimensionToolForUserLayer( contextType: typeof UserLayer, ) { - registerTool(contextType, DIMENSION_TOOL_ID, (layer, obj) => - makeDimensionTool( - { - position: layer.localPosition, - velocity: layer.localVelocity, - coordinateSpaceCombiner: layer.localCoordinateSpaceCombiner, - toolBinder: layer.toolBinder, - }, - obj, - ), + registerTool( + contextType, + DIMENSION_TOOL_ID, + (layer, obj) => + makeDimensionTool( + { + position: layer.localPosition, + velocity: layer.localVelocity, + coordinateSpaceCombiner: layer.localCoordinateSpaceCombiner, + toolBinder: layer.toolBinder, + }, + obj, + ), + (layer, onChange) => + listDimensionTools(layer.localCoordinateSpace, onChange), ); } diff --git a/src/widget/progress_listener.ts b/src/widget/progress_listener.ts new file mode 100644 index 0000000000..970f8c91b5 --- /dev/null +++ b/src/widget/progress_listener.ts @@ -0,0 +1,47 @@ +/** + * @license + * Copyright 2024 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { + ProgressListener, + ProgressSpan, + ProgressSpanId, +} from "#src/util/progress_listener.js"; +import { ProgressSpanSet } from "#src/util/progress_listener.js"; + +export class ProgressListenerWidget implements ProgressListener { + element = document.createElement("ul"); + constructor() { + this.element.classList.add("neuroglancer-progress"); + } + private spanElements = new Map(); + private spans = new ProgressSpanSet(); + + addSpan(span: ProgressSpan) { + if (this.spans.add(span) !== 1) return; + const spanElement = document.createElement("li"); + spanElement.textContent = span.message; + this.spanElements.set(span.id, spanElement); + this.element.appendChild(spanElement); + } + + removeSpan(spanId: ProgressSpanId) { + if (this.spans.deleteKey(spanId) !== 0) return; + const { spanElements } = this; + const spanElement = spanElements.get(spanId)!; + spanElements.delete(spanId); + this.element.removeChild(spanElement); + } +} diff --git a/src/widget/scale_bar.ts b/src/widget/scale_bar.ts index 4d6c8198e7..099014bf7c 100644 --- a/src/widget/scale_bar.ts +++ b/src/widget/scale_bar.ts @@ -273,13 +273,15 @@ export class ScaleBarTexture extends RefCounted { } export class MultipleScaleBarTextures extends RefCounted { - private scaleBarCopyHelper = this.registerDisposer( - OffscreenCopyHelper.get(this.gl), - ); + private scaleBarCopyHelper: OffscreenCopyHelper; private scaleBars: ScaleBarTexture[] = []; constructor(public gl: GL) { super(); + this.scaleBarCopyHelper = this.registerDisposer( + OffscreenCopyHelper.get(this.gl), + ); + for (let i = 0; i < 3; ++i) { this.scaleBars.push(this.registerDisposer(new ScaleBarTexture(gl))); } diff --git a/src/widget/shader_code_widget.ts b/src/widget/shader_code_widget.ts index c86fae81cf..df08d64f1a 100644 --- a/src/widget/shader_code_widget.ts +++ b/src/widget/shader_code_widget.ts @@ -20,8 +20,8 @@ import "codemirror/lib/codemirror.css"; import "codemirror/addon/lint/lint.css"; import CodeMirror from "codemirror"; -import glslCodeMirror from "glsl-editor/glsl.js"; import { debounce } from "lodash-es"; +import glslCodeMirror from "#src/third_party/codemirror-glsl.js"; import type { WatchableValue } from "#src/trackable_value.js"; import { RefCounted } from "#src/util/disposable.js"; import { removeFromParent } from "#src/util/dom.js"; diff --git a/src/widget/shader_controls.ts b/src/widget/shader_controls.ts index f9a3921430..c3cfd523f0 100644 --- a/src/widget/shader_controls.ts +++ b/src/widget/shader_controls.ts @@ -17,7 +17,6 @@ import { debounce } from "lodash-es"; import type { DisplayContext } from "#src/display_context.js"; import type { UserLayer, UserLayerConstructor } from "#src/layer/index.js"; -import type { ToolActivation } from "#src/ui/tool.js"; import { registerTool } from "#src/ui/tool.js"; import { RefCounted } from "#src/util/disposable.js"; import { removeChildren } from "#src/util/dom.js"; @@ -246,26 +245,27 @@ class ShaderControlTool extends LayerControlTool { control, ), ); + const debounceCheckValidity = this.registerCancellable( + debounce(() => { + if ( + layerShaderControls.shaderControlState.state.get(control) === + undefined + ) { + this.unbind(); + } + }), + ); this.registerDisposer( layerShaderControls.shaderControlState.controls.changed.add( - this.registerCancellable( - debounce(() => { - if ( - layerShaderControls.shaderControlState.state.get(control) === - undefined - ) { - this.unbind(); - } - }), - ), + debounceCheckValidity, ), ); } - activate(activation: ToolActivation) { + + isLoading() { const { shaderControlState } = this.layerShaderControls; const controlState = shaderControlState.state.get(this.control); - if (controlState === undefined) return; - super.activate(activation); + return controlState === undefined; } } @@ -274,12 +274,28 @@ export function registerLayerShaderControlsTool( getter: (layer: LayerType) => LayerShaderControls, toolId: string = SHADER_CONTROL_TOOL_ID, ) { - registerTool(layerType, toolId, (layer, options) => { - const control = verifyObjectProperty( - options, - CONTROL_JSON_KEY, - verifyString, - ); - return new ShaderControlTool(layer, getter(layer), toolId, control); - }); + registerTool( + layerType, + toolId, + (layer, options) => { + const control = verifyObjectProperty( + options, + CONTROL_JSON_KEY, + verifyString, + ); + return new ShaderControlTool(layer, getter(layer), toolId, control); + }, + (layer, onChange) => { + const layerShaderControls = getter(layer); + const { shaderControlState } = layerShaderControls; + if (onChange !== undefined) { + shaderControlState.controls.changed.addOnce(onChange); + } + const map = shaderControlState.state; + return Array.from(map.keys(), (key) => ({ + type: SHADER_CONTROL_TOOL_ID, + [CONTROL_JSON_KEY]: key, + })); + }, + ); } diff --git a/src/widget/text_input.ts b/src/widget/text_input.ts index 322bc485d2..1f3775aa91 100644 --- a/src/widget/text_input.ts +++ b/src/widget/text_input.ts @@ -17,6 +17,15 @@ import type { TrackableValueInterface } from "#src/trackable_value.js"; import { RefCounted } from "#src/util/disposable.js"; import { removeFromParent } from "#src/util/dom.js"; +import { EventActionMap } from "#src/util/event_action_map.js"; +import { + KeyboardEventBinder, + registerActionListener, +} from "#src/util/keyboard_bindings.js"; + +const inputEventMap = EventActionMap.fromObject({ + escape: { action: "cancel" }, +}); export class TextInputWidget extends RefCounted { element = document.createElement("input"); @@ -25,7 +34,20 @@ export class TextInputWidget extends RefCounted { this.registerDisposer(model.changed.add(() => this.updateView())); const { element } = this; element.type = "text"; + element.spellcheck = false; + element.autocomplete = "off"; + const keyboardHandler = this.registerDisposer( + new KeyboardEventBinder(element, inputEventMap), + ); + keyboardHandler.allShortcutsAreGlobal = true; + registerActionListener(element, "cancel", (event) => { + this.updateView(); + element.blur(); + event.stopPropagation(); + event.preventDefault(); + }); this.registerEventListener(element, "change", () => this.updateModel()); + this.registerEventListener(element, "blur", () => this.updateModel()); this.updateView(); } diff --git a/src/widget/transfer_function.ts b/src/widget/transfer_function.ts index cfb53e3bd9..507fab64d6 100644 --- a/src/widget/transfer_function.ts +++ b/src/widget/transfer_function.ts @@ -51,8 +51,7 @@ import { startRelativeMouseDrag } from "#src/util/mouse_drag.js"; import { Uint64 } from "#src/util/uint64.js"; import { getWheelZoomAmount } from "#src/util/wheel_zoom.js"; import type { WatchableVisibilityPriority } from "#src/visibility_priority/frontend.js"; -import type { Buffer } from "#src/webgl/buffer.js"; -import { getMemoizedBuffer } from "#src/webgl/buffer.js"; +import { GLBuffer, getMemoizedBuffer } from "#src/webgl/buffer.js"; import type { GL } from "#src/webgl/context.js"; import type { HistogramSpecifications } from "#src/webgl/empirical_cdf.js"; import { @@ -594,7 +593,7 @@ abstract class BaseLookupTexture extends RefCounted { */ class DirectLookupTableTexture extends BaseLookupTexture { texture: WebGLTexture | null = null; - protected priorOptions: LookupTableTextureOptions | undefined = undefined; + declare protected priorOptions: LookupTableTextureOptions | undefined; constructor(public gl: GL | null) { super(gl); @@ -623,7 +622,7 @@ class DirectLookupTableTexture extends BaseLookupTexture { } export class ControlPointTexture extends BaseLookupTexture { - protected priorOptions: ControlPointTextureOptions | undefined; + declare protected priorOptions: ControlPointTextureOptions | undefined; constructor(public gl: GL | null) { super(gl); } @@ -666,80 +665,88 @@ export class ControlPointTexture extends BaseLookupTexture { } } +function getDataValuesArray() { + const array = new Uint8Array(NUM_CDF_LINES * VERTICES_PER_LINE); + for (let i = 0; i < NUM_CDF_LINES; ++i) { + for (let j = 0; j < VERTICES_PER_LINE; ++j) { + array[i * VERTICES_PER_LINE + j] = i; + } + } + return array; +} + +function getTextureVertexBufferArray() { + return createGriddedRectangleArray(TRANSFER_FUNCTION_PANEL_SIZE); +} + /** * Display the UI canvas for the transfer function widget and * handle shader updates for elements of the canvas */ class TransferFunctionPanel extends IndirectRenderedPanel { texture: DirectLookupTableTexture; - private textureVertexBuffer: Buffer; - private textureVertexBufferArray: Float32Array; - private controlPointsVertexBuffer: Buffer; + private textureVertexBuffer: GLBuffer; + private controlPointsVertexBuffer: GLBuffer; private controlPointsPositionArray = new Float32Array(); - private controlPointsColorBuffer: Buffer; + private controlPointsColorBuffer: GLBuffer; private controlPointsColorArray = new Float32Array(); - private linePositionBuffer: Buffer; + private linePositionBuffer: GLBuffer; private linePositionArray = new Float32Array(); get drawOrder() { return 1; } - transferFunction = this.registerDisposer( - new TransferFunction( - this.parent.dataType, - this.parent.trackable, - TRANSFER_FUNCTION_PANEL_SIZE, - ), - ); - controller = this.registerDisposer( - new TransferFunctionController( - this.element, - this.parent.dataType, - this.transferFunction, - () => this.parent.trackable.value, - (value: TransferFunctionParameters) => { - this.parent.trackable.value = value; - }, - ), - ); - private dataValuesBuffer = this.registerDisposer( - getMemoizedBuffer(this.gl, WebGL2RenderingContext.ARRAY_BUFFER, () => { - const array = new Uint8Array(NUM_CDF_LINES * VERTICES_PER_LINE); - for (let i = 0; i < NUM_CDF_LINES; ++i) { - for (let j = 0; j < VERTICES_PER_LINE; ++j) { - array[i * VERTICES_PER_LINE + j] = i; - } - } - return array; - }), - ).value; + transferFunction: TransferFunction; + controller: TransferFunctionController; + private dataValuesBuffer; constructor(public parent: TransferFunctionWidget) { super(parent.display, document.createElement("div"), parent.visibility); const { element, gl } = this; - element.classList.add("neuroglancer-transfer-function-panel"); - this.textureVertexBufferArray = createGriddedRectangleArray( - TRANSFER_FUNCTION_PANEL_SIZE, + + this.transferFunction = this.registerDisposer( + new TransferFunction( + parent.dataType, + parent.trackable, + TRANSFER_FUNCTION_PANEL_SIZE, + ), ); + this.controller = this.registerDisposer( + new TransferFunctionController( + element, + parent.dataType, + this.transferFunction, + () => parent.trackable.value, + (value: TransferFunctionParameters) => { + parent.trackable.value = value; + }, + ), + ); + this.dataValuesBuffer = this.registerDisposer( + getMemoizedBuffer( + gl, + WebGL2RenderingContext.ARRAY_BUFFER, + getDataValuesArray, + ), + ).value; + + element.classList.add("neuroglancer-transfer-function-panel"); this.texture = this.registerDisposer(new DirectLookupTableTexture(gl)); - function createBuffer(dataArray: Float32Array) { - return getMemoizedBuffer( + this.textureVertexBuffer = this.registerDisposer( + getMemoizedBuffer( gl, WebGL2RenderingContext.ARRAY_BUFFER, - () => dataArray, - ).value; - } - this.textureVertexBuffer = this.registerDisposer( - createBuffer(this.textureVertexBufferArray), - ); + getTextureVertexBufferArray, + ), + ).value; this.controlPointsVertexBuffer = this.registerDisposer( - createBuffer(this.controlPointsPositionArray), + new GLBuffer(gl, WebGL2RenderingContext.ARRAY_BUFFER), ); this.controlPointsColorBuffer = this.registerDisposer( - createBuffer(this.controlPointsColorArray), + new GLBuffer(gl, WebGL2RenderingContext.ARRAY_BUFFER), ); this.linePositionBuffer = this.registerDisposer( - createBuffer(this.linePositionArray), + new GLBuffer(gl, WebGL2RenderingContext.ARRAY_BUFFER), ); } diff --git a/src/worker_rpc.ts b/src/worker_rpc.ts index 3ea514efda..d80804a38b 100644 --- a/src/worker_rpc.ts +++ b/src/worker_rpc.ts @@ -14,14 +14,14 @@ * limitations under the License. */ -import type { CancellationToken } from "#src/util/cancellation.js"; -import { - CANCELED, - CancellationTokenSource, - makeCancelablePromise, - uncancelableToken, -} from "#src/util/cancellation.js"; +import { promiseWithResolversAndAbortCallback } from "#src/util/abort.js"; import { RefCounted } from "#src/util/disposable.js"; +import type { + ProgressListener, + ProgressOptions, + ProgressSpanId, +} from "#src/util/progress_listener.js"; +import { ProgressSpan } from "#src/util/progress_listener.js"; export type RPCHandler = (this: RPC, x: any) => void; @@ -35,6 +35,8 @@ const DEBUG_MESSAGES = false; const PROMISE_RESPONSE_ID = "rpc.promise.response"; const PROMISE_CANCEL_ID = "rpc.promise.cancel"; +const PROMISE_PROGRESS_ADD_SPAN_ID = "rpc.promise.addProgressSpan"; +const PROMISE_PROGRESS_REMOVE_SPAN_ID = "rpc.promise.removeProgressSpan"; const READY_ID = "rpc.ready"; const handlers = new Map(); @@ -45,12 +47,27 @@ export function registerRPC(key: string, handler: RPCHandler) { export type RPCPromise = Promise<{ value: T; transfers?: any[] }>; -export class RPCError extends Error { +class ProxyProgressListener implements ProgressListener { constructor( - public name: string, - public message: string, - ) { - super(message); + private rpc: RPC, + private id: number, + ) {} + + addSpan(span: ProgressSpan) { + this.rpc.invoke(PROMISE_PROGRESS_ADD_SPAN_ID, { + id: this.id, + span: { + id: span.id, + message: span.message, + startTime: span.startTime, + }, + }); + } + removeSpan(spanId: ProgressSpanId) { + this.rpc.invoke(PROMISE_PROGRESS_REMOVE_SPAN_ID, { + id: this.id, + spanId, + }); } } @@ -59,14 +76,21 @@ export function registerPromiseRPC( handler: ( this: RPC, x: any, - cancellationToken: CancellationToken, + progressOptions: Partial, ) => RPCPromise, ) { registerRPC(key, function (this: RPC, x: any) { const id = x.id; - const cancellationToken = new CancellationTokenSource(); - const promise = handler.call(this, x, cancellationToken) as RPCPromise; - this.set(id, { promise, cancellationToken }); + const abortController = new AbortController(); + let progressListener: ProgressListener | undefined; + if (x.progressListener === true) { + progressListener = new ProxyProgressListener(this, id); + } + const promise = handler.call(this, x, { + signal: abortController.signal, + progressListener, + }) as RPCPromise; + this.set(id, { promise, abortController }); promise.then( ({ value, transfers }) => { this.delete(id); @@ -76,8 +100,7 @@ export function registerPromiseRPC( this.delete(id); this.invoke(PROMISE_RESPONSE_ID, { id: id, - error: error.message, - errorName: error.name, + error: error, }); }, ); @@ -88,8 +111,8 @@ registerRPC(PROMISE_CANCEL_ID, function (this: RPC, x: any) { const id = x.id; const request = this.get(id); if (request !== undefined) { - const { cancellationToken } = request; - cancellationToken.cancel(); + const { abortController } = request; + abortController.abort(); } }); @@ -100,15 +123,22 @@ registerRPC(PROMISE_RESPONSE_ID, function (this: RPC, x: any) { if (Object.prototype.hasOwnProperty.call(x, "value")) { resolve(x.value); } else { - const errorName = x.errorName; - if (errorName === CANCELED.name) { - reject(CANCELED); - } else { - reject(new RPCError(x.errorName, x.error)); - } + reject(x.error); } }); +registerRPC(PROMISE_PROGRESS_ADD_SPAN_ID, function (this: RPC, x: any) { + const id = x.id; + const { progressListener } = this.get(id); + new ProgressSpan(progressListener, x.span); +}); + +registerRPC(PROMISE_PROGRESS_REMOVE_SPAN_ID, function (this: RPC, x: any) { + const id = x.id; + const { progressListener } = this.get(id); + progressListener.removeSpan(x.spanId); +}); + registerRPC(READY_ID, function (this: RPC, x: any) { x; this.onPeerReady(); @@ -137,6 +167,10 @@ export class RPC { if (DEBUG_MESSAGES) { console.log("Received message", data); } + const handler = handlers.get(data.functionName); + if (handler === undefined) { + throw new Error(`Missing RPC function: ${data.functionName}`); + } handlers.get(data.functionName)!.call(this, data); }; } @@ -204,21 +238,36 @@ export class RPC { promiseInvoke( name: string, x: any, - cancellationToken = uncancelableToken, - transfers?: any[], + options?: { + signal?: AbortSignal; + progressListener?: ProgressListener; + transfers?: any[]; + }, ): Promise { - return makeCancelablePromise( - cancellationToken, - (resolve, reject, token) => { - const id = (x.id = this.newId()); - this.set(id, { resolve, reject }); - this.invoke(name, x, transfers); - token.add(() => { - this.invoke(PROMISE_CANCEL_ID, { id: id }); - }); - }, - ); + let signal: AbortSignal | undefined; + let progressListener: ProgressListener | undefined; + let transfers: any[] | undefined; + if (options !== undefined) { + ({ signal, progressListener, transfers } = options); + } + if (signal?.aborted) { + return Promise.reject(signal.reason); + } + if (progressListener !== undefined) { + x.progressListener = true; + } + const id = (x.id = this.newId()); + this.invoke(name, x, transfers); + const { promise, resolve, reject } = + signal === undefined + ? Promise.withResolvers() + : promiseWithResolversAndAbortCallback(signal, () => { + this.invoke(PROMISE_CANCEL_ID, { id: id }); + }); + this.set(id, { resolve, reject, progressListener }); + return promise; } + newId() { return IS_WORKER ? this.nextId-- : this.nextId++; } @@ -303,7 +352,7 @@ export class SharedObject extends RefCounted { * Should be set to a constant specifying the SharedObject type identifier on the prototype of * final derived owner classes. It is not used on counterpart (non-owner) classes. */ - RPC_TYPE_ID: string; + declare RPC_TYPE_ID: string; } export function initializeSharedObjectCounterpart( diff --git a/templates/sliceview/compressed_segmentation/decode.template.ts b/templates/sliceview/compressed_segmentation/decode.template.ts index a54d9be097..5cf984a321 100644 --- a/templates/sliceview/compressed_segmentation/decode.template.ts +++ b/templates/sliceview/compressed_segmentation/decode.template.ts @@ -19,10 +19,10 @@ * Support for decompressing uint64 segment label chunks. */ -import {decodeValueOffset} from 'neuroglancer/sliceview/compressed_segmentation/decode_common'; +import {decodeValueOffset} from '#src/sliceview/compressed_segmentation/decode_common.js'; /*% if dataType == 'uint64' %*/ -import {Uint64} from 'neuroglancer/util/uint64'; +import {Uint64} from '#src/util/uint64.js'; /*% endif %*/ /** diff --git a/templates/sliceview/compressed_segmentation/encode.template.ts b/templates/sliceview/compressed_segmentation/encode.template.ts index 126dc2a39c..177991d62f 100644 --- a/templates/sliceview/compressed_segmentation/encode.template.ts +++ b/templates/sliceview/compressed_segmentation/encode.template.ts @@ -19,11 +19,11 @@ * Support for compressing uint32/uint64 segment label chunks. */ -import {encodeChannel as encodeChannelCommon, encodeChannels as encodeChannelsCommon, writeBlock} from 'neuroglancer/sliceview/compressed_segmentation/encode_common'; -import {getFortranOrderStrides} from 'neuroglancer/util/array'; -import {Uint32ArrayBuilder} from 'neuroglancer/util/uint32array_builder'; +import {encodeChannel as encodeChannelCommon, encodeChannels as encodeChannelsCommon, writeBlock} from '#src/sliceview/compressed_segmentation/encode_common.js'; +import {getFortranOrderStrides} from '#src/util/array.js'; +import {Uint32ArrayBuilder} from '#src/util/uint32array_builder.js'; -export {newCache} from 'neuroglancer/sliceview/compressed_segmentation/encode_common'; +export {newCache} from '#src/sliceview/compressed_segmentation/encode_common.js'; let tempEncodingBuffer: Uint32Array; let tempValuesBuffer1: Uint32Array; @@ -39,7 +39,8 @@ export function encodeBlock( cache: Map, output: Uint32ArrayBuilder): [number, number] { const ax = actualSize[0], ay = actualSize[1], az = actualSize[2]; const bx = blockSize[0], by = blockSize[1], bz = blockSize[2]; - let sx = inputStrides[0], sy = inputStrides[1], sz = inputStrides[2]; + const sx = inputStrides[0]; + let sy = inputStrides[1], sz = inputStrides[2]; sz -= sy * ay; sy -= sx * ax; if (ax * ay * az === 0) { diff --git a/templates/sliceview/compressed_segmentation/encode_common.template.ts b/templates/sliceview/compressed_segmentation/encode_common.template.ts index 71ae905d23..263878fd70 100644 --- a/templates/sliceview/compressed_segmentation/encode_common.template.ts +++ b/templates/sliceview/compressed_segmentation/encode_common.template.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import {Uint32ArrayBuilder} from 'neuroglancer/util/uint32array_builder'; +import {Uint32ArrayBuilder} from '#src/util/uint32array_builder.js'; export const BLOCK_HEADER_SIZE = 2; diff --git a/templates/util/pairing_heap.template.ts b/templates/util/pairing_heap.template.ts index 5f1f50c9eb..ab46374a10 100644 --- a/templates/util/pairing_heap.template.ts +++ b/templates/util/pairing_heap.template.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import {PairingHeapOperations} from 'neuroglancer/util/pairing_heap'; +import { PairingHeapOperations } from "#src/util/pairing_heap.js"; interface Node { CHILD_PROPERTY: T|null; diff --git a/templates/util/typedarray_builder.template.ts b/templates/util/typedarray_builder.template.ts index b448b27670..2f438c1fba 100644 --- a/templates/util/typedarray_builder.template.ts +++ b/templates/util/typedarray_builder.template.ts @@ -16,7 +16,7 @@ export class $TYPE$Builder { length = 0; - data: $TYPE$; + data: $TYPE$; constructor(initialCapacity: number = 16) { this.data = new $TYPE$(initialCapacity); @@ -34,7 +34,7 @@ export class $TYPE$Builder { get view() { let {data} = this; - return new $TYPE$(data.buffer, data.byteOffset, this.length); + return new $TYPE$(data.buffer, data.byteOffset, this.length); } shrinkToFit() { diff --git a/testdata/64x64x64-raw-uint64-segmentation.dat b/testdata/codec/compressed_segmentation/64x64x64-raw-uint64-segmentation.dat similarity index 100% rename from testdata/64x64x64-raw-uint64-segmentation.dat rename to testdata/codec/compressed_segmentation/64x64x64-raw-uint64-segmentation.dat diff --git a/testdata/README.md b/testdata/codec/compressed_segmentation/README.md similarity index 100% rename from testdata/README.md rename to testdata/codec/compressed_segmentation/README.md diff --git a/testdata/generate_npy_examples.py b/testdata/codec/npy/generate_npy_examples.py similarity index 100% rename from testdata/generate_npy_examples.py rename to testdata/codec/npy/generate_npy_examples.py diff --git a/testdata/npy_test.float32-be.npy b/testdata/codec/npy/npy_test.float32-be.npy similarity index 100% rename from testdata/npy_test.float32-be.npy rename to testdata/codec/npy/npy_test.float32-be.npy diff --git a/testdata/npy_test.float32-le.npy b/testdata/codec/npy/npy_test.float32-le.npy similarity index 100% rename from testdata/npy_test.float32-le.npy rename to testdata/codec/npy/npy_test.float32-le.npy diff --git a/testdata/npy_test.float32.json b/testdata/codec/npy/npy_test.float32.json similarity index 100% rename from testdata/npy_test.float32.json rename to testdata/codec/npy/npy_test.float32.json diff --git a/testdata/npy_test.uint16-be.npy b/testdata/codec/npy/npy_test.uint16-be.npy similarity index 100% rename from testdata/npy_test.uint16-be.npy rename to testdata/codec/npy/npy_test.uint16-be.npy diff --git a/testdata/npy_test.uint16-le.npy b/testdata/codec/npy/npy_test.uint16-le.npy similarity index 100% rename from testdata/npy_test.uint16-le.npy rename to testdata/codec/npy/npy_test.uint16-le.npy diff --git a/testdata/npy_test.uint16.json b/testdata/codec/npy/npy_test.uint16.json similarity index 100% rename from testdata/npy_test.uint16.json rename to testdata/codec/npy/npy_test.uint16.json diff --git a/testdata/npy_test.uint32-be.npy b/testdata/codec/npy/npy_test.uint32-be.npy similarity index 100% rename from testdata/npy_test.uint32-be.npy rename to testdata/codec/npy/npy_test.uint32-be.npy diff --git a/testdata/npy_test.uint32-le.npy b/testdata/codec/npy/npy_test.uint32-le.npy similarity index 100% rename from testdata/npy_test.uint32-le.npy rename to testdata/codec/npy/npy_test.uint32-le.npy diff --git a/testdata/npy_test.uint32.json b/testdata/codec/npy/npy_test.uint32.json similarity index 100% rename from testdata/npy_test.uint32.json rename to testdata/codec/npy/npy_test.uint32.json diff --git a/testdata/npy_test.uint64-be.npy b/testdata/codec/npy/npy_test.uint64-be.npy similarity index 100% rename from testdata/npy_test.uint64-be.npy rename to testdata/codec/npy/npy_test.uint64-be.npy diff --git a/testdata/npy_test.uint64-le.npy b/testdata/codec/npy/npy_test.uint64-le.npy similarity index 100% rename from testdata/npy_test.uint64-le.npy rename to testdata/codec/npy/npy_test.uint64-le.npy diff --git a/testdata/npy_test.uint64.json b/testdata/codec/npy/npy_test.uint64.json similarity index 100% rename from testdata/npy_test.uint64.json rename to testdata/codec/npy/npy_test.uint64.json diff --git a/testdata/npy_test.uint8.json b/testdata/codec/npy/npy_test.uint8.json similarity index 100% rename from testdata/npy_test.uint8.json rename to testdata/codec/npy/npy_test.uint8.json diff --git a/testdata/npy_test.uint8.npy b/testdata/codec/npy/npy_test.uint8.npy similarity index 100% rename from testdata/npy_test.uint8.npy rename to testdata/codec/npy/npy_test.uint8.npy diff --git a/testdata/datasource/deepzoom/14122_mPPC_BDA_s186.dzi b/testdata/datasource/deepzoom/14122_mPPC_BDA_s186.dzi new file mode 100644 index 0000000000..10bb89f11b --- /dev/null +++ b/testdata/datasource/deepzoom/14122_mPPC_BDA_s186.dzi @@ -0,0 +1,4 @@ + + + + diff --git a/testdata/datasource/n5/generate_n5.py b/testdata/datasource/n5/generate_n5.py new file mode 100755 index 0000000000..7bd8ff79c6 --- /dev/null +++ b/testdata/datasource/n5/generate_n5.py @@ -0,0 +1,69 @@ +#!/usr/bin/env -S uv run +# /// script +# requires-python = ">=3.11" +# dependencies = [ +# "tensorstore", +# ] +# /// +import json +import os +import pathlib +import shutil + +import tensorstore as ts + + +def write_multiscale( + path, include_top_level_scales: bool, include_per_scale_downsampling_factors: bool +): + shutil.rmtree(path, ignore_errors=True) + shape = [10, 20] + scales = [] + for scale in [0, 1, 2]: + downsample_factors = [2**scale, 2**scale] + scales.append(downsample_factors) + scale_path = os.path.join(path, f"s{scale}") + scale_attributes = {} + if include_per_scale_downsampling_factors: + scale_attributes["downsamplingFactors"] = downsample_factors + ts.open( + { + "driver": "n5", + "kvstore": {"driver": "file", "path": scale_path}, + "metadata": scale_attributes, + }, + create=True, + delete_existing=True, + dtype=ts.uint16, + shape=[ + -(-shape[0] // downsample_factors[0]), + -(-shape[1] // downsample_factors[1]), + ], + ).result() + top_level_attributes = { + "axes": ["x", "y"], + "units": ["nm", "s"], + "resolution": [10, 20], + } + if include_top_level_scales: + top_level_attributes["scales"] = scales + pathlib.Path(os.path.join(path, "attributes.json")).write_text( + json.dumps(top_level_attributes) + ) + + +write_multiscale( + os.path.abspath( + os.path.join(os.path.dirname(__file__), "n5_viewer_multiscale_deprecated") + ), + include_top_level_scales=True, + include_per_scale_downsampling_factors=False, +) + +write_multiscale( + os.path.abspath( + os.path.join(os.path.dirname(__file__), "n5_viewer_multiscale_modern") + ), + include_top_level_scales=False, + include_per_scale_downsampling_factors=True, +) diff --git a/testdata/datasource/n5/n5_viewer_multiscale_deprecated/attributes.json b/testdata/datasource/n5/n5_viewer_multiscale_deprecated/attributes.json new file mode 100644 index 0000000000..7311cde9a8 --- /dev/null +++ b/testdata/datasource/n5/n5_viewer_multiscale_deprecated/attributes.json @@ -0,0 +1 @@ +{"axes": ["x", "y"], "units": ["nm", "s"], "resolution": [10, 20], "scales": [[1, 1], [2, 2], [4, 4]]} \ No newline at end of file diff --git a/testdata/datasource/n5/n5_viewer_multiscale_deprecated/s0/attributes.json b/testdata/datasource/n5/n5_viewer_multiscale_deprecated/s0/attributes.json new file mode 100644 index 0000000000..7254f6e6fa --- /dev/null +++ b/testdata/datasource/n5/n5_viewer_multiscale_deprecated/s0/attributes.json @@ -0,0 +1 @@ +{"blockSize":[10,20],"compression":{"blocksize":0,"clevel":5,"cname":"lz4","shuffle":1,"type":"blosc"},"dataType":"uint16","dimensions":[10,20]} \ No newline at end of file diff --git a/testdata/datasource/n5/n5_viewer_multiscale_deprecated/s1/attributes.json b/testdata/datasource/n5/n5_viewer_multiscale_deprecated/s1/attributes.json new file mode 100644 index 0000000000..1a935f8806 --- /dev/null +++ b/testdata/datasource/n5/n5_viewer_multiscale_deprecated/s1/attributes.json @@ -0,0 +1 @@ +{"blockSize":[5,10],"compression":{"blocksize":0,"clevel":5,"cname":"lz4","shuffle":1,"type":"blosc"},"dataType":"uint16","dimensions":[5,10]} \ No newline at end of file diff --git a/testdata/datasource/n5/n5_viewer_multiscale_deprecated/s2/attributes.json b/testdata/datasource/n5/n5_viewer_multiscale_deprecated/s2/attributes.json new file mode 100644 index 0000000000..2c2d38eab1 --- /dev/null +++ b/testdata/datasource/n5/n5_viewer_multiscale_deprecated/s2/attributes.json @@ -0,0 +1 @@ +{"blockSize":[3,5],"compression":{"blocksize":0,"clevel":5,"cname":"lz4","shuffle":1,"type":"blosc"},"dataType":"uint16","dimensions":[3,5]} \ No newline at end of file diff --git a/testdata/datasource/n5/n5_viewer_multiscale_modern/attributes.json b/testdata/datasource/n5/n5_viewer_multiscale_modern/attributes.json new file mode 100644 index 0000000000..2b49d435e7 --- /dev/null +++ b/testdata/datasource/n5/n5_viewer_multiscale_modern/attributes.json @@ -0,0 +1 @@ +{"axes": ["x", "y"], "units": ["nm", "s"], "resolution": [10, 20]} \ No newline at end of file diff --git a/testdata/datasource/n5/n5_viewer_multiscale_modern/s0/attributes.json b/testdata/datasource/n5/n5_viewer_multiscale_modern/s0/attributes.json new file mode 100644 index 0000000000..1d0eb09bc9 --- /dev/null +++ b/testdata/datasource/n5/n5_viewer_multiscale_modern/s0/attributes.json @@ -0,0 +1 @@ +{"blockSize":[10,20],"compression":{"blocksize":0,"clevel":5,"cname":"lz4","shuffle":1,"type":"blosc"},"dataType":"uint16","dimensions":[10,20],"downsamplingFactors":[1,1]} \ No newline at end of file diff --git a/testdata/datasource/n5/n5_viewer_multiscale_modern/s1/attributes.json b/testdata/datasource/n5/n5_viewer_multiscale_modern/s1/attributes.json new file mode 100644 index 0000000000..08ca0551a5 --- /dev/null +++ b/testdata/datasource/n5/n5_viewer_multiscale_modern/s1/attributes.json @@ -0,0 +1 @@ +{"blockSize":[5,10],"compression":{"blocksize":0,"clevel":5,"cname":"lz4","shuffle":1,"type":"blosc"},"dataType":"uint16","dimensions":[5,10],"downsamplingFactors":[2,2]} \ No newline at end of file diff --git a/testdata/datasource/n5/n5_viewer_multiscale_modern/s2/attributes.json b/testdata/datasource/n5/n5_viewer_multiscale_modern/s2/attributes.json new file mode 100644 index 0000000000..8f77ef7ea7 --- /dev/null +++ b/testdata/datasource/n5/n5_viewer_multiscale_modern/s2/attributes.json @@ -0,0 +1 @@ +{"blockSize":[3,5],"compression":{"blocksize":0,"clevel":5,"cname":"lz4","shuffle":1,"type":"blosc"},"dataType":"uint16","dimensions":[3,5],"downsamplingFactors":[4,4]} \ No newline at end of file diff --git a/testdata/datasource/nifti/README.md b/testdata/datasource/nifti/README.md new file mode 100644 index 0000000000..0aaf544ebd --- /dev/null +++ b/testdata/datasource/nifti/README.md @@ -0,0 +1,35 @@ +The following test files: + +- example_nifti2.nii.gz +- standard.nii.gz +- standard.nii (derived from standard.nii.gz) + +were copied from nibabel, and are subject to the following license: + +The MIT License + +Copyright (c) 2009-2019 Matthew Brett +Copyright (c) 2010-2013 Stephan Gerhard +Copyright (c) 2006-2014 Michael Hanke +Copyright (c) 2011 Christian Haselgrove +Copyright (c) 2010-2011 Jarrod Millman +Copyright (c) 2011-2019 Yaroslav Halchenko +Copyright (c) 2015-2019 Chris Markiewicz + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/testdata/datasource/nifti/example_nifti2.nii.gz b/testdata/datasource/nifti/example_nifti2.nii.gz new file mode 100644 index 0000000000..a0d9e408f4 Binary files /dev/null and b/testdata/datasource/nifti/example_nifti2.nii.gz differ diff --git a/testdata/datasource/nifti/standard.nii b/testdata/datasource/nifti/standard.nii new file mode 100644 index 0000000000..d685a25135 Binary files /dev/null and b/testdata/datasource/nifti/standard.nii differ diff --git a/testdata/datasource/nifti/standard.nii.gz b/testdata/datasource/nifti/standard.nii.gz new file mode 100644 index 0000000000..98bb31a778 Binary files /dev/null and b/testdata/datasource/nifti/standard.nii.gz differ diff --git a/testdata/datasource/precomputed/generate_precomputed.py b/testdata/datasource/precomputed/generate_precomputed.py new file mode 100755 index 0000000000..24e72e36e8 --- /dev/null +++ b/testdata/datasource/precomputed/generate_precomputed.py @@ -0,0 +1,46 @@ +#!/usr/bin/env -S uv run +# /// script +# requires-python = ">=3.11" +# dependencies = [ +# "tensorstore", +# "numpy", +# ] +# /// +import os +import shutil + +import numpy as np +import tensorstore as ts + + +def write_multiscale(path: str, num_channels: int, num_scales: int): + shutil.rmtree(path, ignore_errors=True) + shape = np.array([10, 20, 30, num_channels]) + base_resolution = np.array([3, 4, 5]) + for scale in range(num_scales): + downsample_factors = [2**scale, 2**scale, 2**scale, 1] + ts.open( + { + "driver": "neuroglancer_precomputed", + "kvstore": {"driver": "file", "path": path}, + "scale_metadata": { + "resolution": base_resolution * downsample_factors[:-1] + }, + }, + create=True, + dtype=ts.uint16, + shape=-(-shape // downsample_factors), + ).result() + + +write_multiscale( + os.path.abspath(os.path.join(os.path.dirname(__file__), "one_channel")), + num_channels=1, + num_scales=3, +) + +write_multiscale( + os.path.abspath(os.path.join(os.path.dirname(__file__), "two_channels")), + num_channels=2, + num_scales=3, +) diff --git a/testdata/datasource/precomputed/one_channel/info b/testdata/datasource/precomputed/one_channel/info new file mode 100644 index 0000000000..1408773d9f --- /dev/null +++ b/testdata/datasource/precomputed/one_channel/info @@ -0,0 +1 @@ +{"@type":"neuroglancer_multiscale_volume","data_type":"uint16","num_channels":1,"scales":[{"chunk_sizes":[[10,20,30]],"encoding":"raw","key":"3_4_5","resolution":[3.0,4.0,5.0],"size":[10,20,30],"voxel_offset":[0,0,0]},{"chunk_sizes":[[5,10,15]],"encoding":"raw","key":"6_8_10","resolution":[6.0,8.0,10.0],"size":[5,10,15],"voxel_offset":[0,0,0]},{"chunk_sizes":[[3,5,8]],"encoding":"raw","key":"12_16_20","resolution":[12.0,16.0,20.0],"size":[3,5,8],"voxel_offset":[0,0,0]}],"type":"image"} \ No newline at end of file diff --git a/testdata/datasource/precomputed/two_channels/info b/testdata/datasource/precomputed/two_channels/info new file mode 100644 index 0000000000..58769bce6f --- /dev/null +++ b/testdata/datasource/precomputed/two_channels/info @@ -0,0 +1 @@ +{"@type":"neuroglancer_multiscale_volume","data_type":"uint16","num_channels":2,"scales":[{"chunk_sizes":[[10,20,30]],"encoding":"raw","key":"3_4_5","resolution":[3.0,4.0,5.0],"size":[10,20,30],"voxel_offset":[0,0,0]},{"chunk_sizes":[[5,10,15]],"encoding":"raw","key":"6_8_10","resolution":[6.0,8.0,10.0],"size":[5,10,15],"voxel_offset":[0,0,0]},{"chunk_sizes":[[3,5,8]],"encoding":"raw","key":"12_16_20","resolution":[12.0,16.0,20.0],"size":[3,5,8],"voxel_offset":[0,0,0]}],"type":"image"} \ No newline at end of file diff --git a/testdata/datasource/zarr/ome_zarr/generate_ome_zarr.py b/testdata/datasource/zarr/ome_zarr/generate_ome_zarr.py new file mode 100755 index 0000000000..97ffac099e --- /dev/null +++ b/testdata/datasource/zarr/ome_zarr/generate_ome_zarr.py @@ -0,0 +1,57 @@ +#!/usr/bin/env -S uv run +# /// script +# requires-python = ">=3.11" +# dependencies = [ +# "ngff-zarr[tensorstore]", +# "numpy", +# ] +# /// + +import os +import shutil +import zipfile + +import ngff_zarr as nz +import numpy as np + +THIS_DIR = os.path.abspath(os.path.dirname(__file__)) + + +def write_data(path: str, version: str): + shape = [10, 10] + + data = np.arange(np.prod(shape), dtype=np.uint16).reshape(shape) + + image = nz.to_ngff_image( + data, + dims=["y", "x"], + scale={"y": 4, "x": 30}, + axes_units={"y": "nanometer", "x": "nanometer"}, + ) + + multiscales = nz.to_multiscales( + image, scale_factors=[{"x": 2, "y": 2}, {"x": 4, "y": 4}] + ) + + full_path = os.path.join(THIS_DIR, path) + shutil.rmtree(full_path, ignore_errors=True) + + nz.to_ngff_zarr( + full_path, + multiscales, + use_tensorstore=True, + version=version, + ) + + +def create_zip(directory_path: str, zip_path: str): + with zipfile.ZipFile(zip_path, "w", zipfile.ZIP_STORED) as zipf: + for root, dirs, files in os.walk(directory_path): + for filename in files: + entry_path = os.path.join(root, filename) + zipf.write(entry_path, os.path.relpath(entry_path, directory_path)) + + +write_data("simple_0.4", version="0.4") +write_data("simple_0.5", version="0.5") +create_zip(os.path.join(THIS_DIR, "simple_0.5"), "simple_0.4.zip") diff --git a/testdata/datasource/zarr/ome_zarr/simple_0.4.zip b/testdata/datasource/zarr/ome_zarr/simple_0.4.zip new file mode 100644 index 0000000000..3766297dfa Binary files /dev/null and b/testdata/datasource/zarr/ome_zarr/simple_0.4.zip differ diff --git a/testdata/datasource/zarr/ome_zarr/simple_0.4/.zattrs b/testdata/datasource/zarr/ome_zarr/simple_0.4/.zattrs new file mode 100644 index 0000000000..8881cf31db --- /dev/null +++ b/testdata/datasource/zarr/ome_zarr/simple_0.4/.zattrs @@ -0,0 +1,80 @@ +{ + "multiscales": [ + { + "axes": [ + { + "name": "y", + "type": "space", + "unit": "nanometer" + }, + { + "name": "x", + "type": "space", + "unit": "nanometer" + } + ], + "datasets": [ + { + "path": "scale0/image", + "coordinateTransformations": [ + { + "scale": [ + 4, + 30 + ], + "type": "scale" + }, + { + "translation": [ + 0.0, + 0.0 + ], + "type": "translation" + } + ] + }, + { + "path": "scale1/image", + "coordinateTransformations": [ + { + "scale": [ + 8, + 60 + ], + "type": "scale" + }, + { + "translation": [ + 2, + 15 + ], + "type": "translation" + } + ] + }, + { + "path": "scale2/image", + "coordinateTransformations": [ + { + "scale": [ + 16, + 120 + ], + "type": "scale" + }, + { + "translation": [ + 6, + 45 + ], + "type": "translation" + } + ] + } + ], + "name": "image", + "version": "0.4", + "@type": "ngff:Image" + } + ] +} \ No newline at end of file diff --git a/testdata/datasource/zarr/ome_zarr/simple_0.4/.zgroup b/testdata/datasource/zarr/ome_zarr/simple_0.4/.zgroup new file mode 100644 index 0000000000..cab13da6ee --- /dev/null +++ b/testdata/datasource/zarr/ome_zarr/simple_0.4/.zgroup @@ -0,0 +1,3 @@ +{ + "zarr_format": 2 +} \ No newline at end of file diff --git a/testdata/datasource/zarr/ome_zarr/simple_0.4/.zmetadata b/testdata/datasource/zarr/ome_zarr/simple_0.4/.zmetadata new file mode 100644 index 0000000000..18b2fe0a54 --- /dev/null +++ b/testdata/datasource/zarr/ome_zarr/simple_0.4/.zmetadata @@ -0,0 +1,202 @@ +{ + "metadata": { + ".zgroup": { + "zarr_format": 2 + }, + ".zattrs": { + "multiscales": [ + { + "axes": [ + { + "name": "y", + "type": "space", + "unit": "nanometer" + }, + { + "name": "x", + "type": "space", + "unit": "nanometer" + } + ], + "datasets": [ + { + "path": "scale0/image", + "coordinateTransformations": [ + { + "scale": [ + 4, + 30 + ], + "type": "scale" + }, + { + "translation": [ + 0.0, + 0.0 + ], + "type": "translation" + } + ] + }, + { + "path": "scale1/image", + "coordinateTransformations": [ + { + "scale": [ + 8, + 60 + ], + "type": "scale" + }, + { + "translation": [ + 2, + 15 + ], + "type": "translation" + } + ] + }, + { + "path": "scale2/image", + "coordinateTransformations": [ + { + "scale": [ + 16, + 120 + ], + "type": "scale" + }, + { + "translation": [ + 6, + 45 + ], + "type": "translation" + } + ] + } + ], + "name": "image", + "version": "0.4", + "@type": "ngff:Image" + } + ] + }, + "scale2/.zattrs": { + "_ARRAY_DIMENSIONS": [ + "y", + "x" + ] + }, + "scale2/.zgroup": { + "zarr_format": 2, + "consolidated_metadata": { + "metadata": {}, + "must_understand": false, + "kind": "inline" + } + }, + "scale2/image/.zattrs": {}, + "scale2/image/.zarray": { + "shape": [ + 2, + 2 + ], + "chunks": [ + 2, + 2 + ], + "fill_value": null, + "order": "C", + "filters": null, + "dimension_separator": "/", + "compressor": { + "id": "blosc", + "cname": "lz4", + "clevel": 5, + "shuffle": -1, + "blocksize": 0 + }, + "zarr_format": 2, + "dtype": " { + const serverFixture = httpServerFixture(constantFixture(TEST_FILES_DIR)); + const kvStoreContextFixture = sharedKvStoreContextFixture(); + test("get completions", async () => { + const serverUrl = await serverFixture.serverUrl(); + expect( + await getKvStoreCompletions(await kvStoreContextFixture(), { + url: serverUrl, + }), + ).toMatchInlineSnapshot(` + { + "completions": [ + { + "value": "baz/", + }, + { + "value": "#|", + }, + { + "value": "a|", + }, + { + "value": "b|", + }, + { + "value": "c|", + }, + { + "value": "empty|", + }, + ], + "defaultCompletion": undefined, + "offset": 23, + } + `); + }); + + test("get completions with partial name", async () => { + const serverUrl = await serverFixture.serverUrl(); + expect( + await getKvStoreCompletions(await kvStoreContextFixture(), { + url: serverUrl + "b", + }), + ).toMatchInlineSnapshot(` + { + "completions": [ + { + "value": "baz/", + }, + { + "value": "b|", + }, + ], + "defaultCompletion": undefined, + "offset": 23, + } + `); + }); + + test("get completions with subdirectory", async () => { + const serverUrl = await serverFixture.serverUrl(); + expect( + await getKvStoreCompletions(await kvStoreContextFixture(), { + url: serverUrl + "baz/", + }), + ).toMatchInlineSnapshot(` + { + "completions": [ + { + "value": "x|", + }, + ], + "defaultCompletion": undefined, + "offset": 27, + } + `); + }); +}); + +describe("datasource completion", () => { + const datasourceProviderFixture = dataSourceProviderFixture(); + + test("get empty completions", async () => { + expect(await (await datasourceProviderFixture()).completeUrl({ url: "" })) + .toMatchInlineSnapshot(` + { + "completions": [ + { + "description": "http (unauthenticated)", + "value": "http://", + }, + { + "description": "https (unauthenticated)", + "value": "https://", + }, + { + "description": "Local in-memory", + "value": "local://", + }, + ], + "offset": 0, + } + `); + }); +}); diff --git a/src/async_computation/decode_gzip.ts b/tests/datasource/deepzoom.browser_test.ts similarity index 61% rename from src/async_computation/decode_gzip.ts rename to tests/datasource/deepzoom.browser_test.ts index 68eeabd70b..924ccf3547 100644 --- a/src/async_computation/decode_gzip.ts +++ b/tests/datasource/deepzoom.browser_test.ts @@ -1,6 +1,6 @@ /** * @license - * Copyright 2019 Google Inc. + * Copyright 2024 Google Inc. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -14,10 +14,8 @@ * limitations under the License. */ -import { decodeGzip } from "#src/async_computation/decode_gzip_request.js"; -import { registerAsyncComputation } from "#src/async_computation/handler.js"; +import "#src/datasource/deepzoom/register_default"; +import "#src/sliceview/uncompressed_chunk_format.js"; +import { datasourceMetadataSnapshotTests } from "#tests/datasource/metadata_snapshot_test_util.js"; -registerAsyncComputation(decodeGzip, async (data: Uint8Array) => { - const result = (await import("pako")).inflate(data); - return { value: result, transfer: [result.buffer] }; -}); +datasourceMetadataSnapshotTests("deepzoom", ["14122_mPPC_BDA_s186.dzi"]); diff --git a/tests/datasource/metadata_snapshot_test_util.ts b/tests/datasource/metadata_snapshot_test_util.ts new file mode 100644 index 0000000000..e03580b874 --- /dev/null +++ b/tests/datasource/metadata_snapshot_test_util.ts @@ -0,0 +1,42 @@ +/** + * @license + * Copyright 2025 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import "#src/kvstore/http/register.js"; +import { describe, test } from "vitest"; +import { getDatasourceMetadata } from "#tests/datasource/test_util.js"; +import { dataSourceProviderFixture } from "#tests/fixtures/datasource_provider.js"; + +declare const TEST_DATA_SERVER: string; + +export const dataSourceProvider = dataSourceProviderFixture(); + +export function datasourceMetadataSnapshotTests( + datasourceName: string, + names: string[], +) { + describe("metadata tests", () => { + test.for(names)("metadata %s", async (name, { expect }) => { + await expect( + await getDatasourceMetadata( + dataSourceProvider, + `${TEST_DATA_SERVER}datasource/${datasourceName}/${name}`, + ), + ).toMatchFileSnapshot( + `./metadata_snapshots/${datasourceName}/${name.replaceAll("/", "_")}.snapshot`, + ); + }); + }); +} diff --git a/tests/datasource/metadata_snapshots/deepzoom/14122_mPPC_BDA_s186.dzi.snapshot b/tests/datasource/metadata_snapshots/deepzoom/14122_mPPC_BDA_s186.dzi.snapshot new file mode 100644 index 0000000000..9556efadaf --- /dev/null +++ b/tests/datasource/metadata_snapshots/deepzoom/14122_mPPC_BDA_s186.dzi.snapshot @@ -0,0 +1,1181 @@ +{ + "canonicalUrl": "http://localhost:*/datasource/deepzoom/14122_mPPC_BDA_s186.dzi|deepzoom:", + "modelTransform": { + "inputSpace": { + "bounds": { + "lowerBounds": Float64Array [ + 0, + 0, + 0, + ], + "upperBounds": Float64Array [ + 48023, + 34907, + 3, + ], + "voxelCenterAtIntegerCoordinates": [ + false, + false, + false, + ], + }, + "coordinateArrays": [ + , + , + , + ], + "names": [ + "x", + "y", + "c^", + ], + "scales": Float64Array [ + 1e-9, + 1e-9, + 1, + ], + "units": [ + "m", + "m", + "", + ], + "valid": true, + }, + }, + "subsources": [ + { + "default": true, + "id": "default", + "subsource": { + "volume": { + "dataType": "UINT8", + "rank": 3, + "sources": [ + [ + { + "chunkSource": { + "parameters": { + "encoding": 0, + "format": "jpg", + "overlap": 1, + "tilesize": 254, + "url": "http://localhost:*/datasource/deepzoom/14122_mPPC_BDA_s186_files/16/", + }, + "spec": { + "baseVoxelOffset": [ + 0, + 0, + 0, + ], + "chunkDataSize": [ + 254, + 254, + 3, + ], + "compressedSegmentationBlockSize": undefined, + "dataType": "UINT8", + "lowerVoxelBound": [ + 0, + 0, + 0, + ], + "upperVoxelBound": [ + 48023, + 34907, + 3, + ], + }, + }, + "upperClipBound": Float32Array [ + 48023, + 34907, + 3, + ], + }, + { + "chunkSource": { + "parameters": { + "encoding": 0, + "format": "jpg", + "overlap": 1, + "tilesize": 254, + "url": "http://localhost:*/datasource/deepzoom/14122_mPPC_BDA_s186_files/15/", + }, + "spec": { + "baseVoxelOffset": [ + 0, + 0, + 0, + ], + "chunkDataSize": [ + 254, + 254, + 3, + ], + "compressedSegmentationBlockSize": undefined, + "dataType": "UINT8", + "lowerVoxelBound": [ + 0, + 0, + 0, + ], + "upperVoxelBound": [ + 24012, + 17454, + 3, + ], + }, + }, + "chunkToMultiscaleTransform": [ + [ + 2, + 0, + 0, + 0, + ], + [ + 0, + 2, + 0, + 0, + ], + [ + 0, + 0, + 1, + 0, + ], + [ + 0, + 0, + 0, + 1, + ], + ], + "upperClipBound": Float32Array [ + 24011.5, + 17453.5, + 3, + ], + }, + { + "chunkSource": { + "parameters": { + "encoding": 0, + "format": "jpg", + "overlap": 1, + "tilesize": 254, + "url": "http://localhost:*/datasource/deepzoom/14122_mPPC_BDA_s186_files/14/", + }, + "spec": { + "baseVoxelOffset": [ + 0, + 0, + 0, + ], + "chunkDataSize": [ + 254, + 254, + 3, + ], + "compressedSegmentationBlockSize": undefined, + "dataType": "UINT8", + "lowerVoxelBound": [ + 0, + 0, + 0, + ], + "upperVoxelBound": [ + 12006, + 8727, + 3, + ], + }, + }, + "chunkToMultiscaleTransform": [ + [ + 4, + 0, + 0, + 0, + ], + [ + 0, + 4, + 0, + 0, + ], + [ + 0, + 0, + 1, + 0, + ], + [ + 0, + 0, + 0, + 1, + ], + ], + "upperClipBound": Float32Array [ + 12005.75, + 8726.75, + 3, + ], + }, + { + "chunkSource": { + "parameters": { + "encoding": 0, + "format": "jpg", + "overlap": 1, + "tilesize": 254, + "url": "http://localhost:*/datasource/deepzoom/14122_mPPC_BDA_s186_files/13/", + }, + "spec": { + "baseVoxelOffset": [ + 0, + 0, + 0, + ], + "chunkDataSize": [ + 254, + 254, + 3, + ], + "compressedSegmentationBlockSize": undefined, + "dataType": "UINT8", + "lowerVoxelBound": [ + 0, + 0, + 0, + ], + "upperVoxelBound": [ + 6003, + 4364, + 3, + ], + }, + }, + "chunkToMultiscaleTransform": [ + [ + 8, + 0, + 0, + 0, + ], + [ + 0, + 8, + 0, + 0, + ], + [ + 0, + 0, + 1, + 0, + ], + [ + 0, + 0, + 0, + 1, + ], + ], + "upperClipBound": Float32Array [ + 6002.875, + 4363.375, + 3, + ], + }, + { + "chunkSource": { + "parameters": { + "encoding": 0, + "format": "jpg", + "overlap": 1, + "tilesize": 254, + "url": "http://localhost:*/datasource/deepzoom/14122_mPPC_BDA_s186_files/12/", + }, + "spec": { + "baseVoxelOffset": [ + 0, + 0, + 0, + ], + "chunkDataSize": [ + 254, + 254, + 3, + ], + "compressedSegmentationBlockSize": undefined, + "dataType": "UINT8", + "lowerVoxelBound": [ + 0, + 0, + 0, + ], + "upperVoxelBound": [ + 3002, + 2182, + 3, + ], + }, + }, + "chunkToMultiscaleTransform": [ + [ + 16, + 0, + 0, + 0, + ], + [ + 0, + 16, + 0, + 0, + ], + [ + 0, + 0, + 1, + 0, + ], + [ + 0, + 0, + 0, + 1, + ], + ], + "upperClipBound": Float32Array [ + 3001.4375, + 2181.6875, + 3, + ], + }, + { + "chunkSource": { + "parameters": { + "encoding": 0, + "format": "jpg", + "overlap": 1, + "tilesize": 254, + "url": "http://localhost:*/datasource/deepzoom/14122_mPPC_BDA_s186_files/11/", + }, + "spec": { + "baseVoxelOffset": [ + 0, + 0, + 0, + ], + "chunkDataSize": [ + 254, + 254, + 3, + ], + "compressedSegmentationBlockSize": undefined, + "dataType": "UINT8", + "lowerVoxelBound": [ + 0, + 0, + 0, + ], + "upperVoxelBound": [ + 1501, + 1091, + 3, + ], + }, + }, + "chunkToMultiscaleTransform": [ + [ + 32, + 0, + 0, + 0, + ], + [ + 0, + 32, + 0, + 0, + ], + [ + 0, + 0, + 1, + 0, + ], + [ + 0, + 0, + 0, + 1, + ], + ], + "upperClipBound": Float32Array [ + 1500.71875, + 1090.84375, + 3, + ], + }, + { + "chunkSource": { + "parameters": { + "encoding": 0, + "format": "jpg", + "overlap": 1, + "tilesize": 254, + "url": "http://localhost:*/datasource/deepzoom/14122_mPPC_BDA_s186_files/10/", + }, + "spec": { + "baseVoxelOffset": [ + 0, + 0, + 0, + ], + "chunkDataSize": [ + 254, + 254, + 3, + ], + "compressedSegmentationBlockSize": undefined, + "dataType": "UINT8", + "lowerVoxelBound": [ + 0, + 0, + 0, + ], + "upperVoxelBound": [ + 751, + 546, + 3, + ], + }, + }, + "chunkToMultiscaleTransform": [ + [ + 64, + 0, + 0, + 0, + ], + [ + 0, + 64, + 0, + 0, + ], + [ + 0, + 0, + 1, + 0, + ], + [ + 0, + 0, + 0, + 1, + ], + ], + "upperClipBound": Float32Array [ + 750.359375, + 545.421875, + 3, + ], + }, + { + "chunkSource": { + "parameters": { + "encoding": 0, + "format": "jpg", + "overlap": 1, + "tilesize": 254, + "url": "http://localhost:*/datasource/deepzoom/14122_mPPC_BDA_s186_files/9/", + }, + "spec": { + "baseVoxelOffset": [ + 0, + 0, + 0, + ], + "chunkDataSize": [ + 254, + 254, + 3, + ], + "compressedSegmentationBlockSize": undefined, + "dataType": "UINT8", + "lowerVoxelBound": [ + 0, + 0, + 0, + ], + "upperVoxelBound": [ + 376, + 273, + 3, + ], + }, + }, + "chunkToMultiscaleTransform": [ + [ + 128, + 0, + 0, + 0, + ], + [ + 0, + 128, + 0, + 0, + ], + [ + 0, + 0, + 1, + 0, + ], + [ + 0, + 0, + 0, + 1, + ], + ], + "upperClipBound": Float32Array [ + 375.1796875, + 272.7109375, + 3, + ], + }, + { + "chunkSource": { + "parameters": { + "encoding": 0, + "format": "jpg", + "overlap": 1, + "tilesize": 254, + "url": "http://localhost:*/datasource/deepzoom/14122_mPPC_BDA_s186_files/8/", + }, + "spec": { + "baseVoxelOffset": [ + 0, + 0, + 0, + ], + "chunkDataSize": [ + 254, + 254, + 3, + ], + "compressedSegmentationBlockSize": undefined, + "dataType": "UINT8", + "lowerVoxelBound": [ + 0, + 0, + 0, + ], + "upperVoxelBound": [ + 188, + 137, + 3, + ], + }, + }, + "chunkToMultiscaleTransform": [ + [ + 256, + 0, + 0, + 0, + ], + [ + 0, + 256, + 0, + 0, + ], + [ + 0, + 0, + 1, + 0, + ], + [ + 0, + 0, + 0, + 1, + ], + ], + "upperClipBound": Float32Array [ + 187.58984375, + 136.35546875, + 3, + ], + }, + { + "chunkSource": { + "parameters": { + "encoding": 0, + "format": "jpg", + "overlap": 1, + "tilesize": 254, + "url": "http://localhost:*/datasource/deepzoom/14122_mPPC_BDA_s186_files/7/", + }, + "spec": { + "baseVoxelOffset": [ + 0, + 0, + 0, + ], + "chunkDataSize": [ + 254, + 254, + 3, + ], + "compressedSegmentationBlockSize": undefined, + "dataType": "UINT8", + "lowerVoxelBound": [ + 0, + 0, + 0, + ], + "upperVoxelBound": [ + 94, + 69, + 3, + ], + }, + }, + "chunkToMultiscaleTransform": [ + [ + 512, + 0, + 0, + 0, + ], + [ + 0, + 512, + 0, + 0, + ], + [ + 0, + 0, + 1, + 0, + ], + [ + 0, + 0, + 0, + 1, + ], + ], + "upperClipBound": Float32Array [ + 93.794921875, + 68.177734375, + 3, + ], + }, + { + "chunkSource": { + "parameters": { + "encoding": 0, + "format": "jpg", + "overlap": 1, + "tilesize": 254, + "url": "http://localhost:*/datasource/deepzoom/14122_mPPC_BDA_s186_files/6/", + }, + "spec": { + "baseVoxelOffset": [ + 0, + 0, + 0, + ], + "chunkDataSize": [ + 254, + 254, + 3, + ], + "compressedSegmentationBlockSize": undefined, + "dataType": "UINT8", + "lowerVoxelBound": [ + 0, + 0, + 0, + ], + "upperVoxelBound": [ + 47, + 35, + 3, + ], + }, + }, + "chunkToMultiscaleTransform": [ + [ + 1024, + 0, + 0, + 0, + ], + [ + 0, + 1024, + 0, + 0, + ], + [ + 0, + 0, + 1, + 0, + ], + [ + 0, + 0, + 0, + 1, + ], + ], + "upperClipBound": Float32Array [ + 46.8974609375, + 34.0888671875, + 3, + ], + }, + { + "chunkSource": { + "parameters": { + "encoding": 0, + "format": "jpg", + "overlap": 1, + "tilesize": 254, + "url": "http://localhost:*/datasource/deepzoom/14122_mPPC_BDA_s186_files/5/", + }, + "spec": { + "baseVoxelOffset": [ + 0, + 0, + 0, + ], + "chunkDataSize": [ + 254, + 254, + 3, + ], + "compressedSegmentationBlockSize": undefined, + "dataType": "UINT8", + "lowerVoxelBound": [ + 0, + 0, + 0, + ], + "upperVoxelBound": [ + 24, + 18, + 3, + ], + }, + }, + "chunkToMultiscaleTransform": [ + [ + 2048, + 0, + 0, + 0, + ], + [ + 0, + 2048, + 0, + 0, + ], + [ + 0, + 0, + 1, + 0, + ], + [ + 0, + 0, + 0, + 1, + ], + ], + "upperClipBound": Float32Array [ + 23.44873046875, + 17.04443359375, + 3, + ], + }, + { + "chunkSource": { + "parameters": { + "encoding": 0, + "format": "jpg", + "overlap": 1, + "tilesize": 254, + "url": "http://localhost:*/datasource/deepzoom/14122_mPPC_BDA_s186_files/4/", + }, + "spec": { + "baseVoxelOffset": [ + 0, + 0, + 0, + ], + "chunkDataSize": [ + 254, + 254, + 3, + ], + "compressedSegmentationBlockSize": undefined, + "dataType": "UINT8", + "lowerVoxelBound": [ + 0, + 0, + 0, + ], + "upperVoxelBound": [ + 12, + 9, + 3, + ], + }, + }, + "chunkToMultiscaleTransform": [ + [ + 4096, + 0, + 0, + 0, + ], + [ + 0, + 4096, + 0, + 0, + ], + [ + 0, + 0, + 1, + 0, + ], + [ + 0, + 0, + 0, + 1, + ], + ], + "upperClipBound": Float32Array [ + 11.724365234375, + 8.522216796875, + 3, + ], + }, + { + "chunkSource": { + "parameters": { + "encoding": 0, + "format": "jpg", + "overlap": 1, + "tilesize": 254, + "url": "http://localhost:*/datasource/deepzoom/14122_mPPC_BDA_s186_files/3/", + }, + "spec": { + "baseVoxelOffset": [ + 0, + 0, + 0, + ], + "chunkDataSize": [ + 254, + 254, + 3, + ], + "compressedSegmentationBlockSize": undefined, + "dataType": "UINT8", + "lowerVoxelBound": [ + 0, + 0, + 0, + ], + "upperVoxelBound": [ + 6, + 5, + 3, + ], + }, + }, + "chunkToMultiscaleTransform": [ + [ + 8192, + 0, + 0, + 0, + ], + [ + 0, + 8192, + 0, + 0, + ], + [ + 0, + 0, + 1, + 0, + ], + [ + 0, + 0, + 0, + 1, + ], + ], + "upperClipBound": Float32Array [ + 5.8621826171875, + 4.2611083984375, + 3, + ], + }, + { + "chunkSource": { + "parameters": { + "encoding": 0, + "format": "jpg", + "overlap": 1, + "tilesize": 254, + "url": "http://localhost:*/datasource/deepzoom/14122_mPPC_BDA_s186_files/2/", + }, + "spec": { + "baseVoxelOffset": [ + 0, + 0, + 0, + ], + "chunkDataSize": [ + 254, + 254, + 3, + ], + "compressedSegmentationBlockSize": undefined, + "dataType": "UINT8", + "lowerVoxelBound": [ + 0, + 0, + 0, + ], + "upperVoxelBound": [ + 3, + 3, + 3, + ], + }, + }, + "chunkToMultiscaleTransform": [ + [ + 16384, + 0, + 0, + 0, + ], + [ + 0, + 16384, + 0, + 0, + ], + [ + 0, + 0, + 1, + 0, + ], + [ + 0, + 0, + 0, + 1, + ], + ], + "upperClipBound": Float32Array [ + 2.93109130859375, + 2.13055419921875, + 3, + ], + }, + { + "chunkSource": { + "parameters": { + "encoding": 0, + "format": "jpg", + "overlap": 1, + "tilesize": 254, + "url": "http://localhost:*/datasource/deepzoom/14122_mPPC_BDA_s186_files/1/", + }, + "spec": { + "baseVoxelOffset": [ + 0, + 0, + 0, + ], + "chunkDataSize": [ + 254, + 254, + 3, + ], + "compressedSegmentationBlockSize": undefined, + "dataType": "UINT8", + "lowerVoxelBound": [ + 0, + 0, + 0, + ], + "upperVoxelBound": [ + 2, + 2, + 3, + ], + }, + }, + "chunkToMultiscaleTransform": [ + [ + 32768, + 0, + 0, + 0, + ], + [ + 0, + 32768, + 0, + 0, + ], + [ + 0, + 0, + 1, + 0, + ], + [ + 0, + 0, + 0, + 1, + ], + ], + "upperClipBound": Float32Array [ + 1.465545654296875, + 1.065277099609375, + 3, + ], + }, + { + "chunkSource": { + "parameters": { + "encoding": 0, + "format": "jpg", + "overlap": 1, + "tilesize": 254, + "url": "http://localhost:*/datasource/deepzoom/14122_mPPC_BDA_s186_files/0/", + }, + "spec": { + "baseVoxelOffset": [ + 0, + 0, + 0, + ], + "chunkDataSize": [ + 254, + 254, + 3, + ], + "compressedSegmentationBlockSize": undefined, + "dataType": "UINT8", + "lowerVoxelBound": [ + 0, + 0, + 0, + ], + "upperVoxelBound": [ + 1, + 1, + 3, + ], + }, + }, + "chunkToMultiscaleTransform": [ + [ + 65536, + 0, + 0, + 0, + ], + [ + 0, + 65536, + 0, + 0, + ], + [ + 0, + 0, + 1, + 0, + ], + [ + 0, + 0, + 0, + 1, + ], + ], + "upperClipBound": Float32Array [ + 0.7327728271484375, + 0.5326385498046875, + 3, + ], + }, + ], + ], + "volumeType": "IMAGE", + }, + }, + }, + { + "default": true, + "id": "bounds", + "subsource": { + "staticAnnotations": [ + { + "description": "Data Bounds", + "id": "data-bounds", + "pointA": [ + 0, + 0, + 0, + ], + "pointB": [ + 48023, + 34907, + 3, + ], + "type": "axis_aligned_bounding_box", + }, + ], + }, + }, + ], +} \ No newline at end of file diff --git a/tests/datasource/metadata_snapshots/n5/n5_viewer_multiscale_deprecated.snapshot b/tests/datasource/metadata_snapshots/n5/n5_viewer_multiscale_deprecated.snapshot new file mode 100644 index 0000000000..f391dcfe50 --- /dev/null +++ b/tests/datasource/metadata_snapshots/n5/n5_viewer_multiscale_deprecated.snapshot @@ -0,0 +1,194 @@ +{ + "canonicalUrl": "http://localhost:*/datasource/n5/n5_viewer_multiscale_deprecated/|n5:", + "modelTransform": { + "inputSpace": { + "bounds": { + "lowerBounds": Float64Array [ + 0, + 0, + ], + "upperBounds": Float64Array [ + 10, + 20, + ], + "voxelCenterAtIntegerCoordinates": [ + false, + false, + ], + }, + "coordinateArrays": [ + , + , + ], + "names": [ + "x", + "y", + ], + "scales": Float64Array [ + 1e-8, + 20, + ], + "units": [ + "m", + "s", + ], + "valid": true, + }, + }, + "subsources": [ + { + "default": true, + "id": "default", + "subsource": { + "volume": { + "dataType": "UINT16", + "rank": 2, + "sources": [ + [ + { + "chunkSource": { + "parameters": { + "encoding": 3, + "url": "http://localhost:*/datasource/n5/n5_viewer_multiscale_deprecated/s0/", + }, + "spec": { + "baseVoxelOffset": [ + 0, + 0, + ], + "chunkDataSize": [ + 10, + 20, + ], + "compressedSegmentationBlockSize": undefined, + "dataType": "UINT16", + "lowerVoxelBound": [ + 0, + 0, + ], + "upperVoxelBound": [ + 10, + 20, + ], + }, + }, + }, + { + "chunkSource": { + "parameters": { + "encoding": 3, + "url": "http://localhost:*/datasource/n5/n5_viewer_multiscale_deprecated/s1/", + }, + "spec": { + "baseVoxelOffset": [ + 0, + 0, + ], + "chunkDataSize": [ + 5, + 10, + ], + "compressedSegmentationBlockSize": undefined, + "dataType": "UINT16", + "lowerVoxelBound": [ + 0, + 0, + ], + "upperVoxelBound": [ + 5, + 10, + ], + }, + }, + "chunkToMultiscaleTransform": [ + [ + 2, + 0, + 0, + ], + [ + 0, + 2, + 0, + ], + [ + 0, + 0, + 1, + ], + ], + }, + { + "chunkSource": { + "parameters": { + "encoding": 3, + "url": "http://localhost:*/datasource/n5/n5_viewer_multiscale_deprecated/s2/", + }, + "spec": { + "baseVoxelOffset": [ + 0, + 0, + ], + "chunkDataSize": [ + 3, + 5, + ], + "compressedSegmentationBlockSize": undefined, + "dataType": "UINT16", + "lowerVoxelBound": [ + 0, + 0, + ], + "upperVoxelBound": [ + 3, + 5, + ], + }, + }, + "chunkToMultiscaleTransform": [ + [ + 4, + 0, + 0, + ], + [ + 0, + 4, + 0, + ], + [ + 0, + 0, + 1, + ], + ], + }, + ], + ], + "volumeType": "IMAGE", + }, + }, + }, + { + "default": true, + "id": "bounds", + "subsource": { + "staticAnnotations": [ + { + "description": "Data Bounds", + "id": "data-bounds", + "pointA": [ + 0, + 0, + ], + "pointB": [ + 10, + 20, + ], + "type": "axis_aligned_bounding_box", + }, + ], + }, + }, + ], +} \ No newline at end of file diff --git a/tests/datasource/metadata_snapshots/n5/n5_viewer_multiscale_modern.snapshot b/tests/datasource/metadata_snapshots/n5/n5_viewer_multiscale_modern.snapshot new file mode 100644 index 0000000000..aca3867952 --- /dev/null +++ b/tests/datasource/metadata_snapshots/n5/n5_viewer_multiscale_modern.snapshot @@ -0,0 +1,194 @@ +{ + "canonicalUrl": "http://localhost:*/datasource/n5/n5_viewer_multiscale_modern/|n5:", + "modelTransform": { + "inputSpace": { + "bounds": { + "lowerBounds": Float64Array [ + 0, + 0, + ], + "upperBounds": Float64Array [ + 10, + 20, + ], + "voxelCenterAtIntegerCoordinates": [ + false, + false, + ], + }, + "coordinateArrays": [ + , + , + ], + "names": [ + "x", + "y", + ], + "scales": Float64Array [ + 1e-8, + 20, + ], + "units": [ + "m", + "s", + ], + "valid": true, + }, + }, + "subsources": [ + { + "default": true, + "id": "default", + "subsource": { + "volume": { + "dataType": "UINT16", + "rank": 2, + "sources": [ + [ + { + "chunkSource": { + "parameters": { + "encoding": 3, + "url": "http://localhost:*/datasource/n5/n5_viewer_multiscale_modern/s0/", + }, + "spec": { + "baseVoxelOffset": [ + 0, + 0, + ], + "chunkDataSize": [ + 10, + 20, + ], + "compressedSegmentationBlockSize": undefined, + "dataType": "UINT16", + "lowerVoxelBound": [ + 0, + 0, + ], + "upperVoxelBound": [ + 10, + 20, + ], + }, + }, + }, + { + "chunkSource": { + "parameters": { + "encoding": 3, + "url": "http://localhost:*/datasource/n5/n5_viewer_multiscale_modern/s1/", + }, + "spec": { + "baseVoxelOffset": [ + 0, + 0, + ], + "chunkDataSize": [ + 5, + 10, + ], + "compressedSegmentationBlockSize": undefined, + "dataType": "UINT16", + "lowerVoxelBound": [ + 0, + 0, + ], + "upperVoxelBound": [ + 5, + 10, + ], + }, + }, + "chunkToMultiscaleTransform": [ + [ + 2, + 0, + 0, + ], + [ + 0, + 2, + 0, + ], + [ + 0, + 0, + 1, + ], + ], + }, + { + "chunkSource": { + "parameters": { + "encoding": 3, + "url": "http://localhost:*/datasource/n5/n5_viewer_multiscale_modern/s2/", + }, + "spec": { + "baseVoxelOffset": [ + 0, + 0, + ], + "chunkDataSize": [ + 3, + 5, + ], + "compressedSegmentationBlockSize": undefined, + "dataType": "UINT16", + "lowerVoxelBound": [ + 0, + 0, + ], + "upperVoxelBound": [ + 3, + 5, + ], + }, + }, + "chunkToMultiscaleTransform": [ + [ + 4, + 0, + 0, + ], + [ + 0, + 4, + 0, + ], + [ + 0, + 0, + 1, + ], + ], + }, + ], + ], + "volumeType": "IMAGE", + }, + }, + }, + { + "default": true, + "id": "bounds", + "subsource": { + "staticAnnotations": [ + { + "description": "Data Bounds", + "id": "data-bounds", + "pointA": [ + 0, + 0, + ], + "pointB": [ + 10, + 20, + ], + "type": "axis_aligned_bounding_box", + }, + ], + }, + }, + ], +} \ No newline at end of file diff --git a/tests/datasource/metadata_snapshots/nifti/example_nifti2.nii.gz.snapshot b/tests/datasource/metadata_snapshots/nifti/example_nifti2.nii.gz.snapshot new file mode 100644 index 0000000000..165e4f1203 --- /dev/null +++ b/tests/datasource/metadata_snapshots/nifti/example_nifti2.nii.gz.snapshot @@ -0,0 +1,213 @@ +{ + "canonicalUrl": "http://localhost:*/datasource/nifti/example_nifti2.nii.gz|gzip:|nifti:", + "modelTransform": { + "inputSpace": { + "bounds": { + "lowerBounds": Float64Array [ + 0, + 0, + 0, + 0, + ], + "upperBounds": Float64Array [ + 32, + 20, + 12, + 2, + ], + "voxelCenterAtIntegerCoordinates": [ + false, + false, + false, + false, + ], + }, + "coordinateArrays": [ + , + , + , + , + ], + "names": [ + "i", + "j", + "k", + "m", + ], + "scales": Float64Array [ + 0.002, + 0.002, + 0.0021999990940093994, + 2000, + ], + "units": [ + "m", + "m", + "m", + "s", + ], + "valid": true, + }, + "outputSpace": { + "bounds": { + "lowerBounds": Float64Array [ + -Infinity, + -Infinity, + -Infinity, + -Infinity, + ], + "upperBounds": Float64Array [ + Infinity, + Infinity, + Infinity, + Infinity, + ], + "voxelCenterAtIntegerCoordinates": [ + false, + false, + false, + false, + ], + }, + "coordinateArrays": [ + , + , + , + , + ], + "names": [ + "x", + "y", + "z", + "t", + ], + "scales": Float64Array [ + 0.001, + 0.001, + 0.001, + 1, + ], + "units": [ + "m", + "m", + "m", + "s", + ], + "valid": true, + }, + "transform": [ + [ + -1, + 0.000005141198016644921, + 0.00006320902321022004, + 0, + 117.8551025390625, + ], + [ + -0.000005141198016644921, + 0.9868557453155518, + -0.16160380840301514, + 0, + -35.72294235229492, + ], + [ + 0.00006320902321022004, + 0.16160380840301514, + 0.9868557453155518, + 0, + -7.248798370361328, + ], + [ + 0, + 0, + 0, + 1, + 0, + ], + [ + 0, + 0, + 0, + 0, + 1, + ], + ], + }, + "subsources": [ + { + "default": true, + "id": "default", + "subsource": { + "volume": { + "dataType": "INT16", + "rank": 4, + "sources": [ + [ + { + "chunkSource": { + "parameters": { + "url": "http://localhost:*/datasource/nifti/example_nifti2.nii.gz|gzip:", + }, + "spec": { + "baseVoxelOffset": [ + 0, + 0, + 0, + 0, + ], + "chunkDataSize": [ + 32, + 20, + 12, + 2, + ], + "compressedSegmentationBlockSize": undefined, + "dataType": "INT16", + "lowerVoxelBound": [ + 0, + 0, + 0, + 0, + ], + "upperVoxelBound": [ + 32, + 20, + 12, + 2, + ], + }, + }, + }, + ], + ], + "volumeType": "UNKNOWN", + }, + }, + }, + { + "default": true, + "id": "bounds", + "subsource": { + "staticAnnotations": [ + { + "description": "Data Bounds", + "id": "data-bounds", + "pointA": [ + 0, + 0, + 0, + 0, + ], + "pointB": [ + 32, + 20, + 12, + 2, + ], + "type": "axis_aligned_bounding_box", + }, + ], + }, + }, + ], +} \ No newline at end of file diff --git a/tests/datasource/metadata_snapshots/nifti/standard.nii.gz.snapshot b/tests/datasource/metadata_snapshots/nifti/standard.nii.gz.snapshot new file mode 100644 index 0000000000..ae3792a1a4 --- /dev/null +++ b/tests/datasource/metadata_snapshots/nifti/standard.nii.gz.snapshot @@ -0,0 +1,156 @@ +{ + "canonicalUrl": "http://localhost:*/datasource/nifti/standard.nii.gz|gzip:|nifti:", + "modelTransform": { + "inputSpace": { + "bounds": { + "lowerBounds": Float64Array [ + 0, + 0, + 0, + ], + "upperBounds": Float64Array [ + 4, + 5, + 7, + ], + "voxelCenterAtIntegerCoordinates": [ + false, + false, + false, + ], + }, + "coordinateArrays": [ + , + , + , + ], + "names": [ + "i", + "j", + "k", + ], + "scales": Float64Array [ + 1, + 3, + 2, + ], + "units": [ + "", + "", + "", + ], + "valid": true, + }, + "outputSpace": { + "bounds": { + "lowerBounds": Float64Array [ + -Infinity, + -Infinity, + -Infinity, + ], + "upperBounds": Float64Array [ + Infinity, + Infinity, + Infinity, + ], + "voxelCenterAtIntegerCoordinates": [ + false, + false, + false, + ], + }, + "coordinateArrays": [ + , + , + , + ], + "names": [ + "x", + "y", + "z", + ], + "scales": Float64Array [ + 1, + 1, + 1, + ], + "units": [ + "", + "", + "", + ], + "valid": true, + }, + }, + "subsources": [ + { + "default": true, + "id": "default", + "subsource": { + "volume": { + "dataType": "UINT8", + "rank": 3, + "sources": [ + [ + { + "chunkSource": { + "parameters": { + "url": "http://localhost:*/datasource/nifti/standard.nii.gz|gzip:", + }, + "spec": { + "baseVoxelOffset": [ + 0, + 0, + 0, + ], + "chunkDataSize": [ + 4, + 5, + 7, + ], + "compressedSegmentationBlockSize": undefined, + "dataType": "UINT8", + "lowerVoxelBound": [ + 0, + 0, + 0, + ], + "upperVoxelBound": [ + 4, + 5, + 7, + ], + }, + }, + }, + ], + ], + "volumeType": "UNKNOWN", + }, + }, + }, + { + "default": true, + "id": "bounds", + "subsource": { + "staticAnnotations": [ + { + "description": "Data Bounds", + "id": "data-bounds", + "pointA": [ + 0, + 0, + 0, + ], + "pointB": [ + 4, + 5, + 7, + ], + "type": "axis_aligned_bounding_box", + }, + ], + }, + }, + ], +} \ No newline at end of file diff --git a/tests/datasource/metadata_snapshots/nifti/standard.nii.snapshot b/tests/datasource/metadata_snapshots/nifti/standard.nii.snapshot new file mode 100644 index 0000000000..3c57057f7b --- /dev/null +++ b/tests/datasource/metadata_snapshots/nifti/standard.nii.snapshot @@ -0,0 +1,156 @@ +{ + "canonicalUrl": "http://localhost:*/datasource/nifti/standard.nii|nifti:", + "modelTransform": { + "inputSpace": { + "bounds": { + "lowerBounds": Float64Array [ + 0, + 0, + 0, + ], + "upperBounds": Float64Array [ + 4, + 5, + 7, + ], + "voxelCenterAtIntegerCoordinates": [ + false, + false, + false, + ], + }, + "coordinateArrays": [ + , + , + , + ], + "names": [ + "i", + "j", + "k", + ], + "scales": Float64Array [ + 1, + 3, + 2, + ], + "units": [ + "", + "", + "", + ], + "valid": true, + }, + "outputSpace": { + "bounds": { + "lowerBounds": Float64Array [ + -Infinity, + -Infinity, + -Infinity, + ], + "upperBounds": Float64Array [ + Infinity, + Infinity, + Infinity, + ], + "voxelCenterAtIntegerCoordinates": [ + false, + false, + false, + ], + }, + "coordinateArrays": [ + , + , + , + ], + "names": [ + "x", + "y", + "z", + ], + "scales": Float64Array [ + 1, + 1, + 1, + ], + "units": [ + "", + "", + "", + ], + "valid": true, + }, + }, + "subsources": [ + { + "default": true, + "id": "default", + "subsource": { + "volume": { + "dataType": "UINT8", + "rank": 3, + "sources": [ + [ + { + "chunkSource": { + "parameters": { + "url": "http://localhost:*/datasource/nifti/standard.nii", + }, + "spec": { + "baseVoxelOffset": [ + 0, + 0, + 0, + ], + "chunkDataSize": [ + 4, + 5, + 7, + ], + "compressedSegmentationBlockSize": undefined, + "dataType": "UINT8", + "lowerVoxelBound": [ + 0, + 0, + 0, + ], + "upperVoxelBound": [ + 4, + 5, + 7, + ], + }, + }, + }, + ], + ], + "volumeType": "UNKNOWN", + }, + }, + }, + { + "default": true, + "id": "bounds", + "subsource": { + "staticAnnotations": [ + { + "description": "Data Bounds", + "id": "data-bounds", + "pointA": [ + 0, + 0, + 0, + ], + "pointB": [ + 4, + 5, + 7, + ], + "type": "axis_aligned_bounding_box", + }, + ], + }, + }, + ], +} \ No newline at end of file diff --git a/tests/datasource/metadata_snapshots/precomputed/one_channel.snapshot b/tests/datasource/metadata_snapshots/precomputed/one_channel.snapshot new file mode 100644 index 0000000000..df3b27612c --- /dev/null +++ b/tests/datasource/metadata_snapshots/precomputed/one_channel.snapshot @@ -0,0 +1,266 @@ +{ + "canonicalUrl": "http://localhost:*/datasource/precomputed/one_channel/|neuroglancer-precomputed:", + "modelTransform": { + "inputSpace": { + "bounds": { + "lowerBounds": Float64Array [ + 0, + 0, + 0, + ], + "upperBounds": Float64Array [ + 10, + 20, + 30, + ], + "voxelCenterAtIntegerCoordinates": [ + false, + false, + false, + ], + }, + "coordinateArrays": [ + , + , + , + ], + "names": [ + "x", + "y", + "z", + ], + "scales": Float64Array [ + 3e-9, + 4e-9, + 5e-9, + ], + "units": [ + "m", + "m", + "m", + ], + "valid": true, + }, + }, + "subsources": [ + { + "default": true, + "id": "default", + "subsource": { + "volume": { + "dataType": "UINT16", + "rank": 3, + "sources": [ + [ + { + "chunkSource": { + "parameters": { + "encoding": 0, + "sharding": undefined, + "url": "http://localhost:*/datasource/precomputed/one_channel/3_4_5/", + }, + "spec": { + "baseVoxelOffset": [ + 0, + 0, + 0, + ], + "chunkDataSize": [ + 10, + 20, + 30, + ], + "compressedSegmentationBlockSize": undefined, + "dataType": "UINT16", + "lowerVoxelBound": [ + 0, + 0, + 0, + ], + "upperVoxelBound": [ + 10, + 20, + 30, + ], + }, + }, + "lowerClipBound": Float32Array [ + 0, + 0, + 0, + ], + "upperClipBound": Float32Array [ + 10, + 20, + 30, + ], + }, + { + "chunkSource": { + "parameters": { + "encoding": 0, + "sharding": undefined, + "url": "http://localhost:*/datasource/precomputed/one_channel/6_8_10/", + }, + "spec": { + "baseVoxelOffset": [ + 0, + 0, + 0, + ], + "chunkDataSize": [ + 5, + 10, + 15, + ], + "compressedSegmentationBlockSize": undefined, + "dataType": "UINT16", + "lowerVoxelBound": [ + 0, + 0, + 0, + ], + "upperVoxelBound": [ + 5, + 10, + 15, + ], + }, + }, + "chunkToMultiscaleTransform": [ + [ + 2, + 0, + 0, + 0, + ], + [ + 0, + 2, + 0, + 0, + ], + [ + 0, + 0, + 2, + 0, + ], + [ + 0, + 0, + 0, + 1, + ], + ], + "lowerClipBound": Float32Array [ + 0, + 0, + 0, + ], + "upperClipBound": Float32Array [ + 5, + 10, + 15, + ], + }, + { + "chunkSource": { + "parameters": { + "encoding": 0, + "sharding": undefined, + "url": "http://localhost:*/datasource/precomputed/one_channel/12_16_20/", + }, + "spec": { + "baseVoxelOffset": [ + 0, + 0, + 0, + ], + "chunkDataSize": [ + 3, + 5, + 8, + ], + "compressedSegmentationBlockSize": undefined, + "dataType": "UINT16", + "lowerVoxelBound": [ + 0, + 0, + 0, + ], + "upperVoxelBound": [ + 3, + 5, + 8, + ], + }, + }, + "chunkToMultiscaleTransform": [ + [ + 4, + 0, + 0, + 0, + ], + [ + 0, + 4, + 0, + 0, + ], + [ + 0, + 0, + 4, + 0, + ], + [ + 0, + 0, + 0, + 1, + ], + ], + "lowerClipBound": Float32Array [ + 0, + 0, + 0, + ], + "upperClipBound": Float32Array [ + 2.5, + 5, + 7.5, + ], + }, + ], + ], + "volumeType": "IMAGE", + }, + }, + }, + { + "default": true, + "id": "bounds", + "subsource": { + "staticAnnotations": [ + { + "description": "Data Bounds", + "id": "data-bounds", + "pointA": [ + 0, + 0, + 0, + ], + "pointB": [ + 10, + 20, + 30, + ], + "type": "axis_aligned_bounding_box", + }, + ], + }, + }, + ], +} \ No newline at end of file diff --git a/tests/datasource/metadata_snapshots/precomputed/two_channels.snapshot b/tests/datasource/metadata_snapshots/precomputed/two_channels.snapshot new file mode 100644 index 0000000000..1b252e1674 --- /dev/null +++ b/tests/datasource/metadata_snapshots/precomputed/two_channels.snapshot @@ -0,0 +1,315 @@ +{ + "canonicalUrl": "http://localhost:*/datasource/precomputed/two_channels/|neuroglancer-precomputed:", + "modelTransform": { + "inputSpace": { + "bounds": { + "lowerBounds": Float64Array [ + 0, + 0, + 0, + 0, + ], + "upperBounds": Float64Array [ + 10, + 20, + 30, + 2, + ], + "voxelCenterAtIntegerCoordinates": [ + false, + false, + false, + false, + ], + }, + "coordinateArrays": [ + , + , + , + , + ], + "names": [ + "x", + "y", + "z", + "c^", + ], + "scales": Float64Array [ + 3e-9, + 4e-9, + 5e-9, + 1, + ], + "units": [ + "m", + "m", + "m", + "", + ], + "valid": true, + }, + }, + "subsources": [ + { + "default": true, + "id": "default", + "subsource": { + "volume": { + "dataType": "UINT16", + "rank": 4, + "sources": [ + [ + { + "chunkSource": { + "parameters": { + "encoding": 0, + "sharding": undefined, + "url": "http://localhost:*/datasource/precomputed/two_channels/3_4_5/", + }, + "spec": { + "baseVoxelOffset": [ + 0, + 0, + 0, + 0, + ], + "chunkDataSize": [ + 10, + 20, + 30, + 2, + ], + "compressedSegmentationBlockSize": undefined, + "dataType": "UINT16", + "lowerVoxelBound": [ + 0, + 0, + 0, + 0, + ], + "upperVoxelBound": [ + 10, + 20, + 30, + 2, + ], + }, + }, + "lowerClipBound": Float32Array [ + 0, + 0, + 0, + 0, + ], + "upperClipBound": Float32Array [ + 10, + 20, + 30, + 2, + ], + }, + { + "chunkSource": { + "parameters": { + "encoding": 0, + "sharding": undefined, + "url": "http://localhost:*/datasource/precomputed/two_channels/6_8_10/", + }, + "spec": { + "baseVoxelOffset": [ + 0, + 0, + 0, + 0, + ], + "chunkDataSize": [ + 5, + 10, + 15, + 2, + ], + "compressedSegmentationBlockSize": undefined, + "dataType": "UINT16", + "lowerVoxelBound": [ + 0, + 0, + 0, + 0, + ], + "upperVoxelBound": [ + 5, + 10, + 15, + 2, + ], + }, + }, + "chunkToMultiscaleTransform": [ + [ + 2, + 0, + 0, + 0, + 0, + ], + [ + 0, + 2, + 0, + 0, + 0, + ], + [ + 0, + 0, + 2, + 0, + 0, + ], + [ + 0, + 0, + 0, + 1, + 0, + ], + [ + 0, + 0, + 0, + 0, + 1, + ], + ], + "lowerClipBound": Float32Array [ + 0, + 0, + 0, + 0, + ], + "upperClipBound": Float32Array [ + 5, + 10, + 15, + 2, + ], + }, + { + "chunkSource": { + "parameters": { + "encoding": 0, + "sharding": undefined, + "url": "http://localhost:*/datasource/precomputed/two_channels/12_16_20/", + }, + "spec": { + "baseVoxelOffset": [ + 0, + 0, + 0, + 0, + ], + "chunkDataSize": [ + 3, + 5, + 8, + 2, + ], + "compressedSegmentationBlockSize": undefined, + "dataType": "UINT16", + "lowerVoxelBound": [ + 0, + 0, + 0, + 0, + ], + "upperVoxelBound": [ + 3, + 5, + 8, + 2, + ], + }, + }, + "chunkToMultiscaleTransform": [ + [ + 4, + 0, + 0, + 0, + 0, + ], + [ + 0, + 4, + 0, + 0, + 0, + ], + [ + 0, + 0, + 4, + 0, + 0, + ], + [ + 0, + 0, + 0, + 1, + 0, + ], + [ + 0, + 0, + 0, + 0, + 1, + ], + ], + "lowerClipBound": Float32Array [ + 0, + 0, + 0, + 0, + ], + "upperClipBound": Float32Array [ + 2.5, + 5, + 7.5, + 2, + ], + }, + ], + ], + "volumeType": "IMAGE", + }, + }, + }, + { + "default": true, + "id": "bounds", + "subsource": { + "staticAnnotations": [ + { + "description": "Data Bounds", + "id": "data-bounds", + "pointA": [ + 0, + 0, + 0, + 0, + ], + "pointB": [ + 10, + 20, + 30, + 2, + ], + "type": "axis_aligned_bounding_box", + }, + ], + }, + }, + ], +} \ No newline at end of file diff --git a/tests/datasource/metadata_snapshots/zarr/ome_zarr_simple_0.4.snapshot b/tests/datasource/metadata_snapshots/zarr/ome_zarr_simple_0.4.snapshot new file mode 100644 index 0000000000..2a04b75837 --- /dev/null +++ b/tests/datasource/metadata_snapshots/zarr/ome_zarr_simple_0.4.snapshot @@ -0,0 +1,208 @@ +{ + "canonicalUrl": "http://localhost:*/datasource/zarr/ome_zarr/simple_0.4/|zarr2:", + "modelTransform": { + "inputSpace": { + "bounds": { + "lowerBounds": Float64Array [ + -0.5, + -0.5, + ], + "upperBounds": Float64Array [ + 9.5, + 9.5, + ], + "voxelCenterAtIntegerCoordinates": [ + true, + true, + ], + }, + "coordinateArrays": [ + , + , + ], + "names": [ + "y", + "x", + ], + "scales": Float64Array [ + 4e-9, + 3.0000000000000004e-8, + ], + "units": [ + "m", + "m", + ], + "valid": true, + }, + }, + "subsources": [ + { + "default": true, + "id": "default", + "subsource": { + "volume": { + "dataType": "UINT16", + "rank": 2, + "sources": [ + [ + { + "chunkSource": { + "parameters": { + "url": "http://localhost:*/datasource/zarr/ome_zarr/simple_0.4/scale0/image/", + }, + "spec": { + "baseVoxelOffset": [ + 0, + 0, + ], + "chunkDataSize": [ + 10, + 10, + ], + "compressedSegmentationBlockSize": undefined, + "dataType": "UINT16", + "lowerVoxelBound": [ + 0, + 0, + ], + "upperVoxelBound": [ + 10, + 10, + ], + }, + }, + "chunkToMultiscaleTransform": [ + [ + 0, + 1, + -0.5, + ], + [ + 1, + 0, + -0.5, + ], + [ + 0, + 0, + 1, + ], + ], + }, + { + "chunkSource": { + "parameters": { + "url": "http://localhost:*/datasource/zarr/ome_zarr/simple_0.4/scale1/image/", + }, + "spec": { + "baseVoxelOffset": [ + 0, + 0, + ], + "chunkDataSize": [ + 5, + 5, + ], + "compressedSegmentationBlockSize": undefined, + "dataType": "UINT16", + "lowerVoxelBound": [ + 0, + 0, + ], + "upperVoxelBound": [ + 5, + 5, + ], + }, + }, + "chunkToMultiscaleTransform": [ + [ + 0, + 2, + -0.5, + ], + [ + 2, + 0, + -0.5, + ], + [ + 0, + 0, + 1, + ], + ], + }, + { + "chunkSource": { + "parameters": { + "url": "http://localhost:*/datasource/zarr/ome_zarr/simple_0.4/scale2/image/", + }, + "spec": { + "baseVoxelOffset": [ + 0, + 0, + ], + "chunkDataSize": [ + 2, + 2, + ], + "compressedSegmentationBlockSize": undefined, + "dataType": "UINT16", + "lowerVoxelBound": [ + 0, + 0, + ], + "upperVoxelBound": [ + 2, + 2, + ], + }, + }, + "chunkToMultiscaleTransform": [ + [ + 0, + 4, + -0.5, + ], + [ + 4, + 0, + -0.5, + ], + [ + 0, + 0, + 1, + ], + ], + }, + ], + ], + "volumeType": "IMAGE", + }, + }, + }, + { + "default": true, + "id": "bounds", + "subsource": { + "staticAnnotations": [ + { + "description": "Data Bounds", + "id": "data-bounds", + "pointA": [ + -0.5, + -0.5, + ], + "pointB": [ + 9.5, + 9.5, + ], + "type": "axis_aligned_bounding_box", + }, + ], + }, + }, + ], +} \ No newline at end of file diff --git a/tests/datasource/metadata_snapshots/zarr/ome_zarr_simple_0.4.zip.snapshot b/tests/datasource/metadata_snapshots/zarr/ome_zarr_simple_0.4.zip.snapshot new file mode 100644 index 0000000000..2f91f77c3c --- /dev/null +++ b/tests/datasource/metadata_snapshots/zarr/ome_zarr_simple_0.4.zip.snapshot @@ -0,0 +1,208 @@ +{ + "canonicalUrl": "http://localhost:*/datasource/zarr/ome_zarr/simple_0.4.zip|zip:|zarr3:", + "modelTransform": { + "inputSpace": { + "bounds": { + "lowerBounds": Float64Array [ + -0.5, + -0.5, + ], + "upperBounds": Float64Array [ + 9.5, + 9.5, + ], + "voxelCenterAtIntegerCoordinates": [ + true, + true, + ], + }, + "coordinateArrays": [ + , + , + ], + "names": [ + "y", + "x", + ], + "scales": Float64Array [ + 4e-9, + 3.0000000000000004e-8, + ], + "units": [ + "m", + "m", + ], + "valid": true, + }, + }, + "subsources": [ + { + "default": true, + "id": "default", + "subsource": { + "volume": { + "dataType": "UINT16", + "rank": 2, + "sources": [ + [ + { + "chunkSource": { + "parameters": { + "url": "http://localhost:*/datasource/zarr/ome_zarr/simple_0.4.zip|zip:scale0/image/", + }, + "spec": { + "baseVoxelOffset": [ + 0, + 0, + ], + "chunkDataSize": [ + 10, + 10, + ], + "compressedSegmentationBlockSize": undefined, + "dataType": "UINT16", + "lowerVoxelBound": [ + 0, + 0, + ], + "upperVoxelBound": [ + 10, + 10, + ], + }, + }, + "chunkToMultiscaleTransform": [ + [ + 0, + 1, + -0.5, + ], + [ + 1, + 0, + -0.5, + ], + [ + 0, + 0, + 1, + ], + ], + }, + { + "chunkSource": { + "parameters": { + "url": "http://localhost:*/datasource/zarr/ome_zarr/simple_0.4.zip|zip:scale1/image/", + }, + "spec": { + "baseVoxelOffset": [ + 0, + 0, + ], + "chunkDataSize": [ + 5, + 5, + ], + "compressedSegmentationBlockSize": undefined, + "dataType": "UINT16", + "lowerVoxelBound": [ + 0, + 0, + ], + "upperVoxelBound": [ + 5, + 5, + ], + }, + }, + "chunkToMultiscaleTransform": [ + [ + 0, + 2, + -0.5, + ], + [ + 2, + 0, + -0.5, + ], + [ + 0, + 0, + 1, + ], + ], + }, + { + "chunkSource": { + "parameters": { + "url": "http://localhost:*/datasource/zarr/ome_zarr/simple_0.4.zip|zip:scale2/image/", + }, + "spec": { + "baseVoxelOffset": [ + 0, + 0, + ], + "chunkDataSize": [ + 2, + 2, + ], + "compressedSegmentationBlockSize": undefined, + "dataType": "UINT16", + "lowerVoxelBound": [ + 0, + 0, + ], + "upperVoxelBound": [ + 2, + 2, + ], + }, + }, + "chunkToMultiscaleTransform": [ + [ + 0, + 4, + -0.5, + ], + [ + 4, + 0, + -0.5, + ], + [ + 0, + 0, + 1, + ], + ], + }, + ], + ], + "volumeType": "IMAGE", + }, + }, + }, + { + "default": true, + "id": "bounds", + "subsource": { + "staticAnnotations": [ + { + "description": "Data Bounds", + "id": "data-bounds", + "pointA": [ + -0.5, + -0.5, + ], + "pointB": [ + 9.5, + 9.5, + ], + "type": "axis_aligned_bounding_box", + }, + ], + }, + }, + ], +} \ No newline at end of file diff --git a/tests/datasource/metadata_snapshots/zarr/ome_zarr_simple_0.5.snapshot b/tests/datasource/metadata_snapshots/zarr/ome_zarr_simple_0.5.snapshot new file mode 100644 index 0000000000..fe94094414 --- /dev/null +++ b/tests/datasource/metadata_snapshots/zarr/ome_zarr_simple_0.5.snapshot @@ -0,0 +1,208 @@ +{ + "canonicalUrl": "http://localhost:*/datasource/zarr/ome_zarr/simple_0.5/|zarr3:", + "modelTransform": { + "inputSpace": { + "bounds": { + "lowerBounds": Float64Array [ + -0.5, + -0.5, + ], + "upperBounds": Float64Array [ + 9.5, + 9.5, + ], + "voxelCenterAtIntegerCoordinates": [ + true, + true, + ], + }, + "coordinateArrays": [ + , + , + ], + "names": [ + "y", + "x", + ], + "scales": Float64Array [ + 4e-9, + 3.0000000000000004e-8, + ], + "units": [ + "m", + "m", + ], + "valid": true, + }, + }, + "subsources": [ + { + "default": true, + "id": "default", + "subsource": { + "volume": { + "dataType": "UINT16", + "rank": 2, + "sources": [ + [ + { + "chunkSource": { + "parameters": { + "url": "http://localhost:*/datasource/zarr/ome_zarr/simple_0.5/scale0/image/", + }, + "spec": { + "baseVoxelOffset": [ + 0, + 0, + ], + "chunkDataSize": [ + 10, + 10, + ], + "compressedSegmentationBlockSize": undefined, + "dataType": "UINT16", + "lowerVoxelBound": [ + 0, + 0, + ], + "upperVoxelBound": [ + 10, + 10, + ], + }, + }, + "chunkToMultiscaleTransform": [ + [ + 0, + 1, + -0.5, + ], + [ + 1, + 0, + -0.5, + ], + [ + 0, + 0, + 1, + ], + ], + }, + { + "chunkSource": { + "parameters": { + "url": "http://localhost:*/datasource/zarr/ome_zarr/simple_0.5/scale1/image/", + }, + "spec": { + "baseVoxelOffset": [ + 0, + 0, + ], + "chunkDataSize": [ + 5, + 5, + ], + "compressedSegmentationBlockSize": undefined, + "dataType": "UINT16", + "lowerVoxelBound": [ + 0, + 0, + ], + "upperVoxelBound": [ + 5, + 5, + ], + }, + }, + "chunkToMultiscaleTransform": [ + [ + 0, + 2, + -0.5, + ], + [ + 2, + 0, + -0.5, + ], + [ + 0, + 0, + 1, + ], + ], + }, + { + "chunkSource": { + "parameters": { + "url": "http://localhost:*/datasource/zarr/ome_zarr/simple_0.5/scale2/image/", + }, + "spec": { + "baseVoxelOffset": [ + 0, + 0, + ], + "chunkDataSize": [ + 2, + 2, + ], + "compressedSegmentationBlockSize": undefined, + "dataType": "UINT16", + "lowerVoxelBound": [ + 0, + 0, + ], + "upperVoxelBound": [ + 2, + 2, + ], + }, + }, + "chunkToMultiscaleTransform": [ + [ + 0, + 4, + -0.5, + ], + [ + 4, + 0, + -0.5, + ], + [ + 0, + 0, + 1, + ], + ], + }, + ], + ], + "volumeType": "IMAGE", + }, + }, + }, + { + "default": true, + "id": "bounds", + "subsource": { + "staticAnnotations": [ + { + "description": "Data Bounds", + "id": "data-bounds", + "pointA": [ + -0.5, + -0.5, + ], + "pointB": [ + 9.5, + 9.5, + ], + "type": "axis_aligned_bounding_box", + }, + ], + }, + }, + ], +} \ No newline at end of file diff --git a/tests/datasource/metadata_snapshots/zarr/zarr_v3_examples_single_res.snapshot b/tests/datasource/metadata_snapshots/zarr/zarr_v3_examples_single_res.snapshot new file mode 100644 index 0000000000..61d179dcc5 --- /dev/null +++ b/tests/datasource/metadata_snapshots/zarr/zarr_v3_examples_single_res.snapshot @@ -0,0 +1,120 @@ +{ + "canonicalUrl": "http://localhost:*/datasource/zarr/zarr_v3/examples/single_res/|zarr3:", + "modelTransform": { + "inputSpace": { + "bounds": { + "lowerBounds": Float64Array [ + 0, + 0, + ], + "upperBounds": Float64Array [ + 6, + 7, + ], + "voxelCenterAtIntegerCoordinates": [ + false, + false, + ], + }, + "coordinateArrays": [ + , + , + ], + "names": [ + "dim_0", + "dim_1", + ], + "scales": Float64Array [ + 1, + 1, + ], + "units": [ + "", + "", + ], + "valid": true, + }, + }, + "subsources": [ + { + "default": true, + "id": "default", + "subsource": { + "volume": { + "dataType": "UINT16", + "rank": 2, + "sources": [ + [ + { + "chunkSource": { + "parameters": { + "url": "http://localhost:*/datasource/zarr/zarr_v3/examples/single_res/", + }, + "spec": { + "baseVoxelOffset": [ + 0, + 0, + ], + "chunkDataSize": [ + 5, + 4, + ], + "compressedSegmentationBlockSize": undefined, + "dataType": "UINT16", + "lowerVoxelBound": [ + 0, + 0, + ], + "upperVoxelBound": [ + 7, + 6, + ], + }, + }, + "chunkToMultiscaleTransform": [ + [ + 0, + 1, + 0, + ], + [ + 1, + 0, + 0, + ], + [ + 0, + 0, + 1, + ], + ], + }, + ], + ], + "volumeType": "IMAGE", + }, + }, + }, + { + "default": true, + "id": "bounds", + "subsource": { + "staticAnnotations": [ + { + "description": "Data Bounds", + "id": "data-bounds", + "pointA": [ + 0, + 0, + ], + "pointB": [ + 6, + 7, + ], + "type": "axis_aligned_bounding_box", + }, + ], + }, + }, + ], +} \ No newline at end of file diff --git a/tests/datasource/n5.browser_test.ts b/tests/datasource/n5.browser_test.ts new file mode 100644 index 0000000000..1de2f252a4 --- /dev/null +++ b/tests/datasource/n5.browser_test.ts @@ -0,0 +1,24 @@ +/** + * @license + * Copyright 2024 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import "#src/datasource/n5/register_default"; +import "#src/sliceview/uncompressed_chunk_format.js"; +import { datasourceMetadataSnapshotTests } from "#tests/datasource/metadata_snapshot_test_util.js"; + +datasourceMetadataSnapshotTests("n5", [ + "n5_viewer_multiscale_deprecated", + "n5_viewer_multiscale_modern", +]); diff --git a/tests/datasource/nifti.browser_test.ts b/tests/datasource/nifti.browser_test.ts new file mode 100644 index 0000000000..430f745b46 --- /dev/null +++ b/tests/datasource/nifti.browser_test.ts @@ -0,0 +1,26 @@ +/** + * @license + * Copyright 2024 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import "#src/datasource/nifti/register_default.js"; +import "#src/kvstore/gzip/register.js"; +import "#src/sliceview/uncompressed_chunk_format.js"; +import { datasourceMetadataSnapshotTests } from "#tests/datasource/metadata_snapshot_test_util.js"; + +datasourceMetadataSnapshotTests("nifti", [ + "standard.nii", + "standard.nii.gz", + "example_nifti2.nii.gz", +]); diff --git a/tests/datasource/precomputed.browser_test.ts b/tests/datasource/precomputed.browser_test.ts new file mode 100644 index 0000000000..735bbe16da --- /dev/null +++ b/tests/datasource/precomputed.browser_test.ts @@ -0,0 +1,21 @@ +/** + * @license + * Copyright 2024 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import "#src/datasource/precomputed/register_default"; +import "#src/sliceview/uncompressed_chunk_format.js"; +import { datasourceMetadataSnapshotTests } from "#tests/datasource/metadata_snapshot_test_util.js"; + +datasourceMetadataSnapshotTests("precomputed", ["one_channel", "two_channels"]); diff --git a/tests/datasource/suggest_name.spec.ts b/tests/datasource/suggest_name.spec.ts new file mode 100644 index 0000000000..a9128e05f4 --- /dev/null +++ b/tests/datasource/suggest_name.spec.ts @@ -0,0 +1,31 @@ +/** + * @license + * Copyright 2025 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { expect, test } from "vitest"; +import { dataSourceProviderFixture } from "#tests/fixtures/datasource_provider.js"; + +const datasourceProviderFixture = dataSourceProviderFixture(); + +test.for([ + ["http://localhost/path/to/array/|zarr3:", "array"], + ["http://localhost/path/to/array/", "array"], + ["http://localhost/path/to/array", "array"], + ["http://localhost/path/to/group/|zarr3:path/to/array/", "array"], + ["brainmaps://foo:bar:baz", "baz"], +])("%s -> %s", async ([url, expectedName]) => { + const registry = await datasourceProviderFixture(); + expect(registry.suggestLayerName(url)).toEqual(expectedName); +}); diff --git a/tests/datasource/test_util.ts b/tests/datasource/test_util.ts new file mode 100644 index 0000000000..66b804ada5 --- /dev/null +++ b/tests/datasource/test_util.ts @@ -0,0 +1,184 @@ +/** + * @license + * Copyright 2025 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { + CoordinateSpace, + CoordinateSpaceTransform, +} from "#src/coordinate_transform.js"; +import { coordinateSpacesEqual } from "#src/coordinate_transform.js"; +import type { + DataSource, + DataSourceRegistry, + DataSubsource, + DataSubsourceEntry, +} from "#src/datasource/index.js"; +import type { SliceViewSingleResolutionSource } from "#src/sliceview/frontend.js"; +import { VolumeType } from "#src/sliceview/volume/base.js"; +import type { MultiscaleVolumeChunkSource } from "#src/sliceview/volume/frontend.js"; +import { VolumeChunkSource } from "#src/sliceview/volume/frontend.js"; +import { DataType } from "#src/util/data_type.js"; +import * as matrix from "#src/util/matrix.js"; +import type { ProgressListener } from "#src/util/progress_listener.js"; +import type { Fixture } from "#tests/fixtures/fixture.js"; + +export function getDatasourceSnapshot(datasource: DataSource) { + return { + subsources: Array.from(datasource.subsources, getSubsourceEntrySnapshot), + modelTransform: getCoordinateSpaceTransformSnapshot( + datasource.modelTransform, + ), + canonicalUrl: redactUrl(datasource.canonicalUrl), + ...getKeys(datasource, ["canChangeModelSpaceRank"]), + }; +} + +function getKeys(x: T, keys: Array) { + return Object.fromEntries( + keys + .map((key) => [key, x[key]]) + .filter(([_key, value]) => value !== undefined), + ); +} + +function getCoordinateSpaceSnapshot(x: CoordinateSpace) { + return getKeys(x, [ + "valid", + "names", + "units", + "scales", + "bounds", + "coordinateArrays", + ]); +} + +function getCoordinateSpaceTransformSnapshot(x: CoordinateSpaceTransform) { + const { rank } = x; + const result: any = {}; + result.inputSpace = getCoordinateSpaceSnapshot(x.inputSpace); + if (!coordinateSpacesEqual(x.inputSpace, x.outputSpace)) { + result.outputSpace = getCoordinateSpaceSnapshot(x.outputSpace); + } + if (!matrix.isIdentity(x.transform, rank + 1, rank + 1)) { + result.transform = getMatrixSnapshot(x.transform, rank + 1); + } + return result; +} + +function getMatrixSnapshot(matrix: ArrayLike, rows: number) { + const result: number[][] = []; + const cols = matrix.length / rows; + for (let row = 0; row < rows; ++row) { + const rowElements: number[] = []; + for (let col = 0; col < cols; ++col) { + rowElements[col] = matrix[col * rows + row]; + } + result[row] = rowElements; + } + return result; +} + +function getSubsourceEntrySnapshot(subsource: DataSubsourceEntry) { + return { + subsource: getSubsourceSnapshot(subsource.subsource), + ...getKeys(subsource, [ + "default", + "id", + "modelSubspaceDimensionIndices", + "subsourceToModelSubspaceTransform", + ]), + }; +} + +function getSubsourceSnapshot(subsource: DataSubsource) { + if (subsource.volume) { + return { volume: getVolumeSnapshot(subsource.volume) }; + } + if (subsource.staticAnnotations) { + return { staticAnnotations: subsource.staticAnnotations.toJSON() }; + } + return {}; +} + +function getVolumeSnapshot(volume: MultiscaleVolumeChunkSource) { + const sources = volume.getSources({ + multiscaleToViewTransform: matrix.createIdentity(Float32Array, volume.rank), + displayRank: volume.rank, + modelChannelDimensionIndices: [], + }); + return { + dataType: DataType[volume.dataType], + volumeType: VolumeType[volume.volumeType], + rank: volume.rank, + sources: sources.map((sourceList) => sourceList.map(getSourceSnapshot)), + }; +} + +function getSourceSnapshot( + source: SliceViewSingleResolutionSource, +) { + const rank = source.chunkSource.spec.rank; + let spec: any = VolumeChunkSource.encodeSpec(source.chunkSource.spec); + spec = { ...spec, dataType: DataType[spec.dataType] }; + const parameters = (source.chunkSource as any).parameters; + delete parameters.metadata; + if (parameters.url) { + parameters.url = redactUrl(parameters.url as string); + } + const result: any = { + ...getKeys(source, ["lowerClipBound", "upperClipBound"]), + chunkSource: { + parameters: (source.chunkSource as any).parameters, + spec, + }, + }; + if ( + !matrix.isIdentity(source.chunkToMultiscaleTransform, rank + 1, rank + 1) + ) { + result.chunkToMultiscaleTransform = getMatrixSnapshot( + source.chunkToMultiscaleTransform, + rank + 1, + ); + } + return result; +} + +function redactUrl(x: string | undefined): string | undefined { + if (x === undefined) return undefined; + return x.replaceAll(/(?<=http:\/\/localhost:)[0-9]+/g, "*"); +} + +export function loggingProgressListener(): ProgressListener { + return { + addSpan(span) { + console.log(`[progress] ${span.message}`); + }, + removeSpan(_span) {}, + }; +} + +export async function getDatasourceMetadata( + dataSourceProvider: Fixture, + url: string, +) { + const provider = await dataSourceProvider(); + const dataSource = await provider.get({ + url, + globalCoordinateSpace: undefined as any, + transform: undefined, + progressListener: loggingProgressListener(), + }); + return getDatasourceSnapshot(dataSource); +} diff --git a/tests/datasource/zarr.browser_test.ts b/tests/datasource/zarr.browser_test.ts new file mode 100644 index 0000000000..dbf8b6b8fb --- /dev/null +++ b/tests/datasource/zarr.browser_test.ts @@ -0,0 +1,27 @@ +/** + * @license + * Copyright 2024 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import "#src/datasource/zarr/register_default.js"; +import "#src/kvstore/zip/register_frontend.js"; +import "#src/sliceview/uncompressed_chunk_format.js"; +import { datasourceMetadataSnapshotTests } from "#tests/datasource/metadata_snapshot_test_util.js"; + +datasourceMetadataSnapshotTests("zarr", [ + "zarr_v3/examples/single_res", + "ome_zarr/simple_0.4", + "ome_zarr/simple_0.4.zip", + "ome_zarr/simple_0.5", +]); diff --git a/tests/fixtures/clear_cookies.ts b/tests/fixtures/clear_cookies.ts new file mode 100644 index 0000000000..f8c05947eb --- /dev/null +++ b/tests/fixtures/clear_cookies.ts @@ -0,0 +1,31 @@ +/** + * @license + * Copyright 2024 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { afterEach } from "vitest"; +import type { Fixture } from "#tests/fixtures/fixture.js"; + +export function clearCookiesFixture(): Fixture { + afterEach(() => clearCookies()); + return async () => {}; +} + +export function clearCookies(): void { + document.cookie.split(";").forEach((cookie) => { + document.cookie = cookie + .replace(/^ +/, "") + .replace(/=.*/, `=;expires=${new Date(0).toUTCString()};path=/`); + }); +} diff --git a/tests/fixtures/datasource_provider.ts b/tests/fixtures/datasource_provider.ts new file mode 100644 index 0000000000..8d39316eda --- /dev/null +++ b/tests/fixtures/datasource_provider.ts @@ -0,0 +1,35 @@ +/** + * @license + * Copyright 2024 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { getDefaultDataSourceProvider } from "#src/datasource/default_provider.js"; +import { type DataSourceRegistry } from "#src/datasource/index.js"; +import type { SharedKvStoreContext } from "#src/kvstore/frontend.js"; +import { fixture, type Fixture } from "#tests/fixtures/fixture.js"; +import { sharedKvStoreContextFixture } from "./shared_kvstore_context"; + +export function dataSourceProviderFixture( + sharedKvStoreContext: Fixture = sharedKvStoreContextFixture(), +): Fixture { + return fixture(async (stack) => { + const kvStoreContext = await sharedKvStoreContext(); + const provider = getDefaultDataSourceProvider({ + kvStoreContext, + credentialsManager: kvStoreContext.credentialsManager, + }); + stack.defer(() => provider.dispose()); + return provider; + }); +} diff --git a/tests/fixtures/fake_gcs_server.ts b/tests/fixtures/fake_gcs_server.ts new file mode 100644 index 0000000000..f225d6c6ae --- /dev/null +++ b/tests/fixtures/fake_gcs_server.ts @@ -0,0 +1,120 @@ +/** + * @license + * Copyright 2024 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { spawn } from "node:child_process"; +import readline from "node:readline"; +import { bypass, http } from "msw"; +import { beforeEach } from "vitest"; +import { fetchOk } from "#src/util/http_request.js"; +import { fixture, type Fixture } from "#tests/fixtures/fixture.js"; +import type { mswFixture } from "#tests/fixtures/msw"; + +function pickRandomPort() { + const minPort = 1024; + const maxPort = 65535; + return Math.round(Math.random() * (maxPort - minPort) + minPort); +} + +declare const FAKE_GCS_SERVER_BIN: string; + +export function fakeGcsServerFixture( + msw?: ReturnType, +): Fixture { + const gcsServer = fixture(async (stack) => { + const port = pickRandomPort(); + const proc = stack.use( + spawn( + FAKE_GCS_SERVER_BIN, + [ + "-backend", + "memory", + "-scheme", + "http", + "-host", + "localhost", + "-port", + `${port}`, + ], + { stdio: ["ignore", "ignore", "pipe"] }, + ), + ); + + const { resolve, reject, promise } = Promise.withResolvers(); + + (async () => { + for await (const line of readline.createInterface({ + input: proc.stderr, + })) { + console.log(`fake_gcs_server: ${line}`); + if (line.match(/server started at/)) { + resolve(); + } + } + reject(new Error("Failed to start server")); + })(); + await promise; + return `http://localhost:${port}`; + }); + if (msw !== undefined) { + beforeEach(async () => { + const serverUrl = await gcsServer(); + const PUBLIC_SERVER = "https://storage.googleapis.com"; + (await msw()).use( + http.all(`${PUBLIC_SERVER}/storage/*`, ({ request }) => { + const adjustedUrl = + serverUrl + request.url.substring(PUBLIC_SERVER.length); + return fetch(bypass(adjustedUrl, request)); + }), + ); + }); + } + return gcsServer; +} + +const DEFAULT_PROJECT = "myproject"; + +export async function createBucket( + gcs: Fixture, + bucket: string, + project: string = DEFAULT_PROJECT, +) { + await fetchOk( + bypass( + `${await gcs()}/storage/v1/b?project=${encodeURIComponent(project)}`, + { + method: "POST", + body: JSON.stringify({ name: bucket }), + }, + ), + ); +} + +export async function writeObject( + gcs: Fixture, + bucket: string, + path: string, + body: RequestInit["body"], +) { + await fetchOk( + bypass( + `${await gcs()}/upload/storage/v1/b/${encodeURIComponent(bucket)}/o?name=${encodeURIComponent(path)}&uploadType=media`, + { + method: "POST", + body: body, + }, + ), + ); +} diff --git a/tests/fixtures/fake_s3_server.ts b/tests/fixtures/fake_s3_server.ts new file mode 100644 index 0000000000..36c480718f --- /dev/null +++ b/tests/fixtures/fake_s3_server.ts @@ -0,0 +1,137 @@ +/** + * @license + * Copyright 2024 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import nodeHttp from "node:http"; +import nodeStream from "node:stream"; +import { bypass, http } from "msw"; +import S3rver from "s3rver"; +import { beforeEach } from "vitest"; +import { fetchOk } from "#src/util/http_request.js"; +import { fixture, type Fixture } from "#tests/fixtures/fixture.js"; +import type { mswFixture } from "#tests/fixtures/msw"; +import { tempDirectoryFixture } from "#tests/fixtures/temp_directory.js"; + +export function fakeS3ServerFixture( + options: { + directory?: Fixture; + msw?: ReturnType; + } = {}, +): Fixture { + const { directory = tempDirectoryFixture(), msw } = options; + const s3Server = fixture(async (stack) => { + const server = new S3rver({ + address: "localhost", + port: 0, + directory: await directory(), + }); + stack.defer(async () => server.close()); + const address = await server.run(); + return `http://localhost:${address.port}`; + }); + if (msw !== undefined) { + beforeEach(async () => { + const serverUrl = await s3Server(); + (await msw()).use( + http.all( + /^https:\/\/([^/]+\.)?s3\.amazonaws\.com\/.*/, + ({ request }) => { + const parsedServerUrl = new URL(serverUrl); + const requestUrl = new URL(request.url); + const requestHost = requestUrl.host; + requestUrl.protocol = parsedServerUrl.protocol; + requestUrl.host = parsedServerUrl.host; + const headers = request.headers; + headers.set("host", requestHost); + const modifiedRequest = bypass(requestUrl.toString(), request); + const { promise, resolve, reject } = + Promise.withResolvers(); + const req = nodeHttp.request(modifiedRequest.url, { + setHost: false, + signal: modifiedRequest.signal, + headers: { + ...Object.fromEntries(modifiedRequest.headers), + host: requestHost, + }, + method: modifiedRequest.method, + }); + const requestBody = modifiedRequest.body; + req.on("error", (reason) => reject(reason)); + req.on("response", (res) => { + // Convert nodeHttp.IncomingHttpHeaders to Fetch Headers object. + const headers = new Headers(); + for (let [key, value] of Object.entries(res.headers)) { + if (!Array.isArray(value)) value = [value!]; + for (const v of value) { + headers.append(key, v); + } + } + // Convert node stream.Readable to ReadableStream. + const responseBody = new ReadableStream({ + start(controller) { + res.on("data", (chunk) => { + controller.enqueue(chunk); + }); + res.on("end", () => { + controller.close(); + }); + res.on("error", (err) => { + controller.error(err); + }); + }, + }); + resolve( + new Response(responseBody, { + status: res.statusCode, + statusText: res.statusMessage, + headers, + }), + ); + }); + if (requestBody === null) { + req.end(); + } else { + nodeStream.Readable.fromWeb(requestBody as any).pipe(req); + } + return promise; + }, + ), + ); + }); + } + return s3Server; +} + +export async function createBucket(s3: Fixture, bucket: string) { + await fetchOk( + bypass(`${await s3()}/${bucket}/`, { + method: "PUT", + }), + ); +} + +export async function writeObject( + s3: Fixture, + bucket: string, + path: string, + body: RequestInit["body"], +) { + await fetchOk( + bypass(`${await s3()}/${bucket}/${encodeURIComponent(path)}`, { + method: "PUT", + body: body, + }), + ); +} diff --git a/tests/fixtures/fixture.ts b/tests/fixtures/fixture.ts new file mode 100644 index 0000000000..2471c8e91f --- /dev/null +++ b/tests/fixtures/fixture.ts @@ -0,0 +1,54 @@ +/** + * @license + * Copyright 2024 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import "core-js/proposals/explicit-resource-management.js"; +import { beforeAll, afterAll } from "vitest"; + +export interface Fixture { + (): Promise; +} + +export function fixture( + setup: (disposableStack: AsyncDisposableStack) => Promise, +): Fixture { + let setupPromise: Promise | undefined; + const stack = new AsyncDisposableStack(); + + afterAll(async () => { + setupPromise = undefined; + await stack[Symbol.asyncDispose](); + }); + + const asyncGetter = () => { + if (setupPromise === undefined) { + setupPromise = (async () => { + return setup(stack); + })(); + } + return setupPromise; + }; + + beforeAll(async () => { + await asyncGetter(); + }); + + return asyncGetter; +} + +export function constantFixture(value: T): Fixture { + const promise = Promise.resolve(value); + return () => promise; +} diff --git a/tests/fixtures/gl_browser.ts b/tests/fixtures/gl_browser.ts new file mode 100644 index 0000000000..d7f208c42a --- /dev/null +++ b/tests/fixtures/gl_browser.ts @@ -0,0 +1,26 @@ +/** + * @license + * Copyright 2025 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { GL } from "#src/webgl/context.js"; +import { initializeWebGL } from "#src/webgl/context.js"; +import type { Fixture } from "#tests/fixtures/fixture.js"; +import { fixture } from "#tests/fixtures/fixture.js"; + +export function glFixture(): Fixture { + return fixture(async () => { + return initializeWebGL(document.createElement("canvas")); + }); +} diff --git a/tests/fixtures/gl_node.ts b/tests/fixtures/gl_node.ts new file mode 100644 index 0000000000..6da2ff7275 --- /dev/null +++ b/tests/fixtures/gl_node.ts @@ -0,0 +1,27 @@ +/** + * @license + * Copyright 2025 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { RefCounted } from "#src/util/disposable.js"; +import { Memoize } from "#src/util/memoize.js"; +import type { GL } from "#src/webgl/context.js"; +import type { Fixture } from "#tests/fixtures/fixture.js"; +import { fixture } from "#tests/fixtures/fixture.js"; + +export function glFixture(): Fixture { + return fixture(async () => { + return { memoize: new Memoize() } as any; + }); +} diff --git a/tests/fixtures/http_server.ts b/tests/fixtures/http_server.ts new file mode 100644 index 0000000000..800c546838 --- /dev/null +++ b/tests/fixtures/http_server.ts @@ -0,0 +1,50 @@ +/** + * @license + * Copyright 2024 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type * as http from "node:http"; +import type { AddressInfo } from "node:net"; +import { createServer } from "http-server"; +import { fixture, type Fixture } from "#tests/fixtures/fixture.js"; +import { tempDirectoryFixture } from "#tests/fixtures/temp_directory.js"; + +export function httpServerFixture( + rootDirectory: Fixture = tempDirectoryFixture(), +): { serverUrl: Fixture; rootDirectory: Fixture } { + return { + serverUrl: fixture(async (stack) => { + const resolvedRootDirectory = await rootDirectory(); + const server: http.Server = ( + createServer({ + root: resolvedRootDirectory, + cache: -1, + }) as any + ).server; + stack.defer(async () => { + await new Promise((resolve) => server.close(resolve)); + }); + const serverUrl = await new Promise((resolve, reject) => { + server.on("error", reject); + server.listen(0, "localhost", () => { + const port = (server.address() as AddressInfo).port; + resolve(`http://localhost:${port}/`); + }); + }); + console.log(`Serving ${resolvedRootDirectory} at ${serverUrl}`); + return serverUrl; + }), + rootDirectory, + }; +} diff --git a/tests/fixtures/msw_browser.ts b/tests/fixtures/msw_browser.ts new file mode 100644 index 0000000000..a282bbf53f --- /dev/null +++ b/tests/fixtures/msw_browser.ts @@ -0,0 +1,21 @@ +import type { LifeCycleEventsMap, SetupApi } from "msw"; +import { http, passthrough } from "msw"; +import { setupWorker, type SetupWorkerApi } from "msw/browser"; +import { afterEach } from "vitest"; +import type { Fixture } from "#tests/fixtures/fixture.js"; +import { fixture } from "#tests/fixtures/fixture.js"; + +export function mswFixture(): Fixture> { + const mswServer = fixture(async (stack) => { + const server = setupWorker( + http.get("/*", () => passthrough()), + ) as SetupWorkerApi; + stack.defer(() => server.stop()); + await server.start(); + return server; + }); + + afterEach(async () => (await mswServer()).resetHandlers()); + + return mswServer; +} diff --git a/tests/fixtures/msw_node.ts b/tests/fixtures/msw_node.ts new file mode 100644 index 0000000000..a3749e6222 --- /dev/null +++ b/tests/fixtures/msw_node.ts @@ -0,0 +1,18 @@ +import type { LifeCycleEventsMap, SetupApi } from "msw"; +import { setupServer } from "msw/node"; +import { afterEach } from "vitest"; +import type { Fixture } from "#tests/fixtures/fixture.js"; +import { fixture } from "#tests/fixtures/fixture.js"; + +export function mswFixture(): Fixture> { + const mswServer = fixture(async (stack) => { + const server = setupServer(); + stack.defer(() => server.close()); + server.listen(); + return server; + }); + + afterEach(async () => (await mswServer()).resetHandlers()); + + return mswServer; +} diff --git a/tests/fixtures/shared_kvstore_context.ts b/tests/fixtures/shared_kvstore_context.ts new file mode 100644 index 0000000000..7fa6538db0 --- /dev/null +++ b/tests/fixtures/shared_kvstore_context.ts @@ -0,0 +1,50 @@ +/** + * @license + * Copyright 2024 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { getDefaultCredentialsManager } from "#src/credentials_provider/default_manager.js"; +import { SharedCredentialsManager } from "#src/credentials_provider/shared.js"; +import { DataManagementContext } from "#src/data_management_context.js"; +import { SharedKvStoreContext } from "#src/kvstore/frontend.js"; +import type { GL } from "#src/webgl/context.js"; +import { fixture, type Fixture } from "#tests/fixtures/fixture.js"; +import { glFixture } from "#tests/fixtures/gl"; + +export function sharedKvStoreContextFixture( + gl: Fixture = glFixture(), +): Fixture { + return fixture(async (stack) => { + const dataContext = new DataManagementContext( + /*gl=*/ await gl(), + /*frameNumberCounter=*/ undefined as any, + ); + stack.defer(() => dataContext.dispose()); + + const sharedCredentialsManager = dataContext.registerDisposer( + new SharedCredentialsManager( + getDefaultCredentialsManager(), + dataContext.rpc, + ), + ); + + const sharedKvStoreContext = new SharedKvStoreContext( + dataContext.chunkManager, + sharedCredentialsManager, + ); + stack.defer(() => sharedKvStoreContext.dispose()); + + return sharedKvStoreContext; + }); +} diff --git a/tests/fixtures/status_message_observer.ts b/tests/fixtures/status_message_observer.ts new file mode 100644 index 0000000000..78476b70ec --- /dev/null +++ b/tests/fixtures/status_message_observer.ts @@ -0,0 +1,89 @@ +/** + * @license + * Copyright 2024 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { afterEach } from "vitest"; +import type { StatusMessage } from "#src/status.js"; +import { statusMessages, getStatusMessageContainers } from "#src/status.js"; +import type { Fixture } from "#tests/fixtures/fixture.js"; +import { fixture } from "#tests/fixtures/fixture.js"; + +export interface StatusMessageHandler { + (message: StatusMessage): void; +} +export class StatusMessageObserver { + private handlers: Set = new Set(); + private observer: MutationObserver; + constructor() { + this.observer = new MutationObserver(() => { + for (const handler of this.handlers) { + for (const message of statusMessages) { + handler(message); + } + } + }); + for (const element of getStatusMessageContainers()) { + this.observer.observe(element, { + subtree: true, + childList: true, + attributes: true, + characterData: true, + }); + } + } + registerHandler(handler: StatusMessageHandler): Disposable { + const wrappedHandler: StatusMessageHandler = (status) => handler(status); + this.handlers.add(wrappedHandler); + return { + [Symbol.dispose]: () => { + this.handlers.delete(wrappedHandler); + }, + }; + } + async waitForButton(pattern: RegExp): Promise { + const { promise, resolve } = Promise.withResolvers(); + using _handler = this.registerHandler((status) => { + const result = document.evaluate( + `.//button`, + status.element, + null, + XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, + null, + ); + for (let i = 0, length = result.snapshotLength; i < length; ++i) { + const button = result.snapshotItem(i) as HTMLButtonElement; + if ((button.textContent ?? "").match(pattern)) { + resolve(button); + } + } + }); + return await promise; + } + reset() { + this.handlers.clear(); + } + [Symbol.dispose]() { + this.observer.disconnect(); + } +} + +export function statusMessageObserverFixture(): Fixture { + const f = fixture(async () => new StatusMessageObserver()); + afterEach(async () => { + const handler = await f(); + handler.reset(); + }); + return f; +} diff --git a/tests/fixtures/temp_directory.ts b/tests/fixtures/temp_directory.ts new file mode 100644 index 0000000000..248ab191e7 --- /dev/null +++ b/tests/fixtures/temp_directory.ts @@ -0,0 +1,34 @@ +/** + * @license + * Copyright 2024 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Vitest fixture that creates a temporary directory. + +import fs from "node:fs/promises"; +import os from "node:os"; +import path from "node:path"; +import { type Fixture, fixture } from "#tests/fixtures/fixture.js"; + +export function tempDirectoryFixture(prefix: string = ""): Fixture { + return fixture(async (stack) => { + const tempDir = await fs.mkdtemp( + `${os.tmpdir()}${path.sep}neuroglancer-vitest-${prefix}`, + ); + stack.defer(async () => { + await fs.rm(tempDir, { recursive: true, force: true }); + }); + return tempDir; + }); +} diff --git a/tests/kvstore/gcs.spec.ts b/tests/kvstore/gcs.spec.ts new file mode 100644 index 0000000000..5bdfa62fe5 --- /dev/null +++ b/tests/kvstore/gcs.spec.ts @@ -0,0 +1,47 @@ +/** + * @license + * Copyright 2024 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import "#src/kvstore/gcs/register.js"; +import { beforeAll } from "vitest"; +import { + createBucket, + fakeGcsServerFixture, + writeObject, +} from "#tests/fixtures/fake_gcs_server.js"; +import { constantFixture } from "#tests/fixtures/fixture.js"; +import { mswFixture } from "#tests/fixtures/msw"; +import { getTestFiles } from "#tests/kvstore/test_data.js"; +import { testKvStore } from "#tests/kvstore/test_util.js"; + +const msw = mswFixture(); +const fakeGcsServer = fakeGcsServerFixture(msw); + +const BUCKET = "mybucket"; + +beforeAll(async () => { + // Add data to GCS. + await createBucket(fakeGcsServer, BUCKET); + for (const [relativePath, content] of await getTestFiles()) { + await writeObject( + fakeGcsServer, + BUCKET, + relativePath, + new Uint8Array(content), + ); + } +}); + +testKvStore(constantFixture(`gs://${BUCKET}/`)); diff --git a/tests/kvstore/gzip.spec.ts b/tests/kvstore/gzip.spec.ts new file mode 100644 index 0000000000..1f23d1f974 --- /dev/null +++ b/tests/kvstore/gzip.spec.ts @@ -0,0 +1,36 @@ +/** + * @license + * Copyright 2024 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import "#src/kvstore/http/register.js"; +import "#src/kvstore/gzip/register.js"; +import { expect, test } from "vitest"; +import { constantFixture } from "#tests/fixtures/fixture.js"; +import { httpServerFixture } from "#tests/fixtures/http_server.js"; +import { sharedKvStoreContextFixture } from "#tests/fixtures/shared_kvstore_context.js"; +import { TEST_DATA_DIR } from "#tests/kvstore/test_data.js"; + +const serverFixture = httpServerFixture(constantFixture(TEST_DATA_DIR)); +const sharedKvStoreContext = sharedKvStoreContextFixture(); + +test("can read", async () => { + const { response } = await ( + await sharedKvStoreContext() + ).kvStoreContext.read( + `${await serverFixture.serverUrl()}gzip/simple.txt.gz|gzip`, + { throwIfMissing: true }, + ); + expect(await response.text()).toEqual("Hello"); +}); diff --git a/tests/kvstore/http.spec.ts b/tests/kvstore/http.spec.ts new file mode 100644 index 0000000000..9f5d862481 --- /dev/null +++ b/tests/kvstore/http.spec.ts @@ -0,0 +1,25 @@ +/** + * @license + * Copyright 2024 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import "#src/kvstore/http/register.js"; +import { constantFixture } from "#tests/fixtures/fixture.js"; +import { httpServerFixture } from "#tests/fixtures/http_server.js"; +import { TEST_FILES_DIR } from "#tests/kvstore/test_data.js"; +import { testKvStore } from "#tests/kvstore/test_util.js"; + +const serverFixture = httpServerFixture(constantFixture(TEST_FILES_DIR)); + +testKvStore(serverFixture.serverUrl); diff --git a/tests/kvstore/ngauth.browser_test.ts b/tests/kvstore/ngauth.browser_test.ts new file mode 100644 index 0000000000..152250e233 --- /dev/null +++ b/tests/kvstore/ngauth.browser_test.ts @@ -0,0 +1,142 @@ +/** + * @license + * Copyright 2024 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import "#src/kvstore/ngauth/register.js"; +import "#src/kvstore/ngauth/register_credentials_provider.js"; +import { http, passthrough } from "msw"; +import { expect, test, afterEach } from "vitest"; +import { mswFixture } from "#tests/fixtures/msw"; +import { sharedKvStoreContextFixture } from "#tests/fixtures/shared_kvstore_context.js"; +import { statusMessageObserverFixture } from "#tests/fixtures/status_message_observer.js"; +import { clearCookies } from "#tests/util/clear_cookies.js"; +import { mswRequestLog } from "#tests/util/msw_request_log.js"; + +const msw = mswFixture(); + +const statusMessageObserver = statusMessageObserverFixture(); + +declare const FAKE_NGAUTH_SERVER: string; + +const BUCKET = "mybucket"; + +const sharedKvStoreContext = sharedKvStoreContextFixture(); +const sharedKvStoreContext2 = sharedKvStoreContextFixture(); +afterEach(() => { + clearCookies(); +}); + +test("login", async () => { + using requestLog = mswRequestLog(await msw(), { + redact: ["(?<=neuroglancer=)[a-f0-9]+"], + }); + (await msw()).use( + http.get( + `https://storage.googleapis.com/storage/v1/b/mybucket/o/missing`, + async () => { + return new Response(null, { status: 404 }); + }, + ), + http.all(`${FAKE_NGAUTH_SERVER}/*`, () => passthrough()), + ); + { + const readPromise = (await sharedKvStoreContext()).kvStoreContext.read( + `gs+ngauth+${FAKE_NGAUTH_SERVER}/${BUCKET}/missing`, + ); + console.log("Waiting for login"); + const loginButton = await ( + await statusMessageObserver() + ).waitForButton(/\blogin\b/); + console.log("Clicking login"); + loginButton.click(); + console.log("Waiting for read to complete"); + expect(await readPromise).toBe(undefined); + expect.soft(await requestLog.popAll()).toMatchInlineSnapshot(` + [ + { + "request": { + "url": "http://localhost:*/token", + }, + "response": { + "status": 401, + }, + }, + { + "request": { + "body": "{"token":"fake_token","bucket":"mybucket"}", + "url": "http://localhost:*/gcs_token", + }, + "response": { + "body": "{"token":"fake_gcs_token:mybucket"}", + "status": 200, + }, + }, + { + "request": { + "headers": [ + "authorization: Bearer fake_gcs_token:mybucket", + ], + "url": "https://storage.googleapis.com/storage/v1/b/mybucket/o/missing?alt=media&neuroglancer=*", + }, + "response": { + "status": 404, + }, + }, + ] + `); + } + + // Now that cookies has been set, login is not required. + { + const readPromise = (await sharedKvStoreContext2()).kvStoreContext.read( + `gs+ngauth+${FAKE_NGAUTH_SERVER}/${BUCKET}/missing`, + ); + expect(await readPromise).toBe(undefined); + expect(await requestLog.popAll()).toMatchInlineSnapshot(` + [ + { + "request": { + "url": "http://localhost:*/token", + }, + "response": { + "body": "fake_token", + "status": 200, + }, + }, + { + "request": { + "body": "{"token":"fake_token","bucket":"mybucket"}", + "url": "http://localhost:*/gcs_token", + }, + "response": { + "body": "{"token":"fake_gcs_token:mybucket"}", + "status": 200, + }, + }, + { + "request": { + "headers": [ + "authorization: Bearer fake_gcs_token:mybucket", + ], + "url": "https://storage.googleapis.com/storage/v1/b/mybucket/o/missing?alt=media&neuroglancer=*", + }, + "response": { + "status": 404, + }, + }, + ] + `); + } +}); diff --git a/tests/kvstore/s3.spec.ts b/tests/kvstore/s3.spec.ts new file mode 100644 index 0000000000..2f64b292db --- /dev/null +++ b/tests/kvstore/s3.spec.ts @@ -0,0 +1,47 @@ +/** + * @license + * Copyright 2024 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import "#src/kvstore/s3/register.js"; +import { beforeAll } from "vitest"; +import { + createBucket, + fakeS3ServerFixture, + writeObject, +} from "#tests/fixtures/fake_s3_server.js"; +import { constantFixture } from "#tests/fixtures/fixture.js"; +import { mswFixture } from "#tests/fixtures/msw"; +import { getTestFiles } from "#tests/kvstore/test_data.js"; +import { testKvStore } from "#tests/kvstore/test_util.js"; + +const msw = mswFixture(); +const fakeS3Server = fakeS3ServerFixture({ msw }); + +const BUCKET = "mybucket"; + +beforeAll(async () => { + // Add data to S3. + await createBucket(fakeS3Server, BUCKET); + for (const [relativePath, content] of await getTestFiles()) { + await writeObject( + fakeS3Server, + BUCKET, + relativePath, + new Uint8Array(content), + ); + } +}); + +testKvStore(constantFixture(`s3://${BUCKET}/`)); diff --git a/tests/kvstore/test_data.ts b/tests/kvstore/test_data.ts new file mode 100644 index 0000000000..89f87f30e7 --- /dev/null +++ b/tests/kvstore/test_data.ts @@ -0,0 +1,56 @@ +/** + * @license + * Copyright 2024 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import fs from "node:fs/promises"; +import path from "node:path"; + +export const TEST_DATA_DIR = path.join( + import.meta.dirname, + "..", + "..", + "testdata", + "kvstore", +); +export const TEST_FILES_DIR = path.join(TEST_DATA_DIR, "files"); + +export async function findFilesRecursively(rootDir: string): Promise { + const relativePaths: string[] = []; + for (const entry of await fs.readdir(rootDir, { + recursive: true, + withFileTypes: true, + })) { + if (!entry.isFile()) { + continue; + } + const fullPath = path.join(entry.parentPath, entry.name); + const relativePath = path + .relative(rootDir, fullPath) + .replaceAll(path.sep, "/"); + relativePaths.push(relativePath); + } + return relativePaths; +} + +export async function getTestFiles( + rootDir: string = TEST_FILES_DIR, +): Promise> { + const map = new Map(); + for (const relativePath of await findFilesRecursively(rootDir)) { + const content = await fs.readFile(path.join(rootDir, relativePath)); + map.set(relativePath, content); + } + return map; +} diff --git a/tests/kvstore/test_util.ts b/tests/kvstore/test_util.ts new file mode 100644 index 0000000000..14a3cb71a7 --- /dev/null +++ b/tests/kvstore/test_util.ts @@ -0,0 +1,213 @@ +/** + * @license + * Copyright 2024 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { describe, expect, test } from "vitest"; +import type { KvStore } from "#src/kvstore/index.js"; +import { listKvStoreRecursively, readKvStore } from "#src/kvstore/index.js"; +import type { Fixture } from "#tests/fixtures/fixture.js"; +import { sharedKvStoreContextFixture } from "#tests/fixtures/shared_kvstore_context.js"; + +export const sharedKvStoreContext = sharedKvStoreContextFixture(); + +export function testRead(url: Fixture) { + test("read not found", async () => { + expect( + await ( + await sharedKvStoreContext() + ).kvStoreContext.read(`${await url()}missing`), + ).toBe(undefined); + }); + test("read full", async () => { + const response = await ( + await sharedKvStoreContext() + ).kvStoreContext.read(`${await url()}a`); + expect(response).toBeTruthy(); + expect.soft(response!.totalSize).toEqual(3); + expect.soft(response!.offset).toEqual(0); + expect.soft(response!.length).toEqual(3); + expect.soft(await response!.response.text()).toEqual("abc"); + }); + test("read byte range zero length", async () => { + const response = await ( + await sharedKvStoreContext() + ).kvStoreContext.read(`${await url()}a`, { + byteRange: { offset: 1, length: 0 }, + }); + expect(response).toBeTruthy(); + expect.soft(response!.totalSize).toEqual(3); + expect.soft(response!.offset).toEqual(1); + expect.soft(response!.length).toEqual(0); + expect.soft(await response!.response.text()).toEqual(""); + }); + test("read byte range zero length empty file", async () => { + const response = await ( + await sharedKvStoreContext() + ).kvStoreContext.read(`${await url()}empty`, { + byteRange: { offset: 0, length: 0 }, + }); + expect(response).toBeTruthy(); + expect.soft(response!.totalSize).toEqual(0); + expect.soft(response!.offset).toEqual(0); + expect.soft(response!.length).toEqual(0); + expect.soft(await response!.response.text()).toEqual(""); + }); + test("read byte range offset+length", async () => { + const response = await ( + await sharedKvStoreContext() + ).kvStoreContext.read(`${await url()}a`, { + byteRange: { offset: 1, length: 1 }, + }); + expect(response).toBeTruthy(); + expect.soft(response!.totalSize).toEqual(3); + expect.soft(response!.offset).toEqual(1); + expect.soft(response!.length).toEqual(1); + expect.soft(await response!.response.text()).toEqual("b"); + }); + test("read byte range suffixLength", async () => { + const response = await ( + await sharedKvStoreContext() + ).kvStoreContext.read(`${await url()}a`, { + byteRange: { suffixLength: 1 }, + }); + expect(response).toBeTruthy(); + expect.soft(response!.totalSize).toEqual(3); + expect.soft(response!.offset).toEqual(2); + expect.soft(response!.length).toEqual(1); + expect.soft(await response!.response.text()).toEqual("c"); + }); + test("read byte range suffixLength=0", async () => { + const response = await ( + await sharedKvStoreContext() + ).kvStoreContext.read(`${await url()}a`, { + byteRange: { suffixLength: 0 }, + }); + expect(response).toBeTruthy(); + expect.soft(response!.totalSize).toEqual(3); + expect.soft(response!.offset).toEqual(3); + expect.soft(response!.length).toEqual(0); + expect.soft(await response!.response.text()).toEqual(""); + }); + test("stat on directory returns not found", async () => { + const response = await ( + await sharedKvStoreContext() + ).kvStoreContext.stat(`${await url()}baz`); + expect(response).toEqual(undefined); + }); + test("read on directory returns not found", async () => { + const response = await ( + await sharedKvStoreContext() + ).kvStoreContext.read(`${await url()}baz`); + expect(response).toEqual(undefined); + }); +} + +export function testList(url: Fixture) { + test("list with empty prefix", async () => { + expect( + await ( + await sharedKvStoreContext() + ).kvStoreContext.list(await url(), { + responseKeys: "suffix", + }), + ).toMatchInlineSnapshot(` + { + "directories": [ + "baz", + ], + "entries": [ + { + "key": "#", + }, + { + "key": "a", + }, + { + "key": "b", + }, + { + "key": "c", + }, + { + "key": "empty", + }, + ], + } + `); + }); + + test("list with file prefix", async () => { + expect( + await ( + await sharedKvStoreContext() + ).kvStoreContext.list(`${await url()}e`, { + responseKeys: "suffix", + }), + ).toMatchInlineSnapshot(` + { + "directories": [], + "entries": [ + { + "key": "mpty", + }, + ], + } + `); + }); + + test("list with directory prefix", async () => { + expect( + await ( + await sharedKvStoreContext() + ).kvStoreContext.list(`${await url()}baz/`, { + responseKeys: "suffix", + }), + ).toMatchInlineSnapshot(` + { + "directories": [], + "entries": [ + { + "key": "x", + }, + ], + } + `); + }); +} + +export function testKvStore(url: Fixture) { + describe("kvstore", () => { + testRead(url); + testList(url); + }); +} + +export async function readAllFromKvStore( + kvStore: KvStore, + prefix: string, +): Promise> { + const keys = await listKvStoreRecursively(kvStore, prefix, { + responseKeys: "suffix", + }); + const values = await Promise.all( + keys.map(async ({ key }) => { + const readResponse = await readKvStore(kvStore, prefix + key, { + throwIfMissing: true, + }); + return Buffer.from(await readResponse.response.arrayBuffer()); + }), + ); + return new Map(Array.from(keys, ({ key }, i) => [key, values[i]])); +} diff --git a/tests/kvstore/url.spec.ts b/tests/kvstore/url.spec.ts new file mode 100644 index 0000000000..1c4ad25fe8 --- /dev/null +++ b/tests/kvstore/url.spec.ts @@ -0,0 +1,205 @@ +/** + * @license + * Copyright 2024 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { describe, expect, test } from "vitest"; +import { + finalPipelineUrlComponent, + kvstoreEnsureDirectoryPipelineUrl, + parsePipelineUrlComponent, + parseUrlSuffix, + pipelineUrlJoin, + resolveRelativePath, +} from "#src/kvstore/url.js"; + +describe("kvstoreEnsureDirectoryPipelineUrl", () => { + test("single pipeline component", () => { + expect(kvstoreEnsureDirectoryPipelineUrl("http://foo")).toEqual( + "http://foo/", + ); + expect(kvstoreEnsureDirectoryPipelineUrl("http://foo/")).toEqual( + "http://foo/", + ); + }); + + test("with query parameters", () => { + expect(kvstoreEnsureDirectoryPipelineUrl("http://foo?a=b")).toEqual( + "http://foo/?a=b", + ); + }); + + test("with fragment parameters", () => { + expect(kvstoreEnsureDirectoryPipelineUrl("http://foo#a=b")).toEqual( + "http://foo/#a=b", + ); + }); + + test("multiple pipeline component", () => { + expect(kvstoreEnsureDirectoryPipelineUrl("http://foo|zarr")).toEqual( + "http://foo|zarr:", + ); + expect(kvstoreEnsureDirectoryPipelineUrl("http://foo|zarr:")).toEqual( + "http://foo|zarr:", + ); + }); + + test("s3", () => { + expect(kvstoreEnsureDirectoryPipelineUrl("s3://bucket/path")).toEqual( + "s3://bucket/path/", + ); + }); +}); + +describe("pipelineUrlJoin", () => { + test("simple", () => { + expect(pipelineUrlJoin("gs://foo", "a", "b")).toEqual("gs://foo/a/b"); + }); + test("query parameter", () => { + expect(pipelineUrlJoin("gs://foo?a=b", "a", "b")).toEqual( + "gs://foo/a/b?a=b", + ); + expect(pipelineUrlJoin("gs://foo?a=b|zarr", "a", "b")).toEqual( + "gs://foo?a=b|zarr:a/b", + ); + }); +}); + +describe("finalPipelineUrlComponent", () => { + test("single component", () => { + expect(finalPipelineUrlComponent("")).toEqual(""); + expect(finalPipelineUrlComponent("gs://a")).toEqual("gs://a"); + }); + test("multiple components", () => { + expect(finalPipelineUrlComponent("gs://a|zarr")).toEqual("zarr"); + expect(finalPipelineUrlComponent("gs://a|zip:foo|zarr:")).toEqual("zarr:"); + }); +}); + +describe("parsePipelineUrlComponent", () => { + test("scheme only", () => { + expect(parsePipelineUrlComponent("zarr")).toEqual({ + scheme: "zarr", + suffix: undefined, + url: "zarr", + }); + }); + test("empty suffix", () => { + expect(parsePipelineUrlComponent("zarr:")).toEqual({ + scheme: "zarr", + suffix: "", + url: "zarr:", + }); + }); +}); + +describe("parseUrlSuffix", () => { + test("no suffix", () => { + expect(parseUrlSuffix(undefined)).toMatchInlineSnapshot(` + { + "authorityAndPath": undefined, + "fragment": undefined, + "query": undefined, + } + `); + }); + test("empty suffix", () => { + expect(parseUrlSuffix("")).toMatchInlineSnapshot(` + { + "authorityAndPath": "", + "fragment": undefined, + "query": undefined, + } + `); + }); + test("path only", () => { + expect(parseUrlSuffix("a/b/")).toMatchInlineSnapshot(` + { + "authorityAndPath": "a/b/", + "fragment": undefined, + "query": undefined, + } + `); + }); + test("query only", () => { + expect(parseUrlSuffix("?query")).toMatchInlineSnapshot(` + { + "authorityAndPath": "", + "fragment": undefined, + "query": "query", + } + `); + }); + test("fragment only", () => { + expect(parseUrlSuffix("#fragment")).toMatchInlineSnapshot(` + { + "authorityAndPath": "", + "fragment": "fragment", + "query": undefined, + } + `); + }); + test("path and query", () => { + expect(parseUrlSuffix("//host/path?query")).toMatchInlineSnapshot(` + { + "authorityAndPath": "//host/path", + "fragment": undefined, + "query": "query", + } + `); + }); + test("path and fragment", () => { + expect(parseUrlSuffix("//host/path#fragment")).toMatchInlineSnapshot(` + { + "authorityAndPath": "//host/path", + "fragment": "fragment", + "query": undefined, + } + `); + }); + test("path and query and fragment", () => { + expect(parseUrlSuffix("//host/path?query#fragment")).toMatchInlineSnapshot(` + { + "authorityAndPath": "//host/path", + "fragment": "fragment", + "query": "query", + } + `); + }); + test("path and fragment with fake query", () => { + expect(parseUrlSuffix("//host/path#fragment?query")).toMatchInlineSnapshot(` + { + "authorityAndPath": "//host/path", + "fragment": "fragment?query", + "query": undefined, + } + `); + }); +}); + +describe("resolveRelativePath", () => { + test("empty base", () => { + expect(resolveRelativePath("", "a")).toEqual("a"); + expect(resolveRelativePath("", "a/")).toEqual("a/"); + expect(resolveRelativePath("", "")).toEqual(""); + expect(() => resolveRelativePath("", "..")).toThrowError( + /Invalid relative path/, + ); + }); + + test("non empty base", () => { + expect(resolveRelativePath("base/b", "../c")).toEqual("base/c"); + expect(resolveRelativePath("base/b", "../c/")).toEqual("base/c/"); + }); +}); diff --git a/tests/kvstore/zip.spec.ts b/tests/kvstore/zip.spec.ts new file mode 100644 index 0000000000..640cf06398 --- /dev/null +++ b/tests/kvstore/zip.spec.ts @@ -0,0 +1,177 @@ +/** + * @license + * Copyright 2025 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import "#src/kvstore/http/register.js"; +import "#src/kvstore/zip/register_backend.js"; +import "#src/kvstore/zip/register_frontend.js"; +import fs from "node:fs/promises"; +import path from "node:path"; +import { describe, expect, test } from "vitest"; +import yauzl from "yauzl"; +import { getKvStoreCompletions } from "#src/datasource/kvstore_completions.js"; +import { constantFixture } from "#tests/fixtures/fixture.js"; +import { httpServerFixture } from "#tests/fixtures/http_server.js"; +import { TEST_DATA_DIR } from "#tests/kvstore/test_data.js"; +import { + testKvStore, + sharedKvStoreContext, + readAllFromKvStore, +} from "#tests/kvstore/test_util.js"; + +const serverFixture = httpServerFixture(constantFixture(TEST_DATA_DIR)); + +function readAllUsingYauzl(zipPath: string) { + return new Promise((resolve, reject) => { + const map = new Map(); + yauzl.open(zipPath, { lazyEntries: true }, function (err, zipfile) { + if (err) { + reject(err); + return; + } + zipfile.on("entry", async (entry) => { + if (entry.fileName.endsWith("/")) { + zipfile.readEntry(); + return; + } + zipfile.openReadStream(entry, async (err, readStream) => { + if (err) { + reject(err); + return; + } + const parts: Buffer[] = []; + readStream.on("data", (chunk) => { + parts.push(chunk); + }); + readStream.on("end", () => { + map.set(entry.fileName, Buffer.concat(parts)); + zipfile.readEntry(); + }); + }); + }); + zipfile.on("end", () => { + zipfile.close(); + resolve(map); + }); + zipfile.readEntry(); + }); + }); +} + +describe("yauzl success cases", async () => { + const relativePath = "zip/from-yauzl/success"; + const zipFiles = await fs.readdir(path.join(TEST_DATA_DIR, relativePath)); + test.for(zipFiles)("%s", async (zipFile) => { + const url = + (await serverFixture.serverUrl()) + `${relativePath}/${zipFile}|zip:`; + const { kvStoreContext } = await sharedKvStoreContext(); + const kvStore = kvStoreContext.getKvStore(url); + const contentFromZip = await readAllFromKvStore( + kvStore.store, + kvStore.path, + ); + const expectedFiles = await readAllUsingYauzl( + path.join(TEST_DATA_DIR, relativePath, zipFile), + ); + expect(contentFromZip).toEqual(expectedFiles); + }); +}); + +describe("yauzl failure cases", async () => { + const relativePath = "zip/from-yauzl/failure"; + const zipFiles = await fs.readdir(path.join(TEST_DATA_DIR, relativePath)); + test.for(zipFiles)("%s", async (zipFile) => { + const url = + (await serverFixture.serverUrl()) + `${relativePath}/${zipFile}|zip:`; + const { kvStoreContext } = await sharedKvStoreContext(); + const kvStore = kvStoreContext.getKvStore(url); + const expectedError = new RegExp( + zipFile + .replace(/(_[0-9]+)?\.zip$/, "") + .split(/\s+/) + .join(".*"), + "i", + ); + await expect( + readAllFromKvStore(kvStore.store, kvStore.path).then(() => null), + ).rejects.toThrowError(expectedError); + }); +}); + +testKvStore( + async () => (await serverFixture.serverUrl()) + "zip/files.zip|zip:", +); + +describe("completion", () => { + test("empty prefix", async () => { + const url = (await serverFixture.serverUrl()) + "zip/files.zip|zip:"; + const completions = await getKvStoreCompletions( + await sharedKvStoreContext(), + { + url, + }, + ); + expect(completions).toMatchInlineSnapshot(` + { + "completions": [ + { + "value": "baz/", + }, + { + "value": "%23|", + }, + { + "value": "a|", + }, + { + "value": "b|", + }, + { + "value": "c|", + }, + { + "value": "empty|", + }, + ], + "defaultCompletion": undefined, + "offset": 41, + } + `); + }); + + test("single letter prefix", async () => { + const url = (await serverFixture.serverUrl()) + "zip/files.zip|zip:b"; + const completions = await getKvStoreCompletions( + await sharedKvStoreContext(), + { + url, + }, + ); + expect(completions).toMatchInlineSnapshot(` + { + "completions": [ + { + "value": "baz/", + }, + { + "value": "b|", + }, + ], + "defaultCompletion": undefined, + "offset": 41, + } + `); + }); +}); diff --git a/tests/util/clear_cookies.ts b/tests/util/clear_cookies.ts new file mode 100644 index 0000000000..54ab46b3dd --- /dev/null +++ b/tests/util/clear_cookies.ts @@ -0,0 +1,26 @@ +/** + * @license + * Copyright 2024 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Clears all cookies that are accessible to JavaScript. HTTP-only cookies +// cannot be cleared. +export function clearCookies(): void { + for (const cookie of document.cookie.split(";")) { + document.cookie = cookie + .replace(/^ +/, "") + .replace(/=.*/, `=;expires=${new Date(0).toUTCString()};path=/`); + } + window.localStorage.clear(); +} diff --git a/tests/util/msw_request_log.ts b/tests/util/msw_request_log.ts new file mode 100644 index 0000000000..a8e4982888 --- /dev/null +++ b/tests/util/msw_request_log.ts @@ -0,0 +1,128 @@ +/** + * @license + * Copyright 2024 Google Inc. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { type LifeCycleEventsMap, type SetupApi } from "msw"; + +interface RequestLogEntry { + request: { + url: string; + headers?: string[]; + body?: string; + }; + response: { + status: number; + body?: string; + }; +} + +export function mswRequestLog( + msw: SetupApi, + options: { + redact?: string[]; + } = {}, +) { + const redactPatterns = [ + "(?<=http://localhost:)[0-9]+", + ...(options.redact ?? []), + ]; + const redactRegexp = new RegExp( + redactPatterns.map((s) => `(?:${s})`).join("|"), + "g", + ); + const redact = (s: string) => s.replaceAll(redactRegexp, "*"); + const getHeaders = (headers: Headers): { headers?: string[] } => { + const list: string[] = []; + for (const [name, value] of headers.entries()) { + if (name === "accept" || name === "content-type") { + continue; + } + list.push(redact(`${name}: ${value}`)); + } + if (list.length === 0) return {}; + return { headers: list }; + }; + const getBody = async (r: Request | Response): Promise<{ body?: string }> => { + const body = redact(await r.text()); + if (!body) return {}; + return { body }; + }; + const log: Promise[] = []; + const outstandingRequests = new Map< + string, + { resolve: (value: RequestLogEntry) => void } + >(); + const handler = async ({ + request, + response, + requestId, + }: { + request: Request; + response: Response; + requestId: string; + }) => { + const resolvers = outstandingRequests.get(requestId); + if (resolvers === undefined) return; + outstandingRequests.delete(requestId); + request = request.clone(); + response = response.clone(); + const entry: RequestLogEntry = { + request: { + url: redact(request.url), + ...getHeaders(request.headers), + ...(await getBody(request)), + }, + response: { + status: response.status, + ...(await getBody(response)), + }, + }; + resolvers.resolve(entry); + }; + const requestHandler = ({ + request, + requestId, + }: { + request: Request; + requestId: string; + }) => { + if (new URL(request.url).origin === window.origin) { + return; + } + const { promise, resolve } = Promise.withResolvers(); + outstandingRequests.set(requestId, { resolve }); + log.push(promise); + }; + // request:start event is always sequenced before the `fetch` resolves, but + // `response:*` events sometimes don't. To avoid missing events, log entries + // are added on `response:start` and resolved by the corresponding + // `response:*` event. + msw.events.on("request:start", requestHandler); + msw.events.on("response:mocked", handler); + msw.events.on("response:bypass", handler); + return { + [Symbol.dispose]: () => { + msw.events.removeListener("request:start", requestHandler); + msw.events.removeListener("response:mocked", handler); + msw.events.removeListener("response:bypass", handler); + }, + log, + popAll: () => { + const result = log.slice(); + log.length = 0; + return Promise.all(result); + }, + }; +} diff --git a/tsconfig.json b/tsconfig.json index 7afac1fe53..e2185ad26e 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -18,10 +18,11 @@ "moduleResolution": "bundler", "incremental": true, "resolveJsonModule": true, - "target": "ES2017", + "useDefineForClassFields": true, + "target": "ES2022", "newLine": "LF", "baseUrl": ".", - "lib": ["dom", "webworker", "es2020", "dom.iterable"], + "lib": ["dom", "webworker", "esnext", "dom.iterable"], "typeRoots": [], "module": "ESNext", }, @@ -33,6 +34,5 @@ "testdata", "examples", "config", - "tests", ], } diff --git a/typings/index.d.ts b/typings/index.d.ts index ea8848a6c6..792d3785ed 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -1,5 +1,2 @@ -/// -/// -/// +/// /// -/// diff --git a/typings/html.d.ts b/typings/raw.d.ts similarity index 65% rename from typings/html.d.ts rename to typings/raw.d.ts index 0877141d37..a20ce87840 100644 --- a/typings/html.d.ts +++ b/typings/raw.d.ts @@ -1,4 +1,4 @@ -declare module "*.html" { +declare module "*?raw" { const value: string; export default value; } diff --git a/vitest.workspace.ts b/vitest.workspace.ts index 00f4e15afb..8b489d1ca7 100644 --- a/vitest.workspace.ts +++ b/vitest.workspace.ts @@ -1,29 +1,60 @@ +import path from "node:path"; +import mswPlugin from "@iodigital/vite-plugin-msw"; import { defineWorkspace } from "vitest/config"; +import { getFakeGcsServerBin } from "build_tools/vitest/build_fake_gcs_server.ts"; +import { startFakeNgauthServer } from "./build_tools/vitest/fake_ngauth_server.ts"; +import { startTestDataServer } from "./build_tools/vitest/test_data_server.ts"; + +const fakeNgauthServer = await startFakeNgauthServer(); +const testDataServer = await startTestDataServer( + path.join(import.meta.dirname, "testdata"), +); +const fakeGcsServerBin = await getFakeGcsServerBin(); export default defineWorkspace([ { test: { name: "node", - environment: "node", - setupFiles: ["./build_tools/vitest/setup-crypto.ts"], - include: ["src/**/*.spec.ts"], + environment: "jsdom", + setupFiles: [ + "./build_tools/vitest/polyfill-browser-globals-in-node.ts", + "@vitest/web-worker", + ], + include: ["src/**/*.spec.ts", "tests/**/*.spec.ts"], benchmark: { include: ["src/**/*.benchmark.ts"], }, + testTimeout: 10000, + }, + define: { + FAKE_GCS_SERVER_BIN: JSON.stringify(fakeGcsServerBin), }, }, { + define: { + FAKE_NGAUTH_SERVER: JSON.stringify(fakeNgauthServer.url), + TEST_DATA_SERVER: JSON.stringify(testDataServer.url), + }, + esbuild: { + target: "es2022", + }, + plugins: [mswPlugin({ mode: "browser", handlers: [] })], + optimizeDeps: { + include: ["nifti-reader-js"], + entries: ["src/util/polyfills.ts"], + }, test: { name: "browser", - include: ["src/**/*.browser_test.ts"], + include: ["src/**/*.browser_test.ts", "tests/**/*.browser_test.ts"], benchmark: { include: [], }, browser: { - provider: "webdriverio", + provider: "playwright", enabled: true, headless: true, - name: "chrome", + instances: [{ browser: "chromium" }], + screenshotFailures: false, }, }, },