diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..0043c7c --- /dev/null +++ b/.editorconfig @@ -0,0 +1,8 @@ +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +trim_trailing_whitespace = true +insert_final_newline = true diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..af3ad12 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,4 @@ +/.yarn/** linguist-vendored +/.yarn/releases/* binary +/.yarn/plugins/**/* binary +/.pnp.* binary linguist-generated diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 0000000..d267c2f --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,36 @@ +name: Build and Deploy + +on: + push: + branches: + - main + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: 21 + cache: 'yarn' + + - name: Install dependencies + run: yarn --immutable + + - name: Build + run: yarn build + + - name: Setup pages + uses: actions/configure-pages@v4 + + - name: Upload artifact + uses: actions/upload-pages-artifact@v3 + with: + path: './dist' + + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d62ae06 --- /dev/null +++ b/.gitignore @@ -0,0 +1,17 @@ +.yarn/* +!.yarn/patches +!.yarn/plugins +!.yarn/releases +!.yarn/sdks +!.yarn/versions + +# Swap the comments on the following lines if you wish to use zero-installs +# In that case, don't forget to run `yarn config set enableGlobalCache false`! +# Documentation here: https://yarnpkg.com/features/caching#zero-installs + +#!.yarn/cache +.pnp.* + +.parcel-cache + +dist diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..544138b --- /dev/null +++ b/.prettierrc @@ -0,0 +1,3 @@ +{ + "singleQuote": true +} diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..26a5824 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,7 @@ +{ + "recommendations": [ + "bierner.lit-html", + "esbenp.prettier-vscode", + "arcanis.vscode-zipfs" + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..6e47293 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,18 @@ +{ + "editor.formatOnSave": true, + "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.rulers": [ + 80, + 120 + ], + "emmet.includeLanguages": { + "javascript": "html" + }, + "search.exclude": { + "**/.yarn": true, + "**/.pnp.*": true + }, + "prettier.prettierPath": ".yarn/sdks/prettier/index.cjs", + "typescript.tsdk": ".yarn/sdks/typescript/lib", + "typescript.enablePromptUseWorkspaceTsdk": true +} diff --git a/.yarn/sdks/integrations.yml b/.yarn/sdks/integrations.yml new file mode 100644 index 0000000..aa9d0d0 --- /dev/null +++ b/.yarn/sdks/integrations.yml @@ -0,0 +1,5 @@ +# This file is automatically generated by @yarnpkg/sdks. +# Manual changes might be lost! + +integrations: + - vscode diff --git a/.yarn/sdks/prettier/bin/prettier.cjs b/.yarn/sdks/prettier/bin/prettier.cjs new file mode 100644 index 0000000..5efad68 --- /dev/null +++ b/.yarn/sdks/prettier/bin/prettier.cjs @@ -0,0 +1,20 @@ +#!/usr/bin/env node + +const {existsSync} = require(`fs`); +const {createRequire} = require(`module`); +const {resolve} = require(`path`); + +const relPnpApiPath = "../../../../.pnp.cjs"; + +const absPnpApiPath = resolve(__dirname, relPnpApiPath); +const absRequire = createRequire(absPnpApiPath); + +if (existsSync(absPnpApiPath)) { + if (!process.versions.pnp) { + // Setup the environment to be able to require prettier/bin/prettier.cjs + require(absPnpApiPath).setup(); + } +} + +// Defer to the real prettier/bin/prettier.cjs your application uses +module.exports = absRequire(`prettier/bin/prettier.cjs`); diff --git a/.yarn/sdks/prettier/index.cjs b/.yarn/sdks/prettier/index.cjs new file mode 100644 index 0000000..8758e36 --- /dev/null +++ b/.yarn/sdks/prettier/index.cjs @@ -0,0 +1,20 @@ +#!/usr/bin/env node + +const {existsSync} = require(`fs`); +const {createRequire} = require(`module`); +const {resolve} = require(`path`); + +const relPnpApiPath = "../../../.pnp.cjs"; + +const absPnpApiPath = resolve(__dirname, relPnpApiPath); +const absRequire = createRequire(absPnpApiPath); + +if (existsSync(absPnpApiPath)) { + if (!process.versions.pnp) { + // Setup the environment to be able to require prettier + require(absPnpApiPath).setup(); + } +} + +// Defer to the real prettier your application uses +module.exports = absRequire(`prettier`); diff --git a/.yarn/sdks/prettier/package.json b/.yarn/sdks/prettier/package.json new file mode 100644 index 0000000..e6c621d --- /dev/null +++ b/.yarn/sdks/prettier/package.json @@ -0,0 +1,7 @@ +{ + "name": "prettier", + "version": "3.2.4-sdk", + "main": "./index.cjs", + "type": "commonjs", + "bin": "./bin/prettier.cjs" +} diff --git a/.yarn/sdks/typescript/bin/tsc b/.yarn/sdks/typescript/bin/tsc new file mode 100644 index 0000000..454b950 --- /dev/null +++ b/.yarn/sdks/typescript/bin/tsc @@ -0,0 +1,20 @@ +#!/usr/bin/env node + +const {existsSync} = require(`fs`); +const {createRequire} = require(`module`); +const {resolve} = require(`path`); + +const relPnpApiPath = "../../../../.pnp.cjs"; + +const absPnpApiPath = resolve(__dirname, relPnpApiPath); +const absRequire = createRequire(absPnpApiPath); + +if (existsSync(absPnpApiPath)) { + if (!process.versions.pnp) { + // Setup the environment to be able to require typescript/bin/tsc + require(absPnpApiPath).setup(); + } +} + +// Defer to the real typescript/bin/tsc your application uses +module.exports = absRequire(`typescript/bin/tsc`); diff --git a/.yarn/sdks/typescript/bin/tsserver b/.yarn/sdks/typescript/bin/tsserver new file mode 100644 index 0000000..d7a6056 --- /dev/null +++ b/.yarn/sdks/typescript/bin/tsserver @@ -0,0 +1,20 @@ +#!/usr/bin/env node + +const {existsSync} = require(`fs`); +const {createRequire} = require(`module`); +const {resolve} = require(`path`); + +const relPnpApiPath = "../../../../.pnp.cjs"; + +const absPnpApiPath = resolve(__dirname, relPnpApiPath); +const absRequire = createRequire(absPnpApiPath); + +if (existsSync(absPnpApiPath)) { + if (!process.versions.pnp) { + // Setup the environment to be able to require typescript/bin/tsserver + require(absPnpApiPath).setup(); + } +} + +// Defer to the real typescript/bin/tsserver your application uses +module.exports = absRequire(`typescript/bin/tsserver`); diff --git a/.yarn/sdks/typescript/lib/tsc.js b/.yarn/sdks/typescript/lib/tsc.js new file mode 100644 index 0000000..2f62fc9 --- /dev/null +++ b/.yarn/sdks/typescript/lib/tsc.js @@ -0,0 +1,20 @@ +#!/usr/bin/env node + +const {existsSync} = require(`fs`); +const {createRequire} = require(`module`); +const {resolve} = require(`path`); + +const relPnpApiPath = "../../../../.pnp.cjs"; + +const absPnpApiPath = resolve(__dirname, relPnpApiPath); +const absRequire = createRequire(absPnpApiPath); + +if (existsSync(absPnpApiPath)) { + if (!process.versions.pnp) { + // Setup the environment to be able to require typescript/lib/tsc.js + require(absPnpApiPath).setup(); + } +} + +// Defer to the real typescript/lib/tsc.js your application uses +module.exports = absRequire(`typescript/lib/tsc.js`); diff --git a/.yarn/sdks/typescript/lib/tsserver.js b/.yarn/sdks/typescript/lib/tsserver.js new file mode 100644 index 0000000..bbb1e46 --- /dev/null +++ b/.yarn/sdks/typescript/lib/tsserver.js @@ -0,0 +1,225 @@ +#!/usr/bin/env node + +const {existsSync} = require(`fs`); +const {createRequire} = require(`module`); +const {resolve} = require(`path`); + +const relPnpApiPath = "../../../../.pnp.cjs"; + +const absPnpApiPath = resolve(__dirname, relPnpApiPath); +const absRequire = createRequire(absPnpApiPath); + +const moduleWrapper = tsserver => { + if (!process.versions.pnp) { + return tsserver; + } + + const {isAbsolute} = require(`path`); + const pnpApi = require(`pnpapi`); + + const isVirtual = str => str.match(/\/(\$\$virtual|__virtual__)\//); + const isPortal = str => str.startsWith("portal:/"); + const normalize = str => str.replace(/\\/g, `/`).replace(/^\/?/, `/`); + + const dependencyTreeRoots = new Set(pnpApi.getDependencyTreeRoots().map(locator => { + return `${locator.name}@${locator.reference}`; + })); + + // VSCode sends the zip paths to TS using the "zip://" prefix, that TS + // doesn't understand. This layer makes sure to remove the protocol + // before forwarding it to TS, and to add it back on all returned paths. + + function toEditorPath(str) { + // We add the `zip:` prefix to both `.zip/` paths and virtual paths + if (isAbsolute(str) && !str.match(/^\^?(zip:|\/zip\/)/) && (str.match(/\.zip\//) || isVirtual(str))) { + // We also take the opportunity to turn virtual paths into physical ones; + // this makes it much easier to work with workspaces that list peer + // dependencies, since otherwise Ctrl+Click would bring us to the virtual + // file instances instead of the real ones. + // + // We only do this to modules owned by the the dependency tree roots. + // This avoids breaking the resolution when jumping inside a vendor + // with peer dep (otherwise jumping into react-dom would show resolution + // errors on react). + // + const resolved = isVirtual(str) ? pnpApi.resolveVirtual(str) : str; + if (resolved) { + const locator = pnpApi.findPackageLocator(resolved); + if (locator && (dependencyTreeRoots.has(`${locator.name}@${locator.reference}`) || isPortal(locator.reference))) { + str = resolved; + } + } + + str = normalize(str); + + if (str.match(/\.zip\//)) { + switch (hostInfo) { + // Absolute VSCode `Uri.fsPath`s need to start with a slash. + // VSCode only adds it automatically for supported schemes, + // so we have to do it manually for the `zip` scheme. + // The path needs to start with a caret otherwise VSCode doesn't handle the protocol + // + // Ref: https://github.com/microsoft/vscode/issues/105014#issuecomment-686760910 + // + // 2021-10-08: VSCode changed the format in 1.61. + // Before | ^zip:/c:/foo/bar.zip/package.json + // After | ^/zip//c:/foo/bar.zip/package.json + // + // 2022-04-06: VSCode changed the format in 1.66. + // Before | ^/zip//c:/foo/bar.zip/package.json + // After | ^/zip/c:/foo/bar.zip/package.json + // + // 2022-05-06: VSCode changed the format in 1.68 + // Before | ^/zip/c:/foo/bar.zip/package.json + // After | ^/zip//c:/foo/bar.zip/package.json + // + case `vscode <1.61`: { + str = `^zip:${str}`; + } break; + + case `vscode <1.66`: { + str = `^/zip/${str}`; + } break; + + case `vscode <1.68`: { + str = `^/zip${str}`; + } break; + + case `vscode`: { + str = `^/zip/${str}`; + } break; + + // To make "go to definition" work, + // We have to resolve the actual file system path from virtual path + // and convert scheme to supported by [vim-rzip](https://github.com/lbrayner/vim-rzip) + case `coc-nvim`: { + str = normalize(resolved).replace(/\.zip\//, `.zip::`); + str = resolve(`zipfile:${str}`); + } break; + + // Support neovim native LSP and [typescript-language-server](https://github.com/theia-ide/typescript-language-server) + // We have to resolve the actual file system path from virtual path, + // everything else is up to neovim + case `neovim`: { + str = normalize(resolved).replace(/\.zip\//, `.zip::`); + str = `zipfile://${str}`; + } break; + + default: { + str = `zip:${str}`; + } break; + } + } else { + str = str.replace(/^\/?/, process.platform === `win32` ? `` : `/`); + } + } + + return str; + } + + function fromEditorPath(str) { + switch (hostInfo) { + case `coc-nvim`: { + str = str.replace(/\.zip::/, `.zip/`); + // The path for coc-nvim is in format of //zipfile://.yarn/... + // So in order to convert it back, we use .* to match all the thing + // before `zipfile:` + return process.platform === `win32` + ? str.replace(/^.*zipfile:\//, ``) + : str.replace(/^.*zipfile:/, ``); + } break; + + case `neovim`: { + str = str.replace(/\.zip::/, `.zip/`); + // The path for neovim is in format of zipfile:////.yarn/... + return str.replace(/^zipfile:\/\//, ``); + } break; + + case `vscode`: + default: { + return str.replace(/^\^?(zip:|\/zip(\/ts-nul-authority)?)\/+/, process.platform === `win32` ? `` : `/`) + } break; + } + } + + // Force enable 'allowLocalPluginLoads' + // TypeScript tries to resolve plugins using a path relative to itself + // which doesn't work when using the global cache + // https://github.com/microsoft/TypeScript/blob/1b57a0395e0bff191581c9606aab92832001de62/src/server/project.ts#L2238 + // VSCode doesn't want to enable 'allowLocalPluginLoads' due to security concerns but + // TypeScript already does local loads and if this code is running the user trusts the workspace + // https://github.com/microsoft/vscode/issues/45856 + const ConfiguredProject = tsserver.server.ConfiguredProject; + const {enablePluginsWithOptions: originalEnablePluginsWithOptions} = ConfiguredProject.prototype; + ConfiguredProject.prototype.enablePluginsWithOptions = function() { + this.projectService.allowLocalPluginLoads = true; + return originalEnablePluginsWithOptions.apply(this, arguments); + }; + + // And here is the point where we hijack the VSCode <-> TS communications + // by adding ourselves in the middle. We locate everything that looks + // like an absolute path of ours and normalize it. + + const Session = tsserver.server.Session; + const {onMessage: originalOnMessage, send: originalSend} = Session.prototype; + let hostInfo = `unknown`; + + Object.assign(Session.prototype, { + onMessage(/** @type {string | object} */ message) { + const isStringMessage = typeof message === 'string'; + const parsedMessage = isStringMessage ? JSON.parse(message) : message; + + if ( + parsedMessage != null && + typeof parsedMessage === `object` && + parsedMessage.arguments && + typeof parsedMessage.arguments.hostInfo === `string` + ) { + hostInfo = parsedMessage.arguments.hostInfo; + if (hostInfo === `vscode` && process.env.VSCODE_IPC_HOOK) { + const [, major, minor] = (process.env.VSCODE_IPC_HOOK.match( + // The RegExp from https://semver.org/ but without the caret at the start + /(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/ + ) ?? []).map(Number) + + if (major === 1) { + if (minor < 61) { + hostInfo += ` <1.61`; + } else if (minor < 66) { + hostInfo += ` <1.66`; + } else if (minor < 68) { + hostInfo += ` <1.68`; + } + } + } + } + + const processedMessageJSON = JSON.stringify(parsedMessage, (key, value) => { + return typeof value === 'string' ? fromEditorPath(value) : value; + }); + + return originalOnMessage.call( + this, + isStringMessage ? processedMessageJSON : JSON.parse(processedMessageJSON) + ); + }, + + send(/** @type {any} */ msg) { + return originalSend.call(this, JSON.parse(JSON.stringify(msg, (key, value) => { + return typeof value === `string` ? toEditorPath(value) : value; + }))); + } + }); + + return tsserver; +}; + +if (existsSync(absPnpApiPath)) { + if (!process.versions.pnp) { + // Setup the environment to be able to require typescript/lib/tsserver.js + require(absPnpApiPath).setup(); + } +} + +// Defer to the real typescript/lib/tsserver.js your application uses +module.exports = moduleWrapper(absRequire(`typescript/lib/tsserver.js`)); diff --git a/.yarn/sdks/typescript/lib/tsserverlibrary.js b/.yarn/sdks/typescript/lib/tsserverlibrary.js new file mode 100644 index 0000000..a68f028 --- /dev/null +++ b/.yarn/sdks/typescript/lib/tsserverlibrary.js @@ -0,0 +1,225 @@ +#!/usr/bin/env node + +const {existsSync} = require(`fs`); +const {createRequire} = require(`module`); +const {resolve} = require(`path`); + +const relPnpApiPath = "../../../../.pnp.cjs"; + +const absPnpApiPath = resolve(__dirname, relPnpApiPath); +const absRequire = createRequire(absPnpApiPath); + +const moduleWrapper = tsserver => { + if (!process.versions.pnp) { + return tsserver; + } + + const {isAbsolute} = require(`path`); + const pnpApi = require(`pnpapi`); + + const isVirtual = str => str.match(/\/(\$\$virtual|__virtual__)\//); + const isPortal = str => str.startsWith("portal:/"); + const normalize = str => str.replace(/\\/g, `/`).replace(/^\/?/, `/`); + + const dependencyTreeRoots = new Set(pnpApi.getDependencyTreeRoots().map(locator => { + return `${locator.name}@${locator.reference}`; + })); + + // VSCode sends the zip paths to TS using the "zip://" prefix, that TS + // doesn't understand. This layer makes sure to remove the protocol + // before forwarding it to TS, and to add it back on all returned paths. + + function toEditorPath(str) { + // We add the `zip:` prefix to both `.zip/` paths and virtual paths + if (isAbsolute(str) && !str.match(/^\^?(zip:|\/zip\/)/) && (str.match(/\.zip\//) || isVirtual(str))) { + // We also take the opportunity to turn virtual paths into physical ones; + // this makes it much easier to work with workspaces that list peer + // dependencies, since otherwise Ctrl+Click would bring us to the virtual + // file instances instead of the real ones. + // + // We only do this to modules owned by the the dependency tree roots. + // This avoids breaking the resolution when jumping inside a vendor + // with peer dep (otherwise jumping into react-dom would show resolution + // errors on react). + // + const resolved = isVirtual(str) ? pnpApi.resolveVirtual(str) : str; + if (resolved) { + const locator = pnpApi.findPackageLocator(resolved); + if (locator && (dependencyTreeRoots.has(`${locator.name}@${locator.reference}`) || isPortal(locator.reference))) { + str = resolved; + } + } + + str = normalize(str); + + if (str.match(/\.zip\//)) { + switch (hostInfo) { + // Absolute VSCode `Uri.fsPath`s need to start with a slash. + // VSCode only adds it automatically for supported schemes, + // so we have to do it manually for the `zip` scheme. + // The path needs to start with a caret otherwise VSCode doesn't handle the protocol + // + // Ref: https://github.com/microsoft/vscode/issues/105014#issuecomment-686760910 + // + // 2021-10-08: VSCode changed the format in 1.61. + // Before | ^zip:/c:/foo/bar.zip/package.json + // After | ^/zip//c:/foo/bar.zip/package.json + // + // 2022-04-06: VSCode changed the format in 1.66. + // Before | ^/zip//c:/foo/bar.zip/package.json + // After | ^/zip/c:/foo/bar.zip/package.json + // + // 2022-05-06: VSCode changed the format in 1.68 + // Before | ^/zip/c:/foo/bar.zip/package.json + // After | ^/zip//c:/foo/bar.zip/package.json + // + case `vscode <1.61`: { + str = `^zip:${str}`; + } break; + + case `vscode <1.66`: { + str = `^/zip/${str}`; + } break; + + case `vscode <1.68`: { + str = `^/zip${str}`; + } break; + + case `vscode`: { + str = `^/zip/${str}`; + } break; + + // To make "go to definition" work, + // We have to resolve the actual file system path from virtual path + // and convert scheme to supported by [vim-rzip](https://github.com/lbrayner/vim-rzip) + case `coc-nvim`: { + str = normalize(resolved).replace(/\.zip\//, `.zip::`); + str = resolve(`zipfile:${str}`); + } break; + + // Support neovim native LSP and [typescript-language-server](https://github.com/theia-ide/typescript-language-server) + // We have to resolve the actual file system path from virtual path, + // everything else is up to neovim + case `neovim`: { + str = normalize(resolved).replace(/\.zip\//, `.zip::`); + str = `zipfile://${str}`; + } break; + + default: { + str = `zip:${str}`; + } break; + } + } else { + str = str.replace(/^\/?/, process.platform === `win32` ? `` : `/`); + } + } + + return str; + } + + function fromEditorPath(str) { + switch (hostInfo) { + case `coc-nvim`: { + str = str.replace(/\.zip::/, `.zip/`); + // The path for coc-nvim is in format of //zipfile://.yarn/... + // So in order to convert it back, we use .* to match all the thing + // before `zipfile:` + return process.platform === `win32` + ? str.replace(/^.*zipfile:\//, ``) + : str.replace(/^.*zipfile:/, ``); + } break; + + case `neovim`: { + str = str.replace(/\.zip::/, `.zip/`); + // The path for neovim is in format of zipfile:////.yarn/... + return str.replace(/^zipfile:\/\//, ``); + } break; + + case `vscode`: + default: { + return str.replace(/^\^?(zip:|\/zip(\/ts-nul-authority)?)\/+/, process.platform === `win32` ? `` : `/`) + } break; + } + } + + // Force enable 'allowLocalPluginLoads' + // TypeScript tries to resolve plugins using a path relative to itself + // which doesn't work when using the global cache + // https://github.com/microsoft/TypeScript/blob/1b57a0395e0bff191581c9606aab92832001de62/src/server/project.ts#L2238 + // VSCode doesn't want to enable 'allowLocalPluginLoads' due to security concerns but + // TypeScript already does local loads and if this code is running the user trusts the workspace + // https://github.com/microsoft/vscode/issues/45856 + const ConfiguredProject = tsserver.server.ConfiguredProject; + const {enablePluginsWithOptions: originalEnablePluginsWithOptions} = ConfiguredProject.prototype; + ConfiguredProject.prototype.enablePluginsWithOptions = function() { + this.projectService.allowLocalPluginLoads = true; + return originalEnablePluginsWithOptions.apply(this, arguments); + }; + + // And here is the point where we hijack the VSCode <-> TS communications + // by adding ourselves in the middle. We locate everything that looks + // like an absolute path of ours and normalize it. + + const Session = tsserver.server.Session; + const {onMessage: originalOnMessage, send: originalSend} = Session.prototype; + let hostInfo = `unknown`; + + Object.assign(Session.prototype, { + onMessage(/** @type {string | object} */ message) { + const isStringMessage = typeof message === 'string'; + const parsedMessage = isStringMessage ? JSON.parse(message) : message; + + if ( + parsedMessage != null && + typeof parsedMessage === `object` && + parsedMessage.arguments && + typeof parsedMessage.arguments.hostInfo === `string` + ) { + hostInfo = parsedMessage.arguments.hostInfo; + if (hostInfo === `vscode` && process.env.VSCODE_IPC_HOOK) { + const [, major, minor] = (process.env.VSCODE_IPC_HOOK.match( + // The RegExp from https://semver.org/ but without the caret at the start + /(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/ + ) ?? []).map(Number) + + if (major === 1) { + if (minor < 61) { + hostInfo += ` <1.61`; + } else if (minor < 66) { + hostInfo += ` <1.66`; + } else if (minor < 68) { + hostInfo += ` <1.68`; + } + } + } + } + + const processedMessageJSON = JSON.stringify(parsedMessage, (key, value) => { + return typeof value === 'string' ? fromEditorPath(value) : value; + }); + + return originalOnMessage.call( + this, + isStringMessage ? processedMessageJSON : JSON.parse(processedMessageJSON) + ); + }, + + send(/** @type {any} */ msg) { + return originalSend.call(this, JSON.parse(JSON.stringify(msg, (key, value) => { + return typeof value === `string` ? toEditorPath(value) : value; + }))); + } + }); + + return tsserver; +}; + +if (existsSync(absPnpApiPath)) { + if (!process.versions.pnp) { + // Setup the environment to be able to require typescript/lib/tsserverlibrary.js + require(absPnpApiPath).setup(); + } +} + +// Defer to the real typescript/lib/tsserverlibrary.js your application uses +module.exports = moduleWrapper(absRequire(`typescript/lib/tsserverlibrary.js`)); diff --git a/.yarn/sdks/typescript/lib/typescript.js b/.yarn/sdks/typescript/lib/typescript.js new file mode 100644 index 0000000..b5f4db2 --- /dev/null +++ b/.yarn/sdks/typescript/lib/typescript.js @@ -0,0 +1,20 @@ +#!/usr/bin/env node + +const {existsSync} = require(`fs`); +const {createRequire} = require(`module`); +const {resolve} = require(`path`); + +const relPnpApiPath = "../../../../.pnp.cjs"; + +const absPnpApiPath = resolve(__dirname, relPnpApiPath); +const absRequire = createRequire(absPnpApiPath); + +if (existsSync(absPnpApiPath)) { + if (!process.versions.pnp) { + // Setup the environment to be able to require typescript + require(absPnpApiPath).setup(); + } +} + +// Defer to the real typescript your application uses +module.exports = absRequire(`typescript`); diff --git a/.yarn/sdks/typescript/package.json b/.yarn/sdks/typescript/package.json new file mode 100644 index 0000000..eb7dd74 --- /dev/null +++ b/.yarn/sdks/typescript/package.json @@ -0,0 +1,10 @@ +{ + "name": "typescript", + "version": "5.3.3-sdk", + "main": "./lib/typescript.js", + "type": "commonjs", + "bin": { + "tsc": "./bin/tsc", + "tsserver": "./bin/tsserver" + } +} diff --git a/.yarnrc.yml b/.yarnrc.yml new file mode 100644 index 0000000..e3e87bb --- /dev/null +++ b/.yarnrc.yml @@ -0,0 +1,12 @@ +enableGlobalCache: false + +packageExtensions: + '@parcel/node-resolver-core@*': + dependencies: + '@parcel/core': ^2.11.0 + '@parcel/types@*': + dependencies: + '@parcel/core': ^2.11.0 + '@parcel/fs@*': + dependencies: + '@parcel/core': ^2.11.0 diff --git a/CNAME b/CNAME new file mode 100644 index 0000000..026a2c4 --- /dev/null +++ b/CNAME @@ -0,0 +1 @@ +vis.ordbokapi.org diff --git a/README.md b/README.md new file mode 100644 index 0000000..2d61e66 --- /dev/null +++ b/README.md @@ -0,0 +1,31 @@ +# Ordbok API Vis-klient + +![Prosjektbanner](images/ordbokapi-vis-client-open-graph.png) + +

+ Nettstad • + Prosjektnettstad • + API på GitHub +

+ +## Om + +Vis-klienten er ein graf-basert grafisk brukargrensesnitt for å utforske data frå [Ordbok API](https://ordbokapi.org). Klienten er skriven med vanilje-JS og webkomponentar. + +## Starta prosjektet lokalt + +Berre klon prosjektet og køyr ein lokal webserver i rotmappa, t.d.: + +```bash +python -m http.server # Python 3 + +python -m SimpleHTTPServer # Python 2 + +npx http-server # Node.js (npm) + +yarn dlx http-server # Node.js (Yarn) +``` + +## Lisens + +[ISC](LICENCE) diff --git a/package.json b/package.json new file mode 100644 index 0000000..35d7102 --- /dev/null +++ b/package.json @@ -0,0 +1,27 @@ +{ + "name": "vis-client", + "packageManager": "yarn@4.0.2", + "type": "module", + "dependencies": { + "@pixi/core": "^7.3.3", + "@pixi/display": "^7.3.3", + "d3": "^7.8.5", + "pixi-viewport": "^5.0.2", + "pixi.js": "^7.3.3" + }, + "devDependencies": { + "@parcel/packager-raw-url": "2.11.0", + "@parcel/transformer-inline-string": "2.11.0", + "@parcel/transformer-webmanifest": "2.11.0", + "@types/d3": "^7.4.3", + "parcel": "^2.11.0", + "prettier": "^3.2.4", + "punycode": "^1.4.1", + "typescript": "^5.3.3", + "url": "^0.11.0" + }, + "scripts": { + "start": "parcel static/index.html", + "build": "parcel build static/index.html" + } +} diff --git a/src/components/app-logo.ts b/src/components/app-logo.ts new file mode 100644 index 0000000..74c265f --- /dev/null +++ b/src/components/app-logo.ts @@ -0,0 +1,53 @@ +import appLogo from '../../static/images/ordbokapi-vis-client-logo-in-app.png'; +import { html } from '../utils/index.js'; + +/** + * App logo which is displayed in the top left corner of the viewport. + */ +export class AppLogo extends HTMLElement { + constructor() { + super(); + + this.attachShadow({ mode: 'open' }); + + this.shadowRoot!.innerHTML = html` + + + `; + } +} + +customElements.define('vis-app-logo', AppLogo); diff --git a/src/components/index.ts b/src/components/index.ts new file mode 100644 index 0000000..48d4069 --- /dev/null +++ b/src/components/index.ts @@ -0,0 +1,8 @@ +export * from './app-logo.js'; +export * from './loading-icon.js'; +export * from './search-bar.js'; +export * from './sidebar.js'; +export * from './statusbar.js'; +export * from './tooltip-cue.js'; +export * from './viewport.js'; +export * from './vis-client.js'; diff --git a/src/components/loading-icon.ts b/src/components/loading-icon.ts new file mode 100644 index 0000000..60ad35b --- /dev/null +++ b/src/components/loading-icon.ts @@ -0,0 +1,101 @@ +import { html } from '../utils/html.js'; + +/** + * Loading icon which is displayed when the app is loading data. Built entirely + * with CSS. + */ +export class LoadingIcon extends HTMLElement { + constructor() { + super(); + + this.attachShadow({ mode: 'open' }); + + this.shadowRoot!.innerHTML = html` + +
+
+
+
+
+
+ `; + } +} + +customElements.define('vis-loading-icon', LoadingIcon); diff --git a/src/components/modal-dialog.ts b/src/components/modal-dialog.ts new file mode 100644 index 0000000..66c76e8 --- /dev/null +++ b/src/components/modal-dialog.ts @@ -0,0 +1,200 @@ +import { html } from '../utils/index.js'; +import sharedStyles from 'bundle-text:../../static/shared.css'; + +/** + * Options for initializing a modal dialog. + */ +export interface ModalDialogOptions { + /** + * The title of the dialog. + */ + title: string; + + /** + * Plain text content of the dialog. + */ + textContent?: string; + + /** + * HTML content of the dialog. Overrides `textContent`. + */ + html?: Node | string; + + /** + * The callback function to invoke when the dialog is closed. + */ + onClose?: () => void; +} + +/** + * Modal dialog component, which displays a modal dialog over the rest of the + * application. + */ +export class ModalDialog extends HTMLElement { + /** + * The root element of the component. + */ + #root: HTMLDivElement; + + /** + * The title of the dialog. + */ + #title: string; + + /** + * The content of the dialog. + */ + #content: Node; + + /** + * The close button. + */ + #closeButton: HTMLButtonElement; + + /** + * The callback function to invoke when the dialog is closed. + */ + #onClose?: () => void; + + /** + * Creates a new modal dialog component. + * @param options The options for initializing the dialog. + */ + constructor(options: ModalDialogOptions) { + super(); + + const { title, textContent, html: htmlContent, onClose } = options; + + const htmlToElement = (html: string) => { + const template = document.createElement('template'); + template.innerHTML = html; + return template.content; + }; + + this.#title = title; + this.#content = htmlContent + ? typeof htmlContent === 'string' + ? htmlToElement(htmlContent) + : htmlContent + : textContent + ? document.createTextNode(textContent) + : document.createTextNode(''); + this.#onClose = onClose; + + console.log(this.#content); + + this.attachShadow({ mode: 'open' }); + this.shadowRoot!.innerHTML = html` + +
+
+
${title}
+
+
+ +
+ +
+ `; + + this.#root = this.shadowRoot!.querySelector('#dialog') as HTMLDivElement; + this.#closeButton = this.shadowRoot!.querySelector( + '#close-button', + ) as HTMLButtonElement; + this.#closeButton.addEventListener('click', () => this.close()); + this.shadowRoot!.querySelector('#ok-button')!.addEventListener( + 'click', + () => this.close(), + ); + this.#root.querySelector('#content')!.appendChild(this.#content); + } + + /** + * Shows the dialog. + */ + show() { + this.style.display = 'block'; + } + + /** + * Closes the dialog. + */ + close() { + this.style.display = 'none'; + this.parentNode?.removeChild(this); + this.#onClose?.(); + } +} + +customElements.define('vis-modal-dialog', ModalDialog); diff --git a/src/components/search-bar.ts b/src/components/search-bar.ts new file mode 100644 index 0000000..31c2b71 --- /dev/null +++ b/src/components/search-bar.ts @@ -0,0 +1,549 @@ +import { ApiClient, SearchResults } from '../providers/index.js'; +import { Dictionary } from '../types/dictionary.js'; +import { html } from '../utils/index.js'; +import sharedStyles from 'bundle-text:../../static/shared.css'; +import { LoadingIcon } from './loading-icon.js'; + +/** + * Search bar which allows searching for a specific article from the dictionary. + * Search results are displayed in a tooltip, and clicking on a result will + * close the tooltip and fire a `articleSelected` event. + */ +export class SearchBar extends HTMLElement { + /** + * The root element. + */ + #root: HTMLDivElement; + + /** + * The input element. + */ + #input: HTMLInputElement; + + /** + * The tooltip element. + */ + #tooltip: HTMLDivElement; + + /** + * The tooltip's content element. + */ + #tooltipContent: HTMLDivElement; + + /** + * The loading icon. + */ + #loadingIcon: LoadingIcon; + + /** + * The API client. + */ + #apiClient: ApiClient; + + /** + * The current search query. + */ + #query = ''; + + /** + * The current search results. + */ + #results: SearchResults = { query: '', results: [] }; + + /** + * The current search result index. + */ + #resultIndex = -1; + + /** + * The current search result count. + */ + #resultCount = 0; + + /** + * The current search result count. + */ + get resultCount() { + return this.#resultCount; + } + + /** + * The current search result index. + */ + get resultIndex() { + return this.#resultIndex; + } + + /** + * The current search query. + */ + get query() { + return this.#query; + } + + /** + * The current search query. + */ + set query(value: string) { + this.#query = value; + this.#input.value = value; + this.#updateTooltip(); + } + + /** + * The current search results. + */ + get results() { + return this.#results; + } + + /** + * The current search results. + */ + set results(value: SearchResults) { + this.#results = value; + this.#updateTooltip(); + } + + /** + * The current search result index. + */ + set resultIndex(value: number) { + this.#resultIndex = value; + this.#updateTooltip(); + } + + /** + * The current search result count. + */ + set resultCount(value: number) { + this.#resultCount = value; + this.#updateTooltip(); + } + + /** + * The current search result count. + */ + get apiClient() { + return this.#apiClient; + } + + /** + * The current search result count. + */ + set apiClient(value: ApiClient) { + this.#apiClient = value; + this.#updateTooltip(); + } + + constructor() { + super(); + this.attachShadow({ mode: 'open' }); + this.shadowRoot!.innerHTML = html` + +
+
+ + +
+
+
+
+
+ `; + this.#root = this.shadowRoot!.querySelector('#root') as HTMLDivElement; + this.#input = this.shadowRoot!.querySelector('#input') as HTMLInputElement; + this.#tooltip = this.shadowRoot!.querySelector( + '#tooltip', + ) as HTMLDivElement; + this.#tooltipContent = this.shadowRoot!.querySelector( + '#tooltipContent', + ) as HTMLDivElement; + this.#loadingIcon = this.shadowRoot!.querySelector( + 'vis-loading-icon', + ) as LoadingIcon; + this.#input.addEventListener('input', () => this.#handleInput()); + this.#input.addEventListener('keydown', (event) => + this.#handleKeyDown(event), + ); + this.#input.addEventListener('focus', () => this.#handleFocus()); + this.#input.addEventListener('blur', () => this.#handleBlur()); + this.#tooltip.addEventListener('mousedown', (event) => + event.preventDefault(), + ); + this.#tooltip.addEventListener('click', (event) => + this.#handleClick(event), + ); + this.#tooltip.addEventListener('mouseover', (event) => + this.#handleMouseOver(event), + ); + this.#hideTooltip(); + + this.#apiClient = new ApiClient(); + } + + /** + * Handles input events. + */ + #handleInput() { + this.#query = this.#input.value; + this.#requestSearch(); + } + + /** + * Handles keydown events. + */ + #handleKeyDown(event: KeyboardEvent) { + if (event.key === 'ArrowDown') { + event.preventDefault(); + this.#selectNextResult(); + } else if (event.key === 'ArrowUp') { + event.preventDefault(); + this.#selectPreviousResult(); + } else if (event.key === 'Enter') { + event.preventDefault(); + + if (this.#tooltip.style.display !== 'none') { + this.#selectResult(); + } else { + this.#doSearch(); + } + } + } + + /** + * Handles focus events. + */ + #handleFocus() { + this.#input.select(); + this.#updateTooltip(); + } + + /** + * Handles blur events. + */ + #handleBlur() { + this.#hideTooltip(); + } + + /** + * Handles click events. + */ + #handleClick(event: MouseEvent) { + const target = event.target as HTMLElement; + + const resultElement: HTMLElement | null = target.classList.contains( + 'result', + ) + ? target + : target.closest('.result'); + + if (resultElement) { + const index = Number.parseInt(resultElement.dataset.index!, 10); + this.#selectResult(index); + } + } + + /** + * If the current selected result is not in view, scrolls it into view. + */ + #scrollResultIntoView() { + const results = this.#tooltipContent.querySelectorAll('.result'); + const selected = results[this.#resultIndex] as HTMLElement; + + if (selected) { + const top = selected.offsetTop; + const bottom = top + selected.offsetHeight; + if (top < this.#tooltip.scrollTop) { + this.#tooltip.scrollTop = top; + } else if ( + bottom > + this.#tooltip.scrollTop + this.#tooltip.clientHeight + ) { + this.#tooltip.scrollTop = bottom - this.#tooltip.clientHeight; + } + } + } + + /** + * Selects the next result. + */ + #selectNextResult() { + if (this.#resultIndex < this.#resultCount - 1) { + this.#resultIndex++; + this.#scrollResultIntoView(); + this.#updateTooltip(); + } + } + + /** + * Selects the previous result. + */ + #selectPreviousResult() { + if (this.#resultIndex > 0) { + this.#resultIndex--; + this.#scrollResultIntoView(); + this.#updateTooltip(); + } + } + + /** + * Selects the current result. + */ + #selectResult(index = this.#resultIndex) { + if (index >= 0 && index < this.#resultCount) { + this.#input.value = this.#results.results[index].title; + this.dispatchEvent( + new CustomEvent('articleSelected', { + detail: { + id: this.#results.results[index].id, + dictionary: this.#results.results[index].dictionary, + }, + }), + ); + this.#hideTooltip(); + this.#input.blur(); + } + } + + /** + * Handles mouseover events. + * @param event The mouseover event. + */ + #handleMouseOver(event: MouseEvent) { + // select the result under the mouse + const target = event.target as HTMLElement; + + const resultElement: HTMLElement | null = target.classList.contains( + 'result', + ) + ? target + : target.closest('.result'); + + if (resultElement) { + const index = Number.parseInt(resultElement.dataset.index!, 10); + this.#resultIndex = index; + this.#updateTooltip(); + } + } + + /** + * Updates the tooltip. + */ + #updateTooltip() { + if (this.#query.length === 0 || this.#resultCount === 0) { + this.#hideTooltip(); + return; + } + + // add .selected class to the selected result + const results = this.#tooltipContent.querySelectorAll('.result'); + for (let i = 0; i < results.length; i++) { + const result = results[i]; + if (i === this.#resultIndex) { + result.classList.add('selected'); + } else { + result.classList.remove('selected'); + } + } + } + + /** + * Timeout for debouncing the search. + */ + #updateTooltipTimeout?: number; + + /** + * The current search request ID. + */ + #searchRequestId?: number; + + /** + * Requests a search. + */ + #requestSearch() { + clearTimeout(this.#updateTooltipTimeout); + const searchRequestId = Math.random(); + this.#searchRequestId = searchRequestId; + + this.#updateTooltipTimeout = setTimeout( + () => this.#doSearch(searchRequestId), + 250, + ); + } + + /** + * Performs the search. + * @param searchRequestId The search request ID. Used to ensure that only the + * latest search request prints results. + */ + #doSearch(searchRequestId?: number) { + if (searchRequestId === undefined) { + searchRequestId = Math.random(); + this.#searchRequestId = searchRequestId; + } + + clearTimeout(this.#updateTooltipTimeout); + + this.#loadingIcon.style.display = ''; + + this.#apiClient + .search(this.#query) + .then((results) => { + if (searchRequestId !== this.#searchRequestId) { + return; + } + + this.#results = results; + this.#resultIndex = -1; + this.#resultCount = results.results.length; + this.#tooltipContent.innerHTML = ''; + + for (const [i, result] of results.results.entries()) { + const element = document.createElement('div'); + element.classList.add('result'); + element.dataset.index = i.toString(); + element.innerHTML = html` +
${result.title}
+
+ ${result.id} + (${result.dictionary === Dictionary.Bokmaalsordboka + ? 'BM' + : 'NN'}) +
+ `; + this.#tooltipContent.appendChild(element); + } + + this.#showTooltip(); + }) + .catch((error) => { + console.error(error); + this.#hideTooltip(); + }) + .finally(() => { + this.#loadingIcon.style.display = 'none'; + }); + } + + /** + * Shows the tooltip. + */ + #showTooltip() { + this.#tooltip.style.display = 'block'; + this.#tooltip.scrollTop = 0; + this.#resultIndex = -1; + } + + /** + * Hides the tooltip. + */ + #hideTooltip() { + this.#tooltip.style.display = 'none'; + } + + /** + * Focuses the input element. + */ + focus() { + this.#input.focus(); + } +} + +customElements.define('vis-search-bar', SearchBar); diff --git a/src/components/sidebar.ts b/src/components/sidebar.ts new file mode 100644 index 0000000..871f1cc --- /dev/null +++ b/src/components/sidebar.ts @@ -0,0 +1,308 @@ +import { ApiClient, Article } from '../providers/index.js'; +import { Dictionary } from '../types/dictionary.js'; +import { html, text } from '../utils/index.js'; +import { ModalDialog } from './modal-dialog.js'; +import './loading-icon.js'; + +/** + * Sidebar which shows data about the current selection, such as the word or + * phrase that is selected, and its definitions. + */ +export class Sidebar extends HTMLElement { + /** + * The root element of the component. + */ + #root: HTMLDivElement; + + /** + * The resizing handle element. + */ + #resizer: HTMLDivElement; + + /** + * The loading overlay element. + */ + #loadingOverlay: HTMLDivElement; + + /** + * The API client. + */ + #apiClient: ApiClient; + + /** + * The article that is currently being viewed. + */ + #article?: Article; + + /** + * The article that is currently being viewed. + */ + get article() { + return this.#article; + } + + set article(article: Article | undefined) { + this.#article = article; + this.#render(); + } + + constructor() { + super(); + this.attachShadow({ mode: 'open' }); + this.shadowRoot!.innerHTML = html` + + + +
+ `; + this.#root = this.shadowRoot!.querySelector('#sidebar') as HTMLDivElement; + this.#resizer = this.shadowRoot!.querySelector( + '#resizer', + ) as HTMLDivElement; + this.#loadingOverlay = this.shadowRoot!.querySelector( + '#loading-overlay', + ) as HTMLDivElement; + this.#addResizer(); + this.#render(); + this.#apiClient = new ApiClient(); + } + + #addResizer() { + const minWidth = 100; + const maxWidth = 500; + + let startX: number, startWidth: number; + + this.#resizer.addEventListener('mousedown', (e) => { + startX = e.clientX; + startWidth = this.#root.getBoundingClientRect().width; + + document.addEventListener('mousemove', onMouseMove); + document.addEventListener('mouseup', onMouseUp); + }); + + const onMouseMove = (e: MouseEvent) => { + const diffX = startX - e.clientX; + const newWidth = startWidth + diffX; + + if (newWidth >= minWidth && newWidth <= maxWidth) { + this.style.width = `${newWidth}px`; + } + }; + + const onMouseUp = () => { + document.removeEventListener('mousemove', onMouseMove); + document.removeEventListener('mouseup', onMouseUp); + }; + } + + #render() { + if (this.#article) { + this.#root.innerHTML = html` +

${this.#article.lemmas.map((lemma) => lemma.lemma).join(', ')}

+
    + ${this.#article.definitions.reduce( + (acc, definition) => + acc + + html` +
  1. + ${definition.content.reduce( + (acc, content) => + acc + html`

    ${content.textContent}

    `, + '', + )} + ${definition.examples.length > 0 + ? html` +
      + ${definition.examples.reduce( + (acc, example) => + acc + + html`
    • ${example.textContent}
    • `, + '', + )} +
    + ` + : ''} + ${definition.subDefinitions.length > 0 + ? html` +
      + ${definition.subDefinitions.reduce( + (acc, subDefinition) => + acc + + html` +
    • + ${subDefinition.content.reduce( + (acc, content) => + acc + + html`

      ${content.textContent}

      `, + '', + )} + ${subDefinition.examples.length > 0 + ? html` +
        + ${subDefinition.examples.reduce( + (acc, example) => + acc + + html` +
      • + ${example.textContent} +
      • + `, + '', + )} +
      + ` + : ''} +
    • + `, + '', + )} +
    + ` + : ''} +
  2. + `, + '', + )} +
+ `; + } else { + this.#root.innerHTML = html` Vel ein artikkel for å sjå detaljar. `; + } + } + + /** + * Loads the article for the given word. + */ + async loadArticle(id: number, dictionary: Dictionary) { + this.#loadingOverlay.style.display = ''; + + const [article, errors] = await this.#apiClient.getArticle(id, dictionary); + + this.#loadingOverlay.style.display = 'none'; + + if (errors.length > 0) { + const dialog = new ModalDialog({ + title: '⚠️ Feil', + html: html` +

+ Det oppstod ein feil under lasting av artikkelen. Prøv igjen + seinare. +

+ ${errors.map((error) => html`

${text`${error.message}`}

`)} + `, + }); + document.body.appendChild(dialog); + dialog.show(); + return; + } + + this.#article = article; + this.#render(); + } +} + +customElements.define('vis-sidebar', Sidebar); diff --git a/src/components/statusbar.ts b/src/components/statusbar.ts new file mode 100644 index 0000000..1acb685 --- /dev/null +++ b/src/components/statusbar.ts @@ -0,0 +1,188 @@ +import { html } from '../utils/index.js'; +import sharedStyles from 'bundle-text:../../static/shared.css'; +import './tooltip-cue.js'; + +/** + * Statusbar which provides controls for the viewport, such as zooming and + * centering the viewport. + */ +export class Statusbar extends HTMLElement { + /** + * The root element. + */ + #root: HTMLDivElement; + + /** + * The current zoom level. + */ + #zoomLevel = 100; + + /** + * The current zoom level. + */ + get zoomLevel() { + return this.#zoomLevel; + } + set zoomLevel(value: number) { + this.#zoomLevel = Math.round(value); + this.#updateZoomLabel(); + } + + /** + * The amount to zoom in or out by when the zoom buttons are clicked. + */ + zoomStep = 25; + + /** + * The amount to zoom in or out by when the zoom buttons are clicked while + * holding down the shift key. + */ + shiftZoomStep = 10; + + /** + * The minimum zoom level. + */ + minZoom = 10; + + /** + * The maximum zoom level. + */ + maxZoom = 200; + + constructor() { + super(); + this.attachShadow({ mode: 'open' }); + this.shadowRoot!.innerHTML = html` + +
+ 🔍 + + + + + +
+ +
+ `; + this.#root = this.shadowRoot!.querySelector('#statusbar') as HTMLDivElement; + + ( + this.#root.querySelector('#zoom-out') as HTMLButtonElement + ).addEventListener('click', (event) => this.#zoom('out', event.shiftKey)); + + ( + this.#root.querySelector('#zoom-in') as HTMLButtonElement + ).addEventListener('click', (event) => this.#zoom('in', event.shiftKey)); + + this.#root.querySelector('#center-view')!.addEventListener('click', () => { + this.dispatchEvent(new CustomEvent('center')); + }); + + this.#root + .querySelector('#zoom-label')! + .addEventListener('change', (event: Event) => { + const target = event.target as HTMLInputElement; + const value = Number.parseInt(target.value, 10); + if (isNaN(value)) { + target.value = `${this.zoomLevel}%`; + return; + } + this.zoomLevel = Math.min(this.maxZoom, Math.max(this.minZoom, value)); + this.dispatchEvent(new CustomEvent('zoom', { detail: this.zoomLevel })); + }); + + this.#root + .querySelector('#zoom-label')! + .addEventListener('focus', (event: Event) => { + const target = event.target as HTMLInputElement; + target.select(); + }); + + window.addEventListener('keydown', (event) => { + if (event.ctrlKey && event.key === '0') { + this.dispatchEvent(new CustomEvent('center')); + } + }); + } + + #zoom(direction: 'in' | 'out', smallSteps = false) { + const zoomStep = smallSteps ? this.shiftZoomStep : this.zoomStep; + + const nearestStep = + direction === 'in' + ? Math.ceil(this.zoomLevel / zoomStep) * zoomStep + : Math.floor(this.zoomLevel / zoomStep) * zoomStep; + const nextStep = + direction === 'in' ? nearestStep + zoomStep : nearestStep - zoomStep; + + // if the nearest step is more than a quarter of the way to the next step, + // just zoom to the nearest step instead of the next step. + const targetStep = + Math.abs(nearestStep - this.zoomLevel) > zoomStep / 4 + ? nearestStep + : nextStep; + + this.zoomLevel = Math.min(this.maxZoom, Math.max(this.minZoom, targetStep)); + + this.dispatchEvent(new CustomEvent('zoom', { detail: this.zoomLevel })); + } + + /** + * Updates the zoom label. + */ + #updateZoomLabel() { + const zoomLabel = this.#root.querySelector( + '#zoom-label', + )! as HTMLInputElement; + zoomLabel.value = `${this.zoomLevel}%`; + } +} + +customElements.define('vis-statusbar', Statusbar); diff --git a/src/components/tooltip-cue.ts b/src/components/tooltip-cue.ts new file mode 100644 index 0000000..3234e96 --- /dev/null +++ b/src/components/tooltip-cue.ts @@ -0,0 +1,84 @@ +import { html } from '../utils/index.js'; + +/** + * Tooltip cue. Displays a question mark icon which, when hovered over, displays + * a tooltip. + * @example + * ```html + * + * ``` + */ +export class TooltipCue extends HTMLElement { + /** + * The root element. + */ + #root: HTMLDivElement; + + constructor() { + super(); + this.attachShadow({ mode: 'open' }); + this.shadowRoot!.innerHTML = html` + +
+
?
+
+ `; + this.#root = this.shadowRoot!.querySelector('#root')!; + + const observer = new MutationObserver(() => this.#updateTooltip()); + + observer.observe(this, { attributes: true, attributeFilter: ['tooltip'] }); + + this.#updateTooltip(); + } + + /** + * The tooltip text. + */ + get tooltip(): string | null { + return this.getAttribute('tooltip'); + } + + set tooltip(value: string | null) { + if (value === null) { + this.removeAttribute('tooltip'); + } else { + this.setAttribute('tooltip', value); + } + } + + /** + * Updates the tooltip text. + */ + #updateTooltip() { + this.#root.title = this.tooltip ?? ''; + } +} + +customElements.define('vis-tooltip-cue', TooltipCue); diff --git a/src/components/viewport.ts b/src/components/viewport.ts new file mode 100644 index 0000000..b72550c --- /dev/null +++ b/src/components/viewport.ts @@ -0,0 +1,263 @@ +import * as pixi from 'pixi.js'; +// @ts-ignore +import { Viewport as PixiViewport } from 'pixi-viewport'; +import { html, text } from '../utils/index.js'; +import { GraphView } from '../rendering/index.js'; +import { ApiClient } from '../providers/index.js'; +import { Dictionary } from '../types/index.js'; +import { LoadingIcon } from './loading-icon.js'; +import { ModalDialog } from './modal-dialog.js'; + +/** + * Viewport displayed in the browser, which uses a PixiJS application to render + * the interactive graphical content of the editor. Allows the user to pan and + * zoom the view. + */ +export class Viewport extends HTMLElement { + constructor() { + super(); + + this.attachShadow({ mode: 'open' }); + this.shadowRoot!.innerHTML = html` + +
+ + `; + + this.#loadingOverlay = this.shadowRoot!.querySelector( + '.loading-overlay', + ) as HTMLDivElement; + + this.app = new pixi.Application({ + backgroundColor: 0x1b1b1b, + height: this.clientHeight, + width: this.clientWidth, + antialias: true, + }); + + const view = this.app.view as HTMLCanvasElement; + + view.classList.add('viewport'); + + this.shadowRoot!.appendChild(view); + + this.viewport = new PixiViewport({ + events: this.app.renderer.events, + screenWidth: this.clientWidth, + screenHeight: this.clientHeight, + worldWidth: 1000, + worldHeight: 1000, + }); + + this.viewport.cursor = 'grab'; + + const updateCursor = (state: boolean) => { + const [off, on] = state ? ['grab', 'grabbing'] : ['grabbing', 'grab']; + this.viewport.cursor = on; + + if (view.style.cursor === off) { + view.style.cursor = on; + } + }; + + this.viewport.on('drag-start', () => updateCursor(true)); + this.viewport.on('drag-end', () => updateCursor(false)); + + this.viewport.on('mousedown', () => updateCursor(true)); + this.viewport.on('mouseup', () => updateCursor(false)); + + this.app.stage.addChild(this.viewport); + + this.viewport + .drag() + .pinch() + .wheel() + .decelerate({ + friction: 0.95, + minSpeed: 0.01, + }) + .clampZoom({ + minScale: 0.1, + maxScale: 2, + }); + + const resizeObserver = new ResizeObserver((entries) => { + for (const entry of entries) { + const { width, height } = entry.contentRect; + this.app.renderer.resize(width, height); + this.viewport.resize(width, height); + } + }); + + resizeObserver.observe(this); + + // Cleanup observer when component is destroyed + this.addEventListener('disconnected', () => { + resizeObserver.unobserve(this); + }); + + // add the graph view + this.graphView = new GraphView(this.viewport); + + // bubble viewport selection changes + this.graphView.addEventListener('nodeSelected', (event) => { + this.dispatchEvent( + new CustomEvent('nodeSelected', { + detail: (event as CustomEvent).detail, + }), + ); + }); + + this.viewport.on('zoomed', () => { + this.dispatchEvent( + new CustomEvent('zoom', { detail: this.viewport.scale.x * 100 }), + ); + }); + + this.#client = new ApiClient(); + } + + connectedCallback() { + // Zoom the viewport + this.viewport.zoomPercent(0.5); + + requestAnimationFrame(() => { + // resize the viewport + this.app.renderer.resize(this.clientWidth, this.clientHeight); + this.viewport.resize(this.clientWidth, this.clientHeight); + + // Pan the viewport to center at 0,0 + this.viewport.moveCenter(0, 0); + + this.graphView.render(); + }); + } + + /** + * The PixiJS application used to render the viewport. + */ + app: pixi.Application; + + /** + * The loading overlay. + */ + #loadingOverlay: HTMLDivElement; + + /** + * The API client used to fetch data from the Ordbok API. + */ + #client: ApiClient; + + /** + * The PixiJS viewport used to pan and zoom the view. + */ + viewport: PixiViewport; + + /** + * The graph view. + */ + graphView: GraphView; + + /** + * The zoom level of the viewport. + */ + get zoomLevel(): number { + return this.viewport.scale.x * 100; + } + set zoomLevel(value: number) { + this.viewport.setZoom(value / 100); + this.refresh(); + } + + /** + * Centers the viewport to the origin. + */ + center() { + this.viewport.moveCenter(0, 0); + } + + /** + * Refreshes the viewport. + */ + refresh() { + this.graphView.render(); + } + + /** + * Fetches and displays the graph for the given article. + */ + async loadGraph(articleId: number, dictionary: Dictionary) { + this.#loadingOverlay.style.display = ''; + + const [graph, errors] = await this.#client.getArticleGraph( + articleId, + dictionary, + 3, + ); + + this.#loadingOverlay.style.display = 'none'; + + if (errors.length > 0) { + const dialog = new ModalDialog({ + title: '⚠️ Feil', + html: html` +

+ Det oppstod ein feil under lasting av dataa. Prøv igjen seinare. +

+ ${errors.map((error) => html`

${text`${error.message}`}

`)} + `, + }); + document.body.appendChild(dialog); + dialog.show(); + return; + } + + this.graphView.setGraph(graph); + + this.center(); + } +} + +customElements.define('vis-viewport', Viewport); diff --git a/src/components/vis-client.ts b/src/components/vis-client.ts new file mode 100644 index 0000000..b39b2c4 --- /dev/null +++ b/src/components/vis-client.ts @@ -0,0 +1,126 @@ +import { html } from '../utils/index.js'; +import { SearchBar } from './search-bar.js'; +import { Sidebar } from './sidebar.js'; +import { Statusbar } from './statusbar.js'; +import { Viewport } from './viewport.js'; +import './app-logo.js'; + +/** + * Main client component, which encompasses the entire application. + */ +export class VisClient extends HTMLElement { + #root: HTMLDivElement; + + /** + * The viewport component. + */ + #viewport: Viewport; + + /** + * The sidebar component. + */ + #sidebar: Sidebar; + + /** + * The statusbar component. + */ + #statusbar: Statusbar; + + /** + * The search bar component. + */ + #searchBar: SearchBar; + + constructor() { + super(); + this.attachShadow({ mode: 'open' }); + this.shadowRoot!.innerHTML = html` + +
+ +
+ +
+
+ +
+
+ +
+ + `; + this.#root = this.shadowRoot!.querySelector('#vis') as HTMLDivElement; + this.#viewport = this.shadowRoot!.querySelector('vis-viewport') as Viewport; + this.#sidebar = this.shadowRoot!.querySelector('vis-sidebar') as Sidebar; + this.#statusbar = this.shadowRoot!.querySelector( + 'vis-statusbar', + ) as Statusbar; + + // keep statusbar zoom in sync with viewport zoom and vice versa. + this.#viewport.addEventListener('zoom', (event) => { + this.#statusbar.zoomLevel = (event as CustomEvent).detail; + }); + + this.#statusbar.addEventListener('zoom', (event) => { + this.#viewport.zoomLevel = (event as CustomEvent).detail; + }); + + // center view when statusbar event is received + this.#statusbar.addEventListener('center', () => this.#viewport.center()); + + // load graph when articleSelected event is received from search bar + this.#searchBar = this.shadowRoot!.querySelector( + 'vis-search-bar', + ) as SearchBar; + + this.#searchBar.addEventListener('articleSelected', (event) => { + const { id, dictionary } = (event as CustomEvent).detail; + this.#viewport.loadGraph(id, dictionary); + }); + } + + connectedCallback() { + // Listen for viewport selection changes. + this.#viewport.addEventListener('nodeSelected', (event) => { + const { id, dictionary } = (event as CustomEvent).detail; + this.#sidebar.loadArticle(id, dictionary); + }); + + this.#statusbar.zoomLevel = this.#viewport.zoomLevel; + } +} + +customElements.define('vis-client', VisClient); diff --git a/src/providers/api-client.ts b/src/providers/api-client.ts new file mode 100644 index 0000000..9280ed7 --- /dev/null +++ b/src/providers/api-client.ts @@ -0,0 +1,549 @@ +import { GraphQLClient, graphql } from '../utils/index.js'; +import { Dictionary, InflectionTag, GraphQLError } from '../types/index.js'; + +/** + * Represents an article graph. + */ +export type ArticleGraph = { + /** + * Article ID. + */ + id: string; + /** + * Dictionary. + */ + dictionary: Dictionary; + /** + * List of articles in the graph. + */ + nodes: Article[]; + /** + * List of article identifiers that are edges in the graph. + */ + edges: ArticleGraphEdge[]; +}; + +/** + * Represents an article graph edge. + */ +export type ArticleGraphEdge = { + /** + * Article identifier for the source node of the edge. + */ + sourceId: number; + /** + * Article identifier for the target node of the edge. + */ + targetId: number; + /** + * Type of the article relationship. + */ + type: ArticleRelationshipType; + /** + * Optional unique identifier for the definition where the article relationship is defined, unique relative to the article. + */ + sourceDefinitionId?: number; + /** + * Index for the definition where the article relationship is defined, unique relative to the article. + */ + sourceDefinitionIndex?: number; +}; + +/** + * Represents an article. + */ +export type Article = { + /** + * Unique identifier for the article. + */ + id: number; + /** + * Dictionary that the article belongs to. + */ + dictionary: Dictionary; + /** + * Word class of the word in the article, if available. + */ + wordClass?: WordClass; + /** + * List of lemmas (base forms of words) that the article covers. + */ + lemmas: Lemma[]; + /** + * Gender of the word in the article, if relevant. + */ + gender?: Gender; + /** + * List of definitions of the word in the article. + */ + definitions: Definition[]; + /** + * List of articles that include this article as part of a phrase. + */ + phrases: Article[]; + /** + * List of etymological origins of the word in the article. + */ + etymology: RichContent[]; + /** + * List of article relationships that are relevant to the article. + */ + relationships: ArticleRelationship[]; +}; + +/** + * Represents a set of inflection patterns for words, including specific inflection forms and associated tags. + */ +export type Paradigm = { + /** + * Unique identifier for the inflection paradigm. + */ + id: number; + /** + * List of inflection forms associated with this paradigm. + */ + inflections: Inflection[]; + /** + * List of tags relevant to this inflection paradigm. + */ + tags: InflectionTag[]; +}; + +/** + * Represents inflection information for a word, including inflection tag and word form. + */ +export type Inflection = { + /** + * List of inflection tags associated with the word. + */ + tags: InflectionTag[]; + /** + * The specific inflected form of the word. + */ + wordForm: string; +}; + +/** + * Represents a lemma. + */ +export type Lemma = { + /** + * Unique identifier for the lemma. + */ + id: number; + /** + * Base form of the word. + */ + lemma: string; + /** + * Numerical reference number to the meaning of the lemma. + */ + meaning: number; + /** + * List of paradigms associated with the lemma. + */ + paradigms: Paradigm[]; +}; + +/** + * Represents a definition. + */ +export type Definition = { + /** + * Optional unique identifier for the definition, unique relative to the article. + */ + id?: number; + /** + * Content of the definition. + */ + content: RichContent[]; + /** + * List of examples illustrating the use of the word or phrase. + */ + examples: RichContent[]; + /** + * List of article relationships that are relevant to the definition. + */ + relationships: ArticleRelationship[]; + /** + * List of sub-definitions related to the main definition. + */ + subDefinitions: Definition[]; +}; + +/** + * Represents the text content in an article. + */ +export type RichContent = { + /** + * The content in plain text. + */ + textContent: string; + /** + * The content in the form of rich content segments. + */ + richContent: RichContentSegment[]; +}; + +/** + * Represents a rich content segment. + */ +export type RichContentSegment = { + /** + * Type of the rich content segment. + */ + type: RichContentSegmentType; + /** + * Content of the segment. + */ + content: string; +}; + +/** + * Represents a rich content segment with a reference to an article. + */ +export type RichContentArticleSegment = RichContentSegment & { + /** + * The article referred to in the segment. + */ + article: Article; + /** + * The ID of the definition in the article that is referred to. + */ + definitionId?: number; + /** + * The index of the definition in the article that is referred to. + */ + definitionIndex?: number; +}; + +/** + * Represents a rich content segment with text content. + */ +export type RichContentTextSegment = RichContentSegment & { + /** + * The content of the segment. + */ + content: string; +}; + +/** + * Represents an article relationship. + */ +export type ArticleRelationship = { + /** + * Related article. + */ + article: Article; + /** + * Type of the article relationship. + */ + type: ArticleRelationshipType; +}; + +/** + * Represents a word. + */ +export type Word = { + /** + * The actual word being represented. + */ + word: string; + /** + * List of dictionaries that contain this word. + */ + dictionaries: Dictionary[]; + /** + * Articles that provide information about the word. + */ + articles: Article[]; +}; + +/** + * Represents suggestions. + */ +export type Suggestions = { + /** + * List of words that match the search term exactly. + */ + exact: Word[]; + /** + * List of words that are inflections of the search term. + */ + inflections: Word[]; + /** + * List of words found by free text search on the search term. + */ + freetext: Word[]; + /** + * List of words that are similar to the search term. + */ + similar: Word[]; +}; + +/** + * Represents a word class. + */ +export type WordClass = string; +/** + * Represents a gender. + */ +export type Gender = string; +/** + * Represents an article relationship type. + */ +export type ArticleRelationshipType = string; +/** + * Represents a rich content segment type. + */ +export type RichContentSegmentType = string; + +/** + * Represents the response of an API call. + * @template T - The type of the response data. + */ +export type ApiResponse = [T, GraphQLError[]]; + +/** + * Search results. + */ +export type SearchResults = { + /** + * List of search results. + */ + results: SearchResult[]; + + /** + * The search query. + */ + query: string; +}; + +export type SearchResult = { + /** + * The article ID. + */ + id: number; + + /** + * The dictionary the article belongs to. + */ + dictionary: Dictionary; + + /** + * The title of the article, computed from the lemmas. + */ + title: string; + + /** + * The type of suggestion from which the search result was found. + */ + type: SuggestionType; +}; + +/** + * Suggestion types. + */ +export enum SuggestionType { + Exact = 'exact', + Inflections = 'inflections', + Freetext = 'freetext', + Similar = 'similar', +} + +/** + * Client for the Ordbok GraphQL API. + * @see https://ordbokapi.org/ + */ +export class ApiClient { + /** + * Initialize the client with a GraphQL endpoint URL. + * @param url GraphQL endpoint URL. + */ + constructor(url: string = 'https://api.ordbokapi.org/graphql') { + this.#client = new GraphQLClient(url); + } + + /** + * GraphQL client. + */ + #client: GraphQLClient; + + /** + * Get article graph from a given article ID and dictionary. + * @param id Article ID. + * @param dictionary Dictionary. + * @param depth Depth of the graph. Must be between 1 and 3. + * @returns Article graph. + */ + async getArticleGraph( + id: number, + dictionary: Dictionary, + depth: number = 1, + ): Promise> { + // use articleGraph query + const { data, errors } = await this.#client.query( + graphql` + query ArticleGraphQuery( + $articleId: Int! + $dictionary: Dictionary! + $depth: Int! + ) { + articleGraph(id: $articleId, dictionary: $dictionary, depth: $depth) { + nodes { + id + dictionary + lemmas { + lemma + } + } + edges { + sourceId + targetId + type + sourceDefinitionId + sourceDefinitionIndex + } + } + } + `, + { articleId: id, dictionary, depth }, + { allowErrors: true }, + ); + + return [data?.articleGraph, errors]; + } + + /** + * Gets article suggestions for a given search term. + * @param term Search term. + * @param dictionaries List of dictionaries to search in. Defaults to all + * dictionaries. + * @param searchTypes List of suggestion types to search for. Defaults to all + * suggestion types. + * @returns Suggestions. + */ + async search( + term: string, + dictionaires: Dictionary[] = Object.values(Dictionary), + searchTypes: SuggestionType[] = Object.values(SuggestionType), + ): Promise { + const { data } = await this.#client.query( + graphql` + query SuggestionsQuery($term: String!, $dictionaries: [Dictionary!]) { + suggestions(word: $term, dictionaries: $dictionaries) { + ${Object.values(SuggestionType).reduce( + (acc, type) => + searchTypes.includes(type) + ? acc + + graphql` + ${type} + { + word + articles { + id + dictionary + } + } + ` + : acc, + '', + )} + } + } + `, + { term, dictionaries: dictionaires }, + ); + + if (!data) { + return { results: [], query: term }; + } + + const results: SearchResult[] = []; + const resultMap = new Map(); + const articleWordMap = new Map>(); + + for (const type of searchTypes) { + const suggestions = data.suggestions[type]; + + if (suggestions) { + for (const suggestion of suggestions) { + for (const article of suggestion.articles ?? []) { + const key = `${article.id}-${article.dictionary}`; + const existingResult = resultMap.get(key); + + if (!existingResult) { + const newResult: SearchResult = { + id: article.id, + dictionary: article.dictionary, + title: suggestion.word, + type, + }; + resultMap.set(key, newResult); + results.push(newResult); + articleWordMap.set(article.id, new Set([suggestion.word])); + + continue; + } + + if (!articleWordMap.get(article.id)?.has(suggestion.word)) { + existingResult.title += `, ${suggestion.word}`; + articleWordMap.get(article.id)?.add(suggestion.word); + } + } + } + } + } + + return { results, query: term }; + } + + /** + * Gets the article with the given ID and dictionary. + * @param id Article ID. + * @param dictionary Dictionary. + * @returns Article. + */ + async getArticle( + id: number, + dictionary: Dictionary, + ): Promise> { + const { data, errors } = await this.#client.query( + graphql` + fragment RichContentFragment on RichContent { + textContent + richContent { + type + content + } + } + fragment DefinitionFragment on Definition { + content { + ...RichContentFragment + } + examples { + ...RichContentFragment + } + } + query ArticleQuery($id: Int!, $dictionary: Dictionary!) { + article(id: $id, dictionary: $dictionary) { + id + lemmas { + lemma + } + definitions { + ...DefinitionFragment + subDefinitions { + ...DefinitionFragment + } + } + } + } + `, + { id, dictionary }, + { allowErrors: true }, + ); + + return [data?.article, errors]; + } +} diff --git a/src/providers/index.ts b/src/providers/index.ts new file mode 100644 index 0000000..e2b40c9 --- /dev/null +++ b/src/providers/index.ts @@ -0,0 +1 @@ +export * from './api-client.js'; diff --git a/src/rendering/graph-view.ts b/src/rendering/graph-view.ts new file mode 100644 index 0000000..79c5e70 --- /dev/null +++ b/src/rendering/graph-view.ts @@ -0,0 +1,375 @@ +import * as d3 from 'd3'; +import * as pixi from 'pixi.js'; +// @ts-ignore +import { Viewport } from 'pixi-viewport'; +import { + ApiClient, + Article, + ArticleGraph, + ArticleGraphEdge, +} from '../providers/index.js'; +import { Dictionary, Vector2D } from '../types/index.js'; + +/** + * Full-viewport graph view, built using D3 and a canvas. Nodes can be interacted with, + * and the graph can be panned and zoomed. + */ +export class GraphView extends EventTarget { + /** + * GraphQL client. + */ + #client: ApiClient; + + /** + * Pixi-viewport instance. + */ + #viewport: Viewport; + + /** + * PixiJS canvas for overlay. + */ + #overlayCanvas: pixi.Graphics; + + /** + * PixiJS canvas for edges. + */ + #edgeCanvas: pixi.Graphics; + + /** + * Array of node PIXI objects. + */ + #nodeGraphics: pixi.Graphics[]; + + /** + * D3 force simulation. + */ + #simulation: d3.Simulation< + d3.SimulationNodeDatum & Article, + { source: number; target: number } + >; + + constructor(viewport: Viewport) { + super(); + this.#client = new ApiClient(); + this.#viewport = viewport; + this.#overlayCanvas = this.#viewport.addChild(new pixi.Graphics()); + this.#edgeCanvas = this.#viewport.addChild(new pixi.Graphics()); + this.#nodeGraphics = []; + + this.#simulation = d3 + .forceSimulation() + .force( + 'link', + d3 + .forceLink< + d3.SimulationNodeDatum & Article, + { source: number; target: number } + >() + .id((d) => d.id) + .strength(0.05), + ) + .force('charge', d3.forceManyBody().strength(-50)) + // d3 collision force only works with circles, so we use a custom + // implementation instead that uses the PixiJS rectangle bounding boxes + .force('collision', () => { + const nodes = this.#simulation.nodes(); + const quadtree = d3.quadtree( + nodes, + (d) => d.x!, + (d) => d.y!, + ); + + nodes.forEach((node) => { + const nodeBounds = + this.#nodeGraphics[nodes.indexOf(node)].getBounds(); + quadtree.visit((quad) => { + if (!quad) return; + + if ('data' in quad && quad.data !== node) { + const quadNodeBounds = + this.#nodeGraphics[nodes.indexOf(quad.data)].getBounds(); + + // expand bounds slightly to give nodes some breathing room + const margin = 10; + + quadNodeBounds.x -= margin; + quadNodeBounds.y -= margin; + quadNodeBounds.width += margin; + quadNodeBounds.height += margin; + + // Calculate overlap and apply force to separate nodes + + // Calculate overlap on x-axis + const xOverlap = Math.max( + 0, + Math.min(nodeBounds.right, quadNodeBounds.right) - + Math.max(nodeBounds.left, quadNodeBounds.left), + ); + // Calculate overlap on y-axis + const yOverlap = Math.max( + 0, + Math.min(nodeBounds.bottom, quadNodeBounds.bottom) - + Math.max(nodeBounds.top, quadNodeBounds.top), + ); + + // Calculate total overlap + const overlap = xOverlap * yOverlap; + + // Adjust node position if overlap exists + if (overlap > 0) { + const force = + (overlap * 20) / (nodeBounds.width * nodeBounds.height); + const dx = node.x! - quad.data.x! || 1; + const dy = node.y! - quad.data.y! || 1; + const angle = Math.atan2(dy, dx); + node.x! += Math.cos(angle) * force + Math.random() * 0.1; + node.y! += Math.sin(angle) * force + Math.random() * 0.1; + } + } + + // Return false to only check nodes in the current quad + return false; + }); + }); + }) + .force( + 'center', + d3.forceCenter(this.#viewport.width / 2, this.#viewport.height / 2), + ) + .alphaTarget(0.1) + .on('tick', () => this.#tick()); + + this.#viewport.on('zoomed', () => { + const textResolution = this.#viewport.scale.x; + this.#nodeGraphics.forEach((node) => { + const text = node.getChildAt(0) as pixi.Text; + text.resolution = textResolution; + }); + this.#renderIsEmptyOverlay(); + }); + } + + setGraph(graph: ArticleGraph) { + this.#setNodes(graph.nodes); + this.#setLinks(graph.edges); + this.#simulation.alpha(1).restart(); + this.#renderIsEmptyOverlay(); + } + + #setNodes(nodes: Article[]) { + this.#simulation.nodes(nodes); + + this.#createNodeGraphics(); + } + + #setLinks(links: ArticleGraphEdge[]) { + this.#simulation.force>('link')?.links( + links.map((link) => ({ + source: link.sourceId, + target: link.targetId, + })), + ); + } + + /** + * Forces the graph to re-render. + */ + render() { + this.#createNodeGraphics(); + this.#renderIsEmptyOverlay(); + } + + #selectedNode: pixi.Graphics | null = null; + + #renderIsEmptyOverlay() { + this.#overlayCanvas.clear(); + this.#overlayCanvas.removeChildren(); + + if (this.#simulation.nodes().length) { + return; + } + + this.#overlayCanvas.beginFill(0x000000, 0.5); + this.#overlayCanvas.drawRect( + 0, + 0, + this.#viewport.width, + this.#viewport.height, + ); + this.#overlayCanvas.endFill(); + + const text = new pixi.Text( + 'Ingen data. Søk etter ein artikkel for å starta.', + { + fontSize: 16, + fill: 0xaaaaaa, + fontFamily: 'IBM Plex Sans', + }, + ); + + text.resolution = this.#viewport.scale.x; + text.anchor.set(0.5); + text.position.set(this.#viewport.width / 2, this.#viewport.height / 2); + this.#overlayCanvas.addChild(text); + } + + #selectNode(node: pixi.Graphics, id: number, dictionary: Dictionary) { + if (this.#selectedNode) { + // Reset style of previously selected node + this.#selectedNode.tint = 0xffffff; + } + + this.dispatchEvent( + new CustomEvent('nodeSelected', { + detail: { id, dictionary }, + }), + ); + + // Update style of newly selected node + node.tint = 0x666666; + this.#selectedNode = node; + } + + #createNodeGraphics() { + // Remove old nodes + this.#nodeGraphics.forEach((node) => this.#viewport.removeChild(node)); + this.#nodeGraphics = []; + + // Create new nodes + this.#simulation.nodes().forEach((d) => { + const node = new pixi.Graphics(); + const text = new pixi.Text(d.lemmas[0].lemma, { + fontSize: 12, + fill: 0xffffff, + fontFamily: 'Lora', + }); + + text.resolution = this.#viewport.scale.x; + + // Adjust rectangle size based on text bounds + const textBounds = pixi.TextMetrics.measureText( + d.lemmas[0].lemma, + text.style, + ); + const paddingX = 20; + const paddingY = 10; + const width = textBounds.width + paddingX; + const height = textBounds.height + paddingY; + const cornerRadius = 20; + const color = 0x1b1b1b; + const borderColor = 0x666666; + + node.beginFill(color); + node.lineStyle(1, borderColor); + node.drawRoundedRect( + -width / 2, + -height / 2, + width, + height, + cornerRadius, + ); + node.endFill(); + + text.anchor.set(0.5); + text.position.set(0, 0); + node.addChild(text); + + node.x = d.x!; + node.y = d.y!; + this.#viewport.addChild(node); + this.#nodeGraphics.push(node); + + node.eventMode = 'dynamic'; + node.cursor = 'pointer'; + + // Dragging state + let isDragging = false; + let data: Vector2D = new Vector2D(); + let initialPosition = new Vector2D(); + let anchorOffset = new Vector2D(); + + node.on('mouseover', () => { + if (!isDragging) { + node.tint = 0xbbbbbb; + } + }); + + node.on('mouseout', () => { + if (!isDragging) { + node.tint = this.#selectedNode !== node ? 0xffffff : 0x666666; + } + }); + + node.on('pointerdown', (event) => { + // disable viewport dragging + this.#viewport.plugins.pause('drag'); + + isDragging = true; + node.tint = 0x888888; + text.tint = 0x888888; + // calculate offset from location of pointer to center of node + anchorOffset = new Vector2D( + event.getLocalPosition(node.parent), + ).subtract(new Vector2D(node)); + data = new Vector2D(node); + initialPosition = new Vector2D(node); + }); + + this.#viewport.on('pointermove', (event: pixi.FederatedMouseEvent) => { + if (isDragging) { + data = new Vector2D(event.getLocalPosition(node.parent)); + const newPosition = data.subtract(anchorOffset); + d.fx = newPosition.x; + d.fy = newPosition.y; + } + }); + + this.#viewport.on('pointerup', () => { + if (isDragging) { + // enable viewport dragging + this.#viewport.plugins.resume('drag'); + + isDragging = false; + node.tint = this.#selectedNode !== node ? 0xffffff : 0x666666; + text.tint = 0xffffff; + d.fx = null; + d.fy = null; + + const distance = initialPosition.distance(data); + + if (distance < 10) { + this.#selectNode(node, d.id, d.dictionary); + } + } + }); + + this.#viewport.on('pointerupoutside', () => { + if (isDragging) { + isDragging = false; + node.tint = this.#selectedNode !== node ? 0xffffff : 0x666666; + d.fx = null; + d.fy = null; + } + }); + }); + } + + #tick(): void { + this.#edgeCanvas.clear(); + this.#edgeCanvas.lineStyle(1, 0x00ffff, 1); + + this.#simulation + .force>('link') + ?.links() + .forEach((link) => { + this.#edgeCanvas.moveTo(link.source.x!, link.source.y!); + this.#edgeCanvas.lineTo(link.target.x!, link.target.y!); + }); + + // Update node positions + this.#nodeGraphics.forEach((node, i) => { + node.x = this.#simulation.nodes()[i].x!; + node.y = this.#simulation.nodes()[i].y!; + }); + } +} diff --git a/src/rendering/index.ts b/src/rendering/index.ts new file mode 100644 index 0000000..3a26b7f --- /dev/null +++ b/src/rendering/index.ts @@ -0,0 +1 @@ +export * from './graph-view.js'; diff --git a/src/static-imports.d.ts b/src/static-imports.d.ts new file mode 100644 index 0000000..8dadc66 --- /dev/null +++ b/src/static-imports.d.ts @@ -0,0 +1,14 @@ +declare module '*.png' { + const value: string; + export default value; +} + +declare module '*.svg' { + const value: string; + export default value; +} + +declare module '*.css' { + const value: string; + export default value; +} diff --git a/src/types/dictionary.ts b/src/types/dictionary.ts new file mode 100644 index 0000000..a121afc --- /dev/null +++ b/src/types/dictionary.ts @@ -0,0 +1,7 @@ +/** + * Which dictionary to use. + */ +export enum Dictionary { + Nynorskordboka = 'Nynorskordboka', + Bokmaalsordboka = 'Bokmaalsordboka', +} diff --git a/src/types/graphql-error.ts b/src/types/graphql-error.ts new file mode 100644 index 0000000..483c155 --- /dev/null +++ b/src/types/graphql-error.ts @@ -0,0 +1,29 @@ +/** + * Error returned by the GraphQL API. + */ +export class GraphQLError extends Error { + /** + * Initialize the error with a GraphQL error object. + * @param error GraphQL error object. + */ + constructor(error: { + message: string | undefined; + extensions?: { code: string }; + path: string[]; + }) { + super(error.message); + this.name = 'GraphQLError'; + this.code = error.extensions?.code; + this.path = error.path; + } + + /** + * Error code. + */ + code?: string; + + /** + * Path to the GraphQL field that caused the error. + */ + path: string[]; +} diff --git a/src/types/index.ts b/src/types/index.ts new file mode 100644 index 0000000..d253a99 --- /dev/null +++ b/src/types/index.ts @@ -0,0 +1,4 @@ +export * from './dictionary.js'; +export * from './inflection-tag.js'; +export * from './graphql-error.js'; +export * from './vector-2d.js'; diff --git a/src/types/inflection-tag.ts b/src/types/inflection-tag.ts new file mode 100644 index 0000000..cbe2426 --- /dev/null +++ b/src/types/inflection-tag.ts @@ -0,0 +1,28 @@ +/** + * Inflection tags for a word. + */ +export enum InflectionTag { + Infinitiv = 'Infinitiv', + Presens = 'Presens', + Preteritum = 'Preteritum', + PerfektPartisipp = 'PerfektPartisipp', + PresensPartisipp = 'PresensPartisipp', + SPassiv = 'SPassiv', + Imperativ = 'Imperativ', + Passiv = 'Passiv', + Adjektiv = 'Adjektiv', + Adverb = 'Adverb', + Eintal = 'Eintal', + HankjoennHokjoenn = 'HankjoennHokjoenn', + Hankjoenn = 'Hankjoenn', + Hokjoenn = 'Hokjoenn', + Inkjekjoenn = 'Inkjekjoenn', + Ubestemt = 'Ubestemt', + Bestemt = 'Bestemt', + Fleirtal = 'Fleirtal', + Superlativ = 'Superlativ', + Komparativ = 'Komparativ', + Positiv = 'Positiv', + Nominativ = 'Nominativ', + Akkusativ = 'Akkusativ', +} diff --git a/src/types/vector-2d.ts b/src/types/vector-2d.ts new file mode 100644 index 0000000..5e07f06 --- /dev/null +++ b/src/types/vector-2d.ts @@ -0,0 +1,149 @@ +/** + * Describes any type that has x and y coordinates. + */ +export interface IPoint { + /** + * X coordinate. + */ + x: number; + + /** + * Y coordinate. + */ + y: number; +} + +/** + * 2-dimensional vector. + */ +export class Vector2D { + /** + * X coordinate. + */ + x: number; + + /** + * Y coordinate. + */ + y: number; + + /** + * Create a new vector. + * @param x X coordinate. + * @param y Y coordinate. + */ + constructor(x?: number, y?: number); + /** + * Create a new vector. + * @param obj Object with x and y coordinates. + */ + constructor(obj: IPoint); + constructor(objOrX?: IPoint | number, y?: number) { + if (objOrX && typeof objOrX === 'object') { + this.x = objOrX.x; + this.y = objOrX.y; + } else { + this.x = objOrX ?? 0; + this.y = y ?? 0; + } + } + + /** + * Add a vector to this vector. + * @param v Vector to add. + */ + add(v: Vector2D): Vector2D { + return new Vector2D(this.x + v.x, this.y + v.y); + } + + /** + * Subtract a vector from this vector. + * @param v Vector to subtract. + */ + subtract(v: Vector2D): Vector2D { + return new Vector2D(this.x - v.x, this.y - v.y); + } + + /** + * Multiply this vector by a scalar. + * @param s Scalar to multiply by. + */ + multiply(s: number): Vector2D; + /** + * Multiply this vector by another vector. + * @param v Vector to multiply by. + */ + multiply(v: Vector2D): Vector2D; + multiply(sOrV: number | Vector2D): Vector2D { + if (typeof sOrV === 'number') { + return new Vector2D(this.x * sOrV, this.y * sOrV); + } else { + return new Vector2D(this.x * sOrV.x, this.y * sOrV.y); + } + } + + /** + * Divide this vector by a scalar. + * @param s Scalar to divide by. + */ + divide(s: number): Vector2D; + /** + * Divide this vector by another vector. + * @param v Vector to divide by. + */ + divide(v: Vector2D): Vector2D; + divide(sOrV: number | Vector2D): Vector2D { + if (typeof sOrV === 'number') { + return new Vector2D(this.x / sOrV, this.y / sOrV); + } else { + return new Vector2D(this.x / sOrV.x, this.y / sOrV.y); + } + } + + /** + * Get the magnitude of this vector. + */ + get magnitude(): number { + return Math.sqrt(this.x * this.x + this.y * this.y); + } + + /** + * Get the unit vector of this vector. + */ + get unit(): Vector2D { + return this.divide(this.magnitude); + } + + /** + * Get the dot product of this vector and another vector. + * @param v Vector to get the dot product with. + */ + dot(v: Vector2D): number { + return this.x * v.x + this.y * v.y; + } + + /** + * Get the angle between this vector and another vector. + * @param v Vector to get the angle with. + */ + angle(v: Vector2D): number; + /** + * Get the angle between this vector and the x-axis. + */ + angle(): number; + angle(v?: Vector2D): number { + if (v) { + return Math.acos(this.dot(v) / (this.magnitude * v.magnitude)); + } else { + return Math.atan2(this.y, this.x); + } + } + + /** + * Get the distance between this vector and another vector. + * @param v Vector to get the distance with. + */ + distance(v: Vector2D): number { + return this.subtract(v).magnitude; + } +} diff --git a/src/utils/graphql-client.ts b/src/utils/graphql-client.ts new file mode 100644 index 0000000..d1f615c --- /dev/null +++ b/src/utils/graphql-client.ts @@ -0,0 +1,71 @@ +import { GraphQLError } from '../types/index.js'; + +interface GraphQLClientOptions { + /** + * Whether to allow errors in the response. If set to `false` (default), an + * error will be thrown if the response contains any errors. Otherwise, if set + * to `true`, the response will be returned as-is. + */ + allowErrors?: boolean; +} + +interface GraphQLResponse { + /** + * GraphQL data. + */ + data: any; + /** + * GraphQL errors. + */ + errors: GraphQLError[]; +} + +/** + * A simple GraphQL client that can be used in the browser. + */ +export class GraphQLClient { + /** + * Initialize the client with a GraphQL endpoint URL. + * @param url GraphQL endpoint URL. + */ + constructor(url: string) { + this.#url = url; + } + + /** + * URL of the GraphQL endpoint. + */ + #url: string; + + /** + * Send a GraphQL query to the endpoint. + * @param query GraphQL query. + * @param variables GraphQL variables. + * @param options GraphQL client options. + * @returns GraphQL response. + */ + async query( + query: string, + variables: { [key: string]: any }, + options: GraphQLClientOptions = {}, + ): Promise { + const response = await fetch(this.#url, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ query, variables }), + }); + const { data, errors } = await response.json(); + + if (errors?.length) { + const typedErrors = errors.map((error: any) => new GraphQLError(error)); + + if (options?.allowErrors) { + return { data, errors: typedErrors }; + } else { + throw typedErrors; + } + } + + return { data, errors: [] }; + } +} diff --git a/src/utils/graphql.ts b/src/utils/graphql.ts new file mode 100644 index 0000000..f0769e7 --- /dev/null +++ b/src/utils/graphql.ts @@ -0,0 +1,11 @@ +/** + * Fake template literal tag for GraphQL to enable syntax highlighting in + * editors. + * @param strings Template strings. + * @param values Template values. + * @returns emplated string. + */ +export const graphql = ( + strings: TemplateStringsArray, + ...values: any[] +): string => String.raw({ raw: strings }, ...values); diff --git a/src/utils/html.ts b/src/utils/html.ts new file mode 100644 index 0000000..e39a3c7 --- /dev/null +++ b/src/utils/html.ts @@ -0,0 +1,8 @@ +/** + * Fake template literal tag for HTML to enable syntax highlighting in editors. + * @param strings Template strings. + * @param values Template values. + * @returns Templated string. + */ +export const html = (strings: TemplateStringsArray, ...values: any[]): string => + String.raw({ raw: strings }, ...values); diff --git a/src/utils/index.ts b/src/utils/index.ts new file mode 100644 index 0000000..ebd6df0 --- /dev/null +++ b/src/utils/index.ts @@ -0,0 +1,4 @@ +export * from './html.js'; +export * from './graphql-client.js'; +export * from './graphql.js'; +export * from './text.js'; diff --git a/src/utils/text.ts b/src/utils/text.ts new file mode 100644 index 0000000..9dc8c13 --- /dev/null +++ b/src/utils/text.ts @@ -0,0 +1,21 @@ +/** + * Escapes a string to be used in HTML. + * @param string The string to escape. + * @returns The escaped string. + */ +const escapeHtml = (string: unknown) => new Option(string as string).innerHTML; + +/** + * Template literal tag that returns a string with HTML entities escaped. + * @param strings Template strings. + * @param values Template values. + * @returns The escaped string. + */ +export const text = (strings: TemplateStringsArray, ...values: unknown[]) => + strings.reduce( + (result, string, index) => + result + + escapeHtml(string) + + (index < values.length ? escapeHtml(values[index]) : ''), + '', + ); diff --git a/static/favicon.ico b/static/favicon.ico new file mode 100644 index 0000000..6a21eda Binary files /dev/null and b/static/favicon.ico differ diff --git a/static/images/android-chrome-192x192.png b/static/images/android-chrome-192x192.png new file mode 100644 index 0000000..3623d54 Binary files /dev/null and b/static/images/android-chrome-192x192.png differ diff --git a/static/images/android-chrome-512x512.png b/static/images/android-chrome-512x512.png new file mode 100644 index 0000000..cfd3ffe Binary files /dev/null and b/static/images/android-chrome-512x512.png differ diff --git a/static/images/apple-touch-icon.png b/static/images/apple-touch-icon.png new file mode 100644 index 0000000..c4eae7a Binary files /dev/null and b/static/images/apple-touch-icon.png differ diff --git a/static/images/favicon-16x16.png b/static/images/favicon-16x16.png new file mode 100644 index 0000000..3a86146 Binary files /dev/null and b/static/images/favicon-16x16.png differ diff --git a/static/images/favicon-32x32.png b/static/images/favicon-32x32.png new file mode 100644 index 0000000..21b5c96 Binary files /dev/null and b/static/images/favicon-32x32.png differ diff --git a/static/images/ordbokapi-vis-client-logo-in-app.png b/static/images/ordbokapi-vis-client-logo-in-app.png new file mode 100644 index 0000000..7db5fba Binary files /dev/null and b/static/images/ordbokapi-vis-client-logo-in-app.png differ diff --git a/static/images/ordbokapi-vis-client-open-graph.png b/static/images/ordbokapi-vis-client-open-graph.png new file mode 100644 index 0000000..7612bab Binary files /dev/null and b/static/images/ordbokapi-vis-client-open-graph.png differ diff --git a/static/index.html b/static/index.html new file mode 100644 index 0000000..2046f63 --- /dev/null +++ b/static/index.html @@ -0,0 +1,58 @@ + + + + + + Ordbok API | Vis-klient + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/static/shared.css b/static/shared.css new file mode 100644 index 0000000..5cff210 --- /dev/null +++ b/static/shared.css @@ -0,0 +1,85 @@ +:host { + --color-accent: #29d7f6; + --main-bg-color: #1b1b1b; + --main-text-color: #f4f4f4; + --main-text-emphasis-color: #f7ca4f; + --secondary-bg-color: #333; + --link-color: #4fc3f7; + --link-hover-color: #29b6f6; + --btn-primary-bg-color: #0593ac; + --btn-primary-text-color: #fff; + --btn-primary-hover-bg-color: #13aac5; + --btn-primary-active-bg-color: #076d80; + --btn-secondary-bg-color: #999999; + --btn-secondary-text-color: #000; + --btn-secondary-hover-bg-color: #b8b8b8; + --btn-secondary-active-bg-color: #868686; + --border-color: #666; + --list-item-bg-color: #353535; + --list-item-hover-bg-color: #444; + + --sans-serif-family: 'IBM Plex Sans', 'Helvetica Neue', Helvetica, Arial, + sans-serif; + --serif-family: 'Lora', 'Times New Roman', Times, serif; +} + +button, +input { + background-color: #353535; + border: 1px solid #666; + border-radius: 0.25em; + padding: 0.5em 0.5em; + font-family: var(--sans-serif-family); + font-size: 1em; + color: #fff; +} + +button { + cursor: pointer; +} + +button:hover { + background-color: #444; +} + +button:active { + background-color: #555; +} + +button:focus { + outline: none; +} + +button:focus-visible { + box-shadow: 0 0 0 2px #fff; +} + +button:disabled { + opacity: 0.5; + cursor: not-allowed; +} + +button:disabled:hover { + background-color: #353535; +} + +button:disabled:active { + background-color: #353535; +} + +/* only for screen readers, not visible on screen */ +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; +} + +.emoji-icon { + cursor: default; +} diff --git a/static/site.webmanifest b/static/site.webmanifest new file mode 100644 index 0000000..339bacd --- /dev/null +++ b/static/site.webmanifest @@ -0,0 +1,19 @@ +{ + "name": "Ordbok API Vis Klient", + "short_name": "Ordbok API Vis Klient", + "icons": [ + { + "src": "images/android-chrome-192x192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "images/android-chrome-512x512.png", + "sizes": "512x512", + "type": "image/png" + } + ], + "theme_color": "#0593ac", + "background_color": "#1b1b1b", + "display": "standalone" +} diff --git a/static/style.css b/static/style.css new file mode 100644 index 0000000..b23dc8d --- /dev/null +++ b/static/style.css @@ -0,0 +1,28 @@ +@import url('https://fonts.googleapis.com/css2?family=Sarala&family=IBM+Plex+Sans&family=Lora&display=swap'); + +:root { + --main-bg-color: #1b1b1b; + --main-text-color: #f4f4f4; + --main-text-emphasis-color: #f7ca4f; + --navbar-bg-color: #333; + --link-color: #4fc3f7; + --link-hover-color: #29b6f6; + --btn-primary-bg-color: #0593ac; + --btn-primary-text-color: #fff; + --btn-primary-hover-bg-color: #13aac5; + --btn-primary-active-bg-color: #076d80; + --btn-secondary-bg-color: #999999; + --btn-secondary-text-color: #000; + --btn-secondary-hover-bg-color: #b8b8b8; + --btn-secondary-active-bg-color: #868686; +} + +body, +html { + font-family: 'IBM Plex Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif; + margin: 0; + padding: 0; + color: var(--main-text-color); + background-color: var(--main-bg-color); + overflow: hidden; +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..f02f785 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,13 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "NodeNext", + "moduleResolution": "NodeNext", + "allowJs": false, + "checkJs": false, + "noEmit": true, + "lib": ["DOM", "ES2022"], + "strict": true, + }, + "include": ["src/**/*"], +} diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 0000000..67378d9 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,4280 @@ +# This file is generated by running "yarn install" inside your project. +# Manual changes might be lost - proceed with caution! + +__metadata: + version: 8 + cacheKey: 10c0 + +"@babel/code-frame@npm:^7.0.0": + version: 7.23.5 + resolution: "@babel/code-frame@npm:7.23.5" + dependencies: + "@babel/highlight": "npm:^7.23.4" + chalk: "npm:^2.4.2" + checksum: a10e843595ddd9f97faa99917414813c06214f4d9205294013e20c70fbdf4f943760da37dec1d998bf3e6fc20fa2918a47c0e987a7e458663feb7698063ad7c6 + languageName: node + linkType: hard + +"@babel/helper-validator-identifier@npm:^7.22.20": + version: 7.22.20 + resolution: "@babel/helper-validator-identifier@npm:7.22.20" + checksum: dcad63db345fb110e032de46c3688384b0008a42a4845180ce7cd62b1a9c0507a1bed727c4d1060ed1a03ae57b4d918570259f81724aaac1a5b776056f37504e + languageName: node + linkType: hard + +"@babel/highlight@npm:^7.23.4": + version: 7.23.4 + resolution: "@babel/highlight@npm:7.23.4" + dependencies: + "@babel/helper-validator-identifier": "npm:^7.22.20" + chalk: "npm:^2.4.2" + js-tokens: "npm:^4.0.0" + checksum: fbff9fcb2f5539289c3c097d130e852afd10d89a3a08ac0b5ebebbc055cc84a4bcc3dcfed463d488cde12dd0902ef1858279e31d7349b2e8cee43913744bda33 + languageName: node + linkType: hard + +"@isaacs/cliui@npm:^8.0.2": + version: 8.0.2 + resolution: "@isaacs/cliui@npm:8.0.2" + dependencies: + string-width: "npm:^5.1.2" + string-width-cjs: "npm:string-width@^4.2.0" + strip-ansi: "npm:^7.0.1" + strip-ansi-cjs: "npm:strip-ansi@^6.0.1" + wrap-ansi: "npm:^8.1.0" + wrap-ansi-cjs: "npm:wrap-ansi@^7.0.0" + checksum: b1bf42535d49f11dc137f18d5e4e63a28c5569de438a221c369483731e9dac9fb797af554e8bf02b6192d1e5eba6e6402cf93900c3d0ac86391d00d04876789e + languageName: node + linkType: hard + +"@lezer/common@npm:^1.0.0": + version: 1.2.1 + resolution: "@lezer/common@npm:1.2.1" + checksum: af61436dc026f8deebaded13d8e1beea2ae307cbbfb270116cdedadb8208f0674da9c3b5963128a2b1cd4072b4e90bc8128133f4feaf31b6e801e4568f1a15a6 + languageName: node + linkType: hard + +"@lezer/lr@npm:^1.0.0": + version: 1.4.0 + resolution: "@lezer/lr@npm:1.4.0" + dependencies: + "@lezer/common": "npm:^1.0.0" + checksum: 1e3af297cc142bb6676cb3c4e1bd310da2e93b53273cf745dc85d839a08e1d3cbbd67e0fc0322a480cf25ee215fefe967c53bc2af3ddf5d9b1bf267081dfa164 + languageName: node + linkType: hard + +"@lmdb/lmdb-darwin-arm64@npm:2.8.5": + version: 2.8.5 + resolution: "@lmdb/lmdb-darwin-arm64@npm:2.8.5" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@lmdb/lmdb-darwin-x64@npm:2.8.5": + version: 2.8.5 + resolution: "@lmdb/lmdb-darwin-x64@npm:2.8.5" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@lmdb/lmdb-linux-arm64@npm:2.8.5": + version: 2.8.5 + resolution: "@lmdb/lmdb-linux-arm64@npm:2.8.5" + conditions: os=linux & cpu=arm64 + languageName: node + linkType: hard + +"@lmdb/lmdb-linux-arm@npm:2.8.5": + version: 2.8.5 + resolution: "@lmdb/lmdb-linux-arm@npm:2.8.5" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + +"@lmdb/lmdb-linux-x64@npm:2.8.5": + version: 2.8.5 + resolution: "@lmdb/lmdb-linux-x64@npm:2.8.5" + conditions: os=linux & cpu=x64 + languageName: node + linkType: hard + +"@lmdb/lmdb-win32-x64@npm:2.8.5": + version: 2.8.5 + resolution: "@lmdb/lmdb-win32-x64@npm:2.8.5" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"@mischnic/json-sourcemap@npm:^0.1.0": + version: 0.1.1 + resolution: "@mischnic/json-sourcemap@npm:0.1.1" + dependencies: + "@lezer/common": "npm:^1.0.0" + "@lezer/lr": "npm:^1.0.0" + json5: "npm:^2.2.1" + checksum: e2e314fc048a16baedb10ec4d517c2622e464b8a9f8481cd4c008ebdabed1e5167a8f1407e06a14bb89f035addbb13851c1c5b6672ef8e089205f7f6d300cdd8 + languageName: node + linkType: hard + +"@msgpackr-extract/msgpackr-extract-darwin-arm64@npm:3.0.2": + version: 3.0.2 + resolution: "@msgpackr-extract/msgpackr-extract-darwin-arm64@npm:3.0.2" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@msgpackr-extract/msgpackr-extract-darwin-x64@npm:3.0.2": + version: 3.0.2 + resolution: "@msgpackr-extract/msgpackr-extract-darwin-x64@npm:3.0.2" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@msgpackr-extract/msgpackr-extract-linux-arm64@npm:3.0.2": + version: 3.0.2 + resolution: "@msgpackr-extract/msgpackr-extract-linux-arm64@npm:3.0.2" + conditions: os=linux & cpu=arm64 + languageName: node + linkType: hard + +"@msgpackr-extract/msgpackr-extract-linux-arm@npm:3.0.2": + version: 3.0.2 + resolution: "@msgpackr-extract/msgpackr-extract-linux-arm@npm:3.0.2" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + +"@msgpackr-extract/msgpackr-extract-linux-x64@npm:3.0.2": + version: 3.0.2 + resolution: "@msgpackr-extract/msgpackr-extract-linux-x64@npm:3.0.2" + conditions: os=linux & cpu=x64 + languageName: node + linkType: hard + +"@msgpackr-extract/msgpackr-extract-win32-x64@npm:3.0.2": + version: 3.0.2 + resolution: "@msgpackr-extract/msgpackr-extract-win32-x64@npm:3.0.2" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"@npmcli/agent@npm:^2.0.0": + version: 2.2.0 + resolution: "@npmcli/agent@npm:2.2.0" + dependencies: + agent-base: "npm:^7.1.0" + http-proxy-agent: "npm:^7.0.0" + https-proxy-agent: "npm:^7.0.1" + lru-cache: "npm:^10.0.1" + socks-proxy-agent: "npm:^8.0.1" + checksum: 7b89590598476dda88e79c473766b67c682aae6e0ab0213491daa6083dcc0c171f86b3868f5506f22c09aa5ea69ad7dfb78f4bf39a8dca375d89a42f408645b3 + languageName: node + linkType: hard + +"@npmcli/fs@npm:^3.1.0": + version: 3.1.0 + resolution: "@npmcli/fs@npm:3.1.0" + dependencies: + semver: "npm:^7.3.5" + checksum: 162b4a0b8705cd6f5c2470b851d1dc6cd228c86d2170e1769d738c1fbb69a87160901411c3c035331e9e99db72f1f1099a8b734bf1637cc32b9a5be1660e4e1e + languageName: node + linkType: hard + +"@parcel/bundler-default@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/bundler-default@npm:2.11.0" + dependencies: + "@parcel/diagnostic": "npm:2.11.0" + "@parcel/graph": "npm:3.1.0" + "@parcel/plugin": "npm:2.11.0" + "@parcel/rust": "npm:2.11.0" + "@parcel/utils": "npm:2.11.0" + nullthrows: "npm:^1.1.1" + checksum: 02642bff54605cd7c2198c25dc280fd2ac539d5c071b4acf083a82324c1427f4fc779e84a5d78f9dad8f4d769a018584e82f1b33170b3cc8a1895e7042dd91c6 + languageName: node + linkType: hard + +"@parcel/cache@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/cache@npm:2.11.0" + dependencies: + "@parcel/fs": "npm:2.11.0" + "@parcel/logger": "npm:2.11.0" + "@parcel/utils": "npm:2.11.0" + lmdb: "npm:2.8.5" + peerDependencies: + "@parcel/core": ^2.11.0 + checksum: 31806d96248a49361b0fcc445852dc87db3e25d6e6fe21aafcf7a9514a6568b38243539d571b71494af4358c6989c7959150ead746958e6f2494fca0d9fe3ac1 + languageName: node + linkType: hard + +"@parcel/codeframe@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/codeframe@npm:2.11.0" + dependencies: + chalk: "npm:^4.1.0" + checksum: a2ba082794394ad62e9e4e5e2b1c0575b38c187e8ae48f02a8c5f0a1c72fe1936670d91f0a23a1134445b23b62afcdf1ced4816a869d5e085715881b6df31a5b + languageName: node + linkType: hard + +"@parcel/compressor-raw@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/compressor-raw@npm:2.11.0" + dependencies: + "@parcel/plugin": "npm:2.11.0" + checksum: fd4f593e1ed1e7107d99a59edc516e630f3e6decd5ea831881b735d1f484dacfbab0b9a1cae58f0a20e6ee781024afe434e9bebfb581368879562b9f7a70e90f + languageName: node + linkType: hard + +"@parcel/config-default@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/config-default@npm:2.11.0" + dependencies: + "@parcel/bundler-default": "npm:2.11.0" + "@parcel/compressor-raw": "npm:2.11.0" + "@parcel/namer-default": "npm:2.11.0" + "@parcel/optimizer-css": "npm:2.11.0" + "@parcel/optimizer-htmlnano": "npm:2.11.0" + "@parcel/optimizer-image": "npm:2.11.0" + "@parcel/optimizer-svgo": "npm:2.11.0" + "@parcel/optimizer-swc": "npm:2.11.0" + "@parcel/packager-css": "npm:2.11.0" + "@parcel/packager-html": "npm:2.11.0" + "@parcel/packager-js": "npm:2.11.0" + "@parcel/packager-raw": "npm:2.11.0" + "@parcel/packager-svg": "npm:2.11.0" + "@parcel/packager-wasm": "npm:2.11.0" + "@parcel/reporter-dev-server": "npm:2.11.0" + "@parcel/resolver-default": "npm:2.11.0" + "@parcel/runtime-browser-hmr": "npm:2.11.0" + "@parcel/runtime-js": "npm:2.11.0" + "@parcel/runtime-react-refresh": "npm:2.11.0" + "@parcel/runtime-service-worker": "npm:2.11.0" + "@parcel/transformer-babel": "npm:2.11.0" + "@parcel/transformer-css": "npm:2.11.0" + "@parcel/transformer-html": "npm:2.11.0" + "@parcel/transformer-image": "npm:2.11.0" + "@parcel/transformer-js": "npm:2.11.0" + "@parcel/transformer-json": "npm:2.11.0" + "@parcel/transformer-postcss": "npm:2.11.0" + "@parcel/transformer-posthtml": "npm:2.11.0" + "@parcel/transformer-raw": "npm:2.11.0" + "@parcel/transformer-react-refresh-wrap": "npm:2.11.0" + "@parcel/transformer-svg": "npm:2.11.0" + peerDependencies: + "@parcel/core": ^2.11.0 + checksum: cda26bcdbe4400bd31ae71420f8a9b121cad14027f3681d74236834558fe7b94623ede25e54301a861f73d8a48199e089ba338dc859773fa4cc02bb96200e033 + languageName: node + linkType: hard + +"@parcel/core@npm:2.11.0, @parcel/core@npm:^2.11.0": + version: 2.11.0 + resolution: "@parcel/core@npm:2.11.0" + dependencies: + "@mischnic/json-sourcemap": "npm:^0.1.0" + "@parcel/cache": "npm:2.11.0" + "@parcel/diagnostic": "npm:2.11.0" + "@parcel/events": "npm:2.11.0" + "@parcel/fs": "npm:2.11.0" + "@parcel/graph": "npm:3.1.0" + "@parcel/logger": "npm:2.11.0" + "@parcel/package-manager": "npm:2.11.0" + "@parcel/plugin": "npm:2.11.0" + "@parcel/profiler": "npm:2.11.0" + "@parcel/rust": "npm:2.11.0" + "@parcel/source-map": "npm:^2.1.1" + "@parcel/types": "npm:2.11.0" + "@parcel/utils": "npm:2.11.0" + "@parcel/workers": "npm:2.11.0" + abortcontroller-polyfill: "npm:^1.1.9" + base-x: "npm:^3.0.8" + browserslist: "npm:^4.6.6" + clone: "npm:^2.1.1" + dotenv: "npm:^7.0.0" + dotenv-expand: "npm:^5.1.0" + json5: "npm:^2.2.0" + msgpackr: "npm:^1.9.9" + nullthrows: "npm:^1.1.1" + semver: "npm:^7.5.2" + checksum: 8fd40b501ba92fb52e24821772584ece912e77a50bc5503d706ff41ae2250d2be68246284ae62a6b4f1ffa14845e5302faa24700ebc3aa9e4bbfc49fae1cfa41 + languageName: node + linkType: hard + +"@parcel/diagnostic@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/diagnostic@npm:2.11.0" + dependencies: + "@mischnic/json-sourcemap": "npm:^0.1.0" + nullthrows: "npm:^1.1.1" + checksum: 804650d4bd85f861a674e49fc1fcfab9a1bf6d172e392a56fc4942ced2f747a6f4df14654ee784b99b0580c4badcdcd4f5b4ca53f96768d9dd4fe4ee19722236 + languageName: node + linkType: hard + +"@parcel/events@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/events@npm:2.11.0" + checksum: 63bf1e2352a6312165fcb50d11b508526fd3aaa702afcacbd8c7ea4a22861ff49f196c6ba872564b58100cbfc2b08a75e35d51b78e645242911650e28215446f + languageName: node + linkType: hard + +"@parcel/fs@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/fs@npm:2.11.0" + dependencies: + "@parcel/rust": "npm:2.11.0" + "@parcel/types": "npm:2.11.0" + "@parcel/utils": "npm:2.11.0" + "@parcel/watcher": "npm:^2.0.7" + "@parcel/workers": "npm:2.11.0" + peerDependencies: + "@parcel/core": ^2.11.0 + checksum: 00c863be1b4819bcbec2e8c4c5963e7c1afad06bd17085cf67f5863777b21ce8b5a3b640cee30cc93e3b72f3121aa25d7d3a68bd6fe10a716680bd6d7069c9f1 + languageName: node + linkType: hard + +"@parcel/graph@npm:3.1.0": + version: 3.1.0 + resolution: "@parcel/graph@npm:3.1.0" + dependencies: + nullthrows: "npm:^1.1.1" + checksum: 581eece2be3bf94e8eb0f07091bf2d03979da239f5e618079f979c2eca79cae58e6e7a240d767cfb340165e994b5b1df65d7046de06663f986b4491e92988494 + languageName: node + linkType: hard + +"@parcel/logger@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/logger@npm:2.11.0" + dependencies: + "@parcel/diagnostic": "npm:2.11.0" + "@parcel/events": "npm:2.11.0" + checksum: ebac7976abb25c80e75d5e152c54406a473416b90adb523a14fe6a41e25eb5f255a0679f64526f4e723179233caf689588eaa8a2e487c252d3cf4e7a2d65481f + languageName: node + linkType: hard + +"@parcel/markdown-ansi@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/markdown-ansi@npm:2.11.0" + dependencies: + chalk: "npm:^4.1.0" + checksum: 815c622e8b179554bc5a88b1ea2d92513b6974ce4c6577c0f7f5b523550bb3d11351f28e165d58663789ad7ec1a2a1b1e81e016e915aa5bfbd018c736cfbb15e + languageName: node + linkType: hard + +"@parcel/namer-default@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/namer-default@npm:2.11.0" + dependencies: + "@parcel/diagnostic": "npm:2.11.0" + "@parcel/plugin": "npm:2.11.0" + nullthrows: "npm:^1.1.1" + checksum: 76b41c0da23d9eac095830b821ca80bae01514ecbc4cdf522bee867b577de663fac81f4d3c8ef9c8433d9c755050cac611df28c8720a1747ab4b545a7a0bf750 + languageName: node + linkType: hard + +"@parcel/node-resolver-core@npm:3.2.0": + version: 3.2.0 + resolution: "@parcel/node-resolver-core@npm:3.2.0" + dependencies: + "@mischnic/json-sourcemap": "npm:^0.1.0" + "@parcel/diagnostic": "npm:2.11.0" + "@parcel/fs": "npm:2.11.0" + "@parcel/rust": "npm:2.11.0" + "@parcel/utils": "npm:2.11.0" + nullthrows: "npm:^1.1.1" + semver: "npm:^7.5.2" + checksum: 767e0a93f33475fd02440075d7433cd419c23bf904f8e751a6549d5f415142c0f05db690b0ccc3f97b91de8db4842b07c996407bf01ea36cce9233997428e91a + languageName: node + linkType: hard + +"@parcel/optimizer-css@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/optimizer-css@npm:2.11.0" + dependencies: + "@parcel/diagnostic": "npm:2.11.0" + "@parcel/plugin": "npm:2.11.0" + "@parcel/source-map": "npm:^2.1.1" + "@parcel/utils": "npm:2.11.0" + browserslist: "npm:^4.6.6" + lightningcss: "npm:^1.22.1" + nullthrows: "npm:^1.1.1" + checksum: 23de090d4cfb75cd318ae7842fa073fd99381e65292ab9011f88c72a049382a8ea2c91958dd71392ecd707df08a446f4f6c9abdabcb056a5182be04f7895fa72 + languageName: node + linkType: hard + +"@parcel/optimizer-htmlnano@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/optimizer-htmlnano@npm:2.11.0" + dependencies: + "@parcel/plugin": "npm:2.11.0" + htmlnano: "npm:^2.0.0" + nullthrows: "npm:^1.1.1" + posthtml: "npm:^0.16.5" + svgo: "npm:^2.4.0" + checksum: 900658a9447fe396dd959fff2ca3ad483fc60c3eb91055c62fce7c6493056a490db85380c7af15aa8056af2ffbda2540e6f280a82954f46eb67e112f2e7f919e + languageName: node + linkType: hard + +"@parcel/optimizer-image@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/optimizer-image@npm:2.11.0" + dependencies: + "@parcel/diagnostic": "npm:2.11.0" + "@parcel/plugin": "npm:2.11.0" + "@parcel/rust": "npm:2.11.0" + "@parcel/utils": "npm:2.11.0" + "@parcel/workers": "npm:2.11.0" + peerDependencies: + "@parcel/core": ^2.11.0 + checksum: 6bcdfeba1ce7ee91a273a486f176e802b665279843004ab71f0ecc6c31bf1c718d1709e87e63b2a882c987605f5eadf35912a1342658878d43045d5c5b4640c4 + languageName: node + linkType: hard + +"@parcel/optimizer-svgo@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/optimizer-svgo@npm:2.11.0" + dependencies: + "@parcel/diagnostic": "npm:2.11.0" + "@parcel/plugin": "npm:2.11.0" + "@parcel/utils": "npm:2.11.0" + svgo: "npm:^2.4.0" + checksum: 501ee32a5f5955a6a035bab95b446e4ca4d0e697b75ef45d15049bfb0e9873f6b136fc1750cb88951f91f341dc6237194a415322232161552ff5b47e9b11d464 + languageName: node + linkType: hard + +"@parcel/optimizer-swc@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/optimizer-swc@npm:2.11.0" + dependencies: + "@parcel/diagnostic": "npm:2.11.0" + "@parcel/plugin": "npm:2.11.0" + "@parcel/source-map": "npm:^2.1.1" + "@parcel/utils": "npm:2.11.0" + "@swc/core": "npm:^1.3.36" + nullthrows: "npm:^1.1.1" + checksum: b680d7c7a79e8b98a7cfe4016f7dd43ebf7e75f1131dcc91c9a6f1c6a937d429c13aaea03497f6ed5ce3c6620d716422ae5227c037dff2b9ad7b10d954dbb052 + languageName: node + linkType: hard + +"@parcel/package-manager@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/package-manager@npm:2.11.0" + dependencies: + "@parcel/diagnostic": "npm:2.11.0" + "@parcel/fs": "npm:2.11.0" + "@parcel/logger": "npm:2.11.0" + "@parcel/node-resolver-core": "npm:3.2.0" + "@parcel/types": "npm:2.11.0" + "@parcel/utils": "npm:2.11.0" + "@parcel/workers": "npm:2.11.0" + semver: "npm:^7.5.2" + peerDependencies: + "@parcel/core": ^2.11.0 + checksum: 4f8f3fbf4f6875b11f402f0ba7919fa6e390d993ad26a46f888e459622dd3a3ced821d8dea3892888358d9b54eca45996c6794597a1e17c91e00a9f493cabb38 + languageName: node + linkType: hard + +"@parcel/packager-css@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/packager-css@npm:2.11.0" + dependencies: + "@parcel/diagnostic": "npm:2.11.0" + "@parcel/plugin": "npm:2.11.0" + "@parcel/source-map": "npm:^2.1.1" + "@parcel/utils": "npm:2.11.0" + nullthrows: "npm:^1.1.1" + checksum: a931338a460160b7eb3d938dcccdade0192c9087c4d75fd5fdfc79c9fd0413735bee910fcd8f6f47742c76681636b354f9d876db9e846da35044b40c88adce5c + languageName: node + linkType: hard + +"@parcel/packager-html@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/packager-html@npm:2.11.0" + dependencies: + "@parcel/plugin": "npm:2.11.0" + "@parcel/types": "npm:2.11.0" + "@parcel/utils": "npm:2.11.0" + nullthrows: "npm:^1.1.1" + posthtml: "npm:^0.16.5" + checksum: 37e33696181b027f6a8d8972d6f87d18bfca52612cc50253995aacf6bf7a65051a1490cbb7d0b75c9bd880f2365219f7ba23f7fd28e7ae3989eb0ec05b3d122a + languageName: node + linkType: hard + +"@parcel/packager-js@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/packager-js@npm:2.11.0" + dependencies: + "@parcel/diagnostic": "npm:2.11.0" + "@parcel/plugin": "npm:2.11.0" + "@parcel/rust": "npm:2.11.0" + "@parcel/source-map": "npm:^2.1.1" + "@parcel/types": "npm:2.11.0" + "@parcel/utils": "npm:2.11.0" + globals: "npm:^13.2.0" + nullthrows: "npm:^1.1.1" + checksum: 0274e2f7864699f1ef7b8c7cd804924819ed6a02dea5e49648a7f90ba64a6ace9ff43d65a23a58342bd06b629405cafcba1f7b67094c9bd9f4e8a60433b4651c + languageName: node + linkType: hard + +"@parcel/packager-raw-url@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/packager-raw-url@npm:2.11.0" + dependencies: + "@parcel/plugin": "npm:2.11.0" + "@parcel/utils": "npm:2.11.0" + checksum: 33b7a53fec17999cf3727b33c7dc747c36ff1a5bdf8f67d58a016989bf10e802bc632e810af6f812be4bf41ffce53bc905bf57ab77ceaea62962cbeae9ab076b + languageName: node + linkType: hard + +"@parcel/packager-raw@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/packager-raw@npm:2.11.0" + dependencies: + "@parcel/plugin": "npm:2.11.0" + checksum: 48edd1f48017363bc11c6c3318ea0d8662d2f643beb5c0201d7ab24b6033f2827d989aa7c5cc28ef653a9c2238b511223212904c05dafcafe0b057027d798ac0 + languageName: node + linkType: hard + +"@parcel/packager-svg@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/packager-svg@npm:2.11.0" + dependencies: + "@parcel/plugin": "npm:2.11.0" + "@parcel/types": "npm:2.11.0" + "@parcel/utils": "npm:2.11.0" + posthtml: "npm:^0.16.4" + checksum: 7b6d59673d04973d3867866038b714cc6137b37a76030289fd88eba95998bcf78c1876b3b913f46349bf1261571344ff0e865acb3498531ddfe5d800cf3b212d + languageName: node + linkType: hard + +"@parcel/packager-wasm@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/packager-wasm@npm:2.11.0" + dependencies: + "@parcel/plugin": "npm:2.11.0" + checksum: 6ea86622781a6eab2f73eb68e7ccc0961f9616d13a27b7c7867b25968dc97f94a2223daa3f045440f813ec7d66e2feb57f0aacc7c8c5af10ca6c47bf80d4a424 + languageName: node + linkType: hard + +"@parcel/plugin@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/plugin@npm:2.11.0" + dependencies: + "@parcel/types": "npm:2.11.0" + checksum: dece02540744a0bd7638063b05cb2388fc8ee3329ef151c11587f56457ccfddc6d69ae7668de29b9c8b95bd5b00b10b4dc90a8426b51f981332a515138d7a809 + languageName: node + linkType: hard + +"@parcel/profiler@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/profiler@npm:2.11.0" + dependencies: + "@parcel/diagnostic": "npm:2.11.0" + "@parcel/events": "npm:2.11.0" + chrome-trace-event: "npm:^1.0.2" + checksum: 22175fb949cade784b60341478ba5c3e392d26b96055fb3b5a6abf75f0df01fdc5fd4e72c8e29b82773737fc7d2951d30f3f1850f208caf1d33d148daa1eff9e + languageName: node + linkType: hard + +"@parcel/reporter-cli@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/reporter-cli@npm:2.11.0" + dependencies: + "@parcel/plugin": "npm:2.11.0" + "@parcel/types": "npm:2.11.0" + "@parcel/utils": "npm:2.11.0" + chalk: "npm:^4.1.0" + cli-progress: "npm:^3.12.0" + term-size: "npm:^2.2.1" + checksum: e60b82080c0c2f2eb2df73a265ad94b7bf049968b3963ba7377ad531826235bad4e2ea8d9de3c42a1be289f6f4051a13cb9568fd0335f52d290ad30ebb404489 + languageName: node + linkType: hard + +"@parcel/reporter-dev-server@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/reporter-dev-server@npm:2.11.0" + dependencies: + "@parcel/plugin": "npm:2.11.0" + "@parcel/utils": "npm:2.11.0" + checksum: 28b9f17a3d636a15a5fd1763d314f61860b798a7ce26827dd7c5024bca715e9abb39ed59675814abd3cd1832094f19c96ed65c5508482a76e44100c810452287 + languageName: node + linkType: hard + +"@parcel/reporter-tracer@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/reporter-tracer@npm:2.11.0" + dependencies: + "@parcel/plugin": "npm:2.11.0" + "@parcel/utils": "npm:2.11.0" + chrome-trace-event: "npm:^1.0.3" + nullthrows: "npm:^1.1.1" + checksum: a7c4d5c7502860be554c8751c145413908e2b8167e62a20c0ce15e846daa5c3eb497c603937fe6a8b2ead39761e7b596281c9719d8b1188678e2606b07af362c + languageName: node + linkType: hard + +"@parcel/resolver-default@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/resolver-default@npm:2.11.0" + dependencies: + "@parcel/node-resolver-core": "npm:3.2.0" + "@parcel/plugin": "npm:2.11.0" + checksum: 78c589f9dfea0d568e95ebda6d4344c141ede70686d3528e38a5ca90286af4bdbb7e15133abc4ac59081f14549673b2fd42c071463842229b994dacea63f73a4 + languageName: node + linkType: hard + +"@parcel/runtime-browser-hmr@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/runtime-browser-hmr@npm:2.11.0" + dependencies: + "@parcel/plugin": "npm:2.11.0" + "@parcel/utils": "npm:2.11.0" + checksum: 1735b82a0c0692c8324f0c01a0d428f3ee69009fb475eabdf5b1485b013969c0ce5499f380db85eb1fb6613573fe839a7e6da232b41fb8ab3ff1542c1fdb2752 + languageName: node + linkType: hard + +"@parcel/runtime-js@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/runtime-js@npm:2.11.0" + dependencies: + "@parcel/diagnostic": "npm:2.11.0" + "@parcel/plugin": "npm:2.11.0" + "@parcel/utils": "npm:2.11.0" + nullthrows: "npm:^1.1.1" + checksum: 14554128eaca504c9ce16fc88bdf311e512201b1d5d906bd123d11469d7b098886b49b3fb10b58a8d7cf6f290796f352f054695943ea717c640cca6572284357 + languageName: node + linkType: hard + +"@parcel/runtime-react-refresh@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/runtime-react-refresh@npm:2.11.0" + dependencies: + "@parcel/plugin": "npm:2.11.0" + "@parcel/utils": "npm:2.11.0" + react-error-overlay: "npm:6.0.9" + react-refresh: "npm:^0.9.0" + checksum: 987b6054f13aa56cef767d1196ea78f84c0e358cd3821f4c0611a0acb96f208a479cfbff807d8b997eeabe254465eddc9ec33bb26886194161afdb3b38967021 + languageName: node + linkType: hard + +"@parcel/runtime-service-worker@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/runtime-service-worker@npm:2.11.0" + dependencies: + "@parcel/plugin": "npm:2.11.0" + "@parcel/utils": "npm:2.11.0" + nullthrows: "npm:^1.1.1" + checksum: 8f5c8f2eca378f49707fe6f77fab3a947d5f56b2046d0a84285233e4cf3fe780f62e6f861bc7bef9eeec3cc08d8135163731a48d9af90c17a74cb203fb9b3318 + languageName: node + linkType: hard + +"@parcel/rust@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/rust@npm:2.11.0" + checksum: 70f52f830e09081cfd25795aa40fdd0b1a2fee2344537a54b60ab3100ba59389edd43380ae7f7b4de597ff0d450076de23546942167753a4402f7001d13fea22 + languageName: node + linkType: hard + +"@parcel/source-map@npm:^2.1.1": + version: 2.1.1 + resolution: "@parcel/source-map@npm:2.1.1" + dependencies: + detect-libc: "npm:^1.0.3" + checksum: cea8450e152666be413556f0d100f125e81646bffc497e7c792bd9fc5067d052f1a008c8404ce1cd3a587d58b9ef57207ada89149cf2c705e71b1978308045f6 + languageName: node + linkType: hard + +"@parcel/transformer-babel@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/transformer-babel@npm:2.11.0" + dependencies: + "@parcel/diagnostic": "npm:2.11.0" + "@parcel/plugin": "npm:2.11.0" + "@parcel/source-map": "npm:^2.1.1" + "@parcel/utils": "npm:2.11.0" + browserslist: "npm:^4.6.6" + json5: "npm:^2.2.0" + nullthrows: "npm:^1.1.1" + semver: "npm:^7.5.2" + checksum: b953b2523b9dc7ab0b3781370cb53b3bcd51eccbea3804d7f39d3c49bfa338f89decdeb2498b8cef9edca742b4f9980dc5bbd2c461569931bd7b5cc59f0d38bb + languageName: node + linkType: hard + +"@parcel/transformer-css@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/transformer-css@npm:2.11.0" + dependencies: + "@parcel/diagnostic": "npm:2.11.0" + "@parcel/plugin": "npm:2.11.0" + "@parcel/source-map": "npm:^2.1.1" + "@parcel/utils": "npm:2.11.0" + browserslist: "npm:^4.6.6" + lightningcss: "npm:^1.22.1" + nullthrows: "npm:^1.1.1" + checksum: fba5af5c7a83e95100a86c8655c57a8e009ee0b51eea86e4a13161f3b6547cf8ef9242d0f17734046007e4bee7b51086de6ed25b2453455db77df8989b2571e8 + languageName: node + linkType: hard + +"@parcel/transformer-html@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/transformer-html@npm:2.11.0" + dependencies: + "@parcel/diagnostic": "npm:2.11.0" + "@parcel/plugin": "npm:2.11.0" + "@parcel/rust": "npm:2.11.0" + nullthrows: "npm:^1.1.1" + posthtml: "npm:^0.16.5" + posthtml-parser: "npm:^0.10.1" + posthtml-render: "npm:^3.0.0" + semver: "npm:^7.5.2" + srcset: "npm:4" + checksum: 2ad043ef09155262e8ea4c8e4a2443d7dd52ced8e6ae60668adecc2f1e1712d79275482da9edd95676dda087d94a088b774099f319915c1a2591adf3b77136a3 + languageName: node + linkType: hard + +"@parcel/transformer-image@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/transformer-image@npm:2.11.0" + dependencies: + "@parcel/plugin": "npm:2.11.0" + "@parcel/utils": "npm:2.11.0" + "@parcel/workers": "npm:2.11.0" + nullthrows: "npm:^1.1.1" + peerDependencies: + "@parcel/core": ^2.11.0 + checksum: 752ef6b6c619207bb2e13cea43d5bb9052c2878fd62edbf158a9d49628fc54099f35650634d57d0c609227c31dd0f6a4ae76b3192de2e775eff64741ce345d85 + languageName: node + linkType: hard + +"@parcel/transformer-inline-string@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/transformer-inline-string@npm:2.11.0" + dependencies: + "@parcel/plugin": "npm:2.11.0" + checksum: 36d829a703a2cce20879412347a6738b7c2faea59ca5e0d3f8e3a5ed5ec51a53185f929b32fe8ac726679cfdc51224f3e82c59e9d4ee6d9bbe460bdcf7a6591f + languageName: node + linkType: hard + +"@parcel/transformer-js@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/transformer-js@npm:2.11.0" + dependencies: + "@parcel/diagnostic": "npm:2.11.0" + "@parcel/plugin": "npm:2.11.0" + "@parcel/rust": "npm:2.11.0" + "@parcel/source-map": "npm:^2.1.1" + "@parcel/utils": "npm:2.11.0" + "@parcel/workers": "npm:2.11.0" + "@swc/helpers": "npm:^0.5.0" + browserslist: "npm:^4.6.6" + nullthrows: "npm:^1.1.1" + regenerator-runtime: "npm:^0.13.7" + semver: "npm:^7.5.2" + peerDependencies: + "@parcel/core": ^2.11.0 + checksum: 2cbb6d2f7fe04c9883873e6d8daa58ba58ccba9f592f46f1d901ad24167658b10e643d18c3bc725a47f322dd22bfb4db12c4315bae761059989aaef3d442c8d1 + languageName: node + linkType: hard + +"@parcel/transformer-json@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/transformer-json@npm:2.11.0" + dependencies: + "@parcel/plugin": "npm:2.11.0" + json5: "npm:^2.2.0" + checksum: c0d6bc771c673b3ccc73ae52298c5e00bb2540ca276151a2057a813d580f9854bc8600e2d343c0731285df8da47618ac9eea714d3d392949c0ebd97b4a6da6b5 + languageName: node + linkType: hard + +"@parcel/transformer-postcss@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/transformer-postcss@npm:2.11.0" + dependencies: + "@parcel/diagnostic": "npm:2.11.0" + "@parcel/plugin": "npm:2.11.0" + "@parcel/rust": "npm:2.11.0" + "@parcel/utils": "npm:2.11.0" + clone: "npm:^2.1.1" + nullthrows: "npm:^1.1.1" + postcss-value-parser: "npm:^4.2.0" + semver: "npm:^7.5.2" + checksum: af7699b9044d7dfd03eae05d91e08d9beff0b528af8d43fe936943f42fda850e692e4762ba381018a1244694808ca96aaebfd642fabfc4ee6767d10da1db60ae + languageName: node + linkType: hard + +"@parcel/transformer-posthtml@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/transformer-posthtml@npm:2.11.0" + dependencies: + "@parcel/plugin": "npm:2.11.0" + "@parcel/utils": "npm:2.11.0" + nullthrows: "npm:^1.1.1" + posthtml: "npm:^0.16.5" + posthtml-parser: "npm:^0.10.1" + posthtml-render: "npm:^3.0.0" + semver: "npm:^7.5.2" + checksum: 8e1c4de3a403ea09cf924fb30110ad83f484a2af94a52dcb487c5e7ee42d78e3298b585ef5ccc46594191928372310ffdde27c366d265ae8be9bce79d5db07f5 + languageName: node + linkType: hard + +"@parcel/transformer-raw@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/transformer-raw@npm:2.11.0" + dependencies: + "@parcel/plugin": "npm:2.11.0" + checksum: b670e2064283c3e8e67bd0d94cc73e9fba729b1dfa43ab1dc42c6d441ee4c13317562578240e416a5a3717180f389baaebfa9c2311a35c56f2b538e90af3496c + languageName: node + linkType: hard + +"@parcel/transformer-react-refresh-wrap@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/transformer-react-refresh-wrap@npm:2.11.0" + dependencies: + "@parcel/plugin": "npm:2.11.0" + "@parcel/utils": "npm:2.11.0" + react-refresh: "npm:^0.9.0" + checksum: a609c75db15a0c543a0b0c9e0e1c584b60eeee2b0582e133488fccfbec14581051a3137ee838ee0daab0303531aacac50419381212dc62fa1808924b2c05ded4 + languageName: node + linkType: hard + +"@parcel/transformer-svg@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/transformer-svg@npm:2.11.0" + dependencies: + "@parcel/diagnostic": "npm:2.11.0" + "@parcel/plugin": "npm:2.11.0" + "@parcel/rust": "npm:2.11.0" + nullthrows: "npm:^1.1.1" + posthtml: "npm:^0.16.5" + posthtml-parser: "npm:^0.10.1" + posthtml-render: "npm:^3.0.0" + semver: "npm:^7.5.2" + checksum: e434c18759f62a3028fdf78969bbe30128274c513d7e6f512e525e78fd9d8fa9ca8393b7d1f69d4573e59d020a591d35d6edabe99c175fb6ae38c8d95404b23a + languageName: node + linkType: hard + +"@parcel/transformer-webmanifest@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/transformer-webmanifest@npm:2.11.0" + dependencies: + "@mischnic/json-sourcemap": "npm:^0.1.0" + "@parcel/diagnostic": "npm:2.11.0" + "@parcel/plugin": "npm:2.11.0" + "@parcel/utils": "npm:2.11.0" + checksum: 984fe124af4286af4ac2ad20da920ba3d457482f230d33e6dd7cc0e126639dccf064bf104fb7c142039ca4dae5725332f96fea967f2c97746383ad84bf5ed717 + languageName: node + linkType: hard + +"@parcel/types@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/types@npm:2.11.0" + dependencies: + "@parcel/cache": "npm:2.11.0" + "@parcel/diagnostic": "npm:2.11.0" + "@parcel/fs": "npm:2.11.0" + "@parcel/package-manager": "npm:2.11.0" + "@parcel/source-map": "npm:^2.1.1" + "@parcel/workers": "npm:2.11.0" + utility-types: "npm:^3.10.0" + checksum: bbae4c0690a686ca55db55867b91ed56396d1bc7b092c65dd82feff2baf6123deb15d75fd49fa6ef5a4f7206b9017fc00ebab61799e74f748b70e8f7fb409810 + languageName: node + linkType: hard + +"@parcel/utils@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/utils@npm:2.11.0" + dependencies: + "@parcel/codeframe": "npm:2.11.0" + "@parcel/diagnostic": "npm:2.11.0" + "@parcel/logger": "npm:2.11.0" + "@parcel/markdown-ansi": "npm:2.11.0" + "@parcel/rust": "npm:2.11.0" + "@parcel/source-map": "npm:^2.1.1" + chalk: "npm:^4.1.0" + nullthrows: "npm:^1.1.1" + checksum: 5af306021784b47cdf27763c279b02523aff84b0f883f1cf308c34fa743dc47c30806dfdda66291fdfa0bc040aa50e8cbbfc97a3bf7b745bda002b0340c89def + languageName: node + linkType: hard + +"@parcel/watcher-android-arm64@npm:2.4.0": + version: 2.4.0 + resolution: "@parcel/watcher-android-arm64@npm:2.4.0" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + +"@parcel/watcher-darwin-arm64@npm:2.4.0": + version: 2.4.0 + resolution: "@parcel/watcher-darwin-arm64@npm:2.4.0" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@parcel/watcher-darwin-x64@npm:2.4.0": + version: 2.4.0 + resolution: "@parcel/watcher-darwin-x64@npm:2.4.0" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@parcel/watcher-freebsd-x64@npm:2.4.0": + version: 2.4.0 + resolution: "@parcel/watcher-freebsd-x64@npm:2.4.0" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + +"@parcel/watcher-linux-arm-glibc@npm:2.4.0": + version: 2.4.0 + resolution: "@parcel/watcher-linux-arm-glibc@npm:2.4.0" + conditions: os=linux & cpu=arm & libc=glibc + languageName: node + linkType: hard + +"@parcel/watcher-linux-arm64-glibc@npm:2.4.0": + version: 2.4.0 + resolution: "@parcel/watcher-linux-arm64-glibc@npm:2.4.0" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + +"@parcel/watcher-linux-arm64-musl@npm:2.4.0": + version: 2.4.0 + resolution: "@parcel/watcher-linux-arm64-musl@npm:2.4.0" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + +"@parcel/watcher-linux-x64-glibc@npm:2.4.0": + version: 2.4.0 + resolution: "@parcel/watcher-linux-x64-glibc@npm:2.4.0" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + +"@parcel/watcher-linux-x64-musl@npm:2.4.0": + version: 2.4.0 + resolution: "@parcel/watcher-linux-x64-musl@npm:2.4.0" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + +"@parcel/watcher-win32-arm64@npm:2.4.0": + version: 2.4.0 + resolution: "@parcel/watcher-win32-arm64@npm:2.4.0" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@parcel/watcher-win32-ia32@npm:2.4.0": + version: 2.4.0 + resolution: "@parcel/watcher-win32-ia32@npm:2.4.0" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + +"@parcel/watcher-win32-x64@npm:2.4.0": + version: 2.4.0 + resolution: "@parcel/watcher-win32-x64@npm:2.4.0" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"@parcel/watcher@npm:^2.0.7": + version: 2.4.0 + resolution: "@parcel/watcher@npm:2.4.0" + dependencies: + "@parcel/watcher-android-arm64": "npm:2.4.0" + "@parcel/watcher-darwin-arm64": "npm:2.4.0" + "@parcel/watcher-darwin-x64": "npm:2.4.0" + "@parcel/watcher-freebsd-x64": "npm:2.4.0" + "@parcel/watcher-linux-arm-glibc": "npm:2.4.0" + "@parcel/watcher-linux-arm64-glibc": "npm:2.4.0" + "@parcel/watcher-linux-arm64-musl": "npm:2.4.0" + "@parcel/watcher-linux-x64-glibc": "npm:2.4.0" + "@parcel/watcher-linux-x64-musl": "npm:2.4.0" + "@parcel/watcher-win32-arm64": "npm:2.4.0" + "@parcel/watcher-win32-ia32": "npm:2.4.0" + "@parcel/watcher-win32-x64": "npm:2.4.0" + detect-libc: "npm:^1.0.3" + is-glob: "npm:^4.0.3" + micromatch: "npm:^4.0.5" + node-addon-api: "npm:^7.0.0" + node-gyp: "npm:latest" + dependenciesMeta: + "@parcel/watcher-android-arm64": + optional: true + "@parcel/watcher-darwin-arm64": + optional: true + "@parcel/watcher-darwin-x64": + optional: true + "@parcel/watcher-freebsd-x64": + optional: true + "@parcel/watcher-linux-arm-glibc": + optional: true + "@parcel/watcher-linux-arm64-glibc": + optional: true + "@parcel/watcher-linux-arm64-musl": + optional: true + "@parcel/watcher-linux-x64-glibc": + optional: true + "@parcel/watcher-linux-x64-musl": + optional: true + "@parcel/watcher-win32-arm64": + optional: true + "@parcel/watcher-win32-ia32": + optional: true + "@parcel/watcher-win32-x64": + optional: true + checksum: f8a7103d8402dceaeed6e7ceef5592ceed6c3ceed7bd747590dbf7b51ca56fd4cb26a6322d1952b4bca52acb41e9d4a13468035b371ef5d264230c4286bf4d0a + languageName: node + linkType: hard + +"@parcel/workers@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/workers@npm:2.11.0" + dependencies: + "@parcel/diagnostic": "npm:2.11.0" + "@parcel/logger": "npm:2.11.0" + "@parcel/profiler": "npm:2.11.0" + "@parcel/types": "npm:2.11.0" + "@parcel/utils": "npm:2.11.0" + nullthrows: "npm:^1.1.1" + peerDependencies: + "@parcel/core": ^2.11.0 + checksum: 60546c1cf54ae38a5bd920e3832a9387ae1183a5553e7dff67adeccaedcaed31d642e7b62a5c33c411cd75d64115d14d1a9fb964341aadd93698d40ae3a0fbf6 + languageName: node + linkType: hard + +"@pixi/accessibility@npm:7.3.3": + version: 7.3.3 + resolution: "@pixi/accessibility@npm:7.3.3" + peerDependencies: + "@pixi/core": 7.3.3 + "@pixi/display": 7.3.3 + "@pixi/events": 7.3.3 + checksum: c832dde1567cbafb8cf2655b034f53b15d5d6e384b0a38f4a49305f01fc43a5c3eef477c5acf47e5e3729d7a507494b259fb6521e8bc46c1bef20fa42b1a3b4c + languageName: node + linkType: hard + +"@pixi/app@npm:7.3.3": + version: 7.3.3 + resolution: "@pixi/app@npm:7.3.3" + peerDependencies: + "@pixi/core": 7.3.3 + "@pixi/display": 7.3.3 + checksum: 73f042aaed6715b70ff837abc9e288e7473c366e1eda24e68365199107eeb68d08be090356e09415846c82061d936694044b5b5e5cf33e61df015fbddd877037 + languageName: node + linkType: hard + +"@pixi/assets@npm:7.3.3": + version: 7.3.3 + resolution: "@pixi/assets@npm:7.3.3" + dependencies: + "@types/css-font-loading-module": "npm:^0.0.12" + peerDependencies: + "@pixi/core": 7.3.3 + checksum: ad0a500ec41fe90f6c3677034852b1ee12d1a5ac41c630af5de9f1497da13461567d29b6dfc3a6c87ba9c548a47956f35c702bff7678c7dcd9be726af973e836 + languageName: node + linkType: hard + +"@pixi/color@npm:7.3.3": + version: 7.3.3 + resolution: "@pixi/color@npm:7.3.3" + dependencies: + "@pixi/colord": "npm:^2.9.6" + checksum: 19bf578abbb09166fe27c2117d0a2a3614074cefeac94f1fff908700798390a3cb6ade77639b8ea8d2499483b0b9f03a16bc916c1568a9ad2ae7674a928a553b + languageName: node + linkType: hard + +"@pixi/colord@npm:^2.9.6": + version: 2.9.6 + resolution: "@pixi/colord@npm:2.9.6" + checksum: 513636a67140b8bb3292eb4a7a3a5303a394525410fe972ebfe1e5db3749f27f7c0f176e4c84fcb9ab0fa22ee1d8ce2a15b3e32db7021e65ac0561941d2933a3 + languageName: node + linkType: hard + +"@pixi/compressed-textures@npm:7.3.3": + version: 7.3.3 + resolution: "@pixi/compressed-textures@npm:7.3.3" + peerDependencies: + "@pixi/assets": 7.3.3 + "@pixi/core": 7.3.3 + checksum: 36e829894425c5ab270fb7be4ff33482e21ab692d759b50ddbed60631a39d968e029e7ee2fec763968bc0f12348b9e36049317c99b74c2e83a0a149080bb4c33 + languageName: node + linkType: hard + +"@pixi/constants@npm:7.3.3": + version: 7.3.3 + resolution: "@pixi/constants@npm:7.3.3" + checksum: 7081728a2b9530a9b1fa845ba873b94f2688b98131e1b34ebaeff2c30c3fec4b4a2e4fa6a447c0be9d26e5a1e8fcbe0a3ee92b3fab0e52deedc1577c702c3781 + languageName: node + linkType: hard + +"@pixi/core@npm:7.3.3, @pixi/core@npm:^7.3.3": + version: 7.3.3 + resolution: "@pixi/core@npm:7.3.3" + dependencies: + "@pixi/color": "npm:7.3.3" + "@pixi/constants": "npm:7.3.3" + "@pixi/extensions": "npm:7.3.3" + "@pixi/math": "npm:7.3.3" + "@pixi/runner": "npm:7.3.3" + "@pixi/settings": "npm:7.3.3" + "@pixi/ticker": "npm:7.3.3" + "@pixi/utils": "npm:7.3.3" + "@types/offscreencanvas": "npm:^2019.6.4" + checksum: dee27b490a2b9cfec242674be15baffd585022ebb96ec3218874afe4d27964c2a94886c1c139b2b371ffe4bc4e9e2e3f1a61e27e4af388b24bc2930d1239c5ae + languageName: node + linkType: hard + +"@pixi/display@npm:7.3.3, @pixi/display@npm:^7.3.3": + version: 7.3.3 + resolution: "@pixi/display@npm:7.3.3" + peerDependencies: + "@pixi/core": 7.3.3 + checksum: d59ffce30f23060d741349ad81805bbe06c61af573d1ae36c8e2437abe9dbb110ca40ccbdbc2fa27e052f595c68616fe6f50b3ffeee2d686032078d6b0604303 + languageName: node + linkType: hard + +"@pixi/events@npm:7.3.3": + version: 7.3.3 + resolution: "@pixi/events@npm:7.3.3" + peerDependencies: + "@pixi/core": 7.3.3 + "@pixi/display": 7.3.3 + checksum: e097ac5d9df51523a1bf271c8e661ff3002540e432cbeb90f8abaf68b9fece836618d7b641a2a71d6cd49f7913e3fd656a2230daca1a0f90271ee17168a620bb + languageName: node + linkType: hard + +"@pixi/extensions@npm:7.3.3": + version: 7.3.3 + resolution: "@pixi/extensions@npm:7.3.3" + checksum: de2bee81f15e70220ba9a2bbab839ae42e701c9f1e52781f2a03144e4a8dbcf80159e4a5c5d73227a3014b1da79008ead6f6304bb4dd784b9390aa6916de79a1 + languageName: node + linkType: hard + +"@pixi/extract@npm:7.3.3": + version: 7.3.3 + resolution: "@pixi/extract@npm:7.3.3" + peerDependencies: + "@pixi/core": 7.3.3 + checksum: 252f5865081e0d9f1f4918be1c9f7cba3c0266b55d49b38ed50eeeee22c8d55a113e0840cc89248a02e72c35f72f763a9cc157b3220e6a9f4f02f0ac07f9b77c + languageName: node + linkType: hard + +"@pixi/filter-alpha@npm:7.3.3": + version: 7.3.3 + resolution: "@pixi/filter-alpha@npm:7.3.3" + peerDependencies: + "@pixi/core": 7.3.3 + checksum: 3c3f6e347c4269c9d7f4738aef77856327eaf50be2eddd4c9379105c84b7b9fc7db98083b46d7303f58caf7024056f8034c3b5538f229da9acd721a143cacdeb + languageName: node + linkType: hard + +"@pixi/filter-blur@npm:7.3.3": + version: 7.3.3 + resolution: "@pixi/filter-blur@npm:7.3.3" + peerDependencies: + "@pixi/core": 7.3.3 + checksum: 3ac7983e7a902b4049500bb9ea1f53e3e6bc0129b38b3a0b8f0f5b1965cd7a7b3de9732be018d25bfd08969025acc51eec0d68bf84b5e34022bce9aabeabd6a5 + languageName: node + linkType: hard + +"@pixi/filter-color-matrix@npm:7.3.3": + version: 7.3.3 + resolution: "@pixi/filter-color-matrix@npm:7.3.3" + peerDependencies: + "@pixi/core": 7.3.3 + checksum: d2dc320ba55f848b562cf062bd05359eefa62112b17d13a365b954e6ef1aecc2743bbb43f7f3fdcb281b05121fb767f27c8bd216f05bbbad044a05e5a843b063 + languageName: node + linkType: hard + +"@pixi/filter-displacement@npm:7.3.3": + version: 7.3.3 + resolution: "@pixi/filter-displacement@npm:7.3.3" + peerDependencies: + "@pixi/core": 7.3.3 + checksum: 586e0a0cde63fdf950c4da10f05208f627a4811fb65cd8d145e94742d6d5160a685cfec86dab2ac3864fd70a08b1b1a722363bb1ff68ea56d8d3d3db7fedf8b0 + languageName: node + linkType: hard + +"@pixi/filter-fxaa@npm:7.3.3": + version: 7.3.3 + resolution: "@pixi/filter-fxaa@npm:7.3.3" + peerDependencies: + "@pixi/core": 7.3.3 + checksum: 1c04ca3f576a62e1beef67f33cd0b8f4248d7072e3f5eabef77ca4ea05b20eeb2803dd48f17b73ef9929be54f662ef5bccfff3e3f665daac3fc95929124f8e61 + languageName: node + linkType: hard + +"@pixi/filter-noise@npm:7.3.3": + version: 7.3.3 + resolution: "@pixi/filter-noise@npm:7.3.3" + peerDependencies: + "@pixi/core": 7.3.3 + checksum: b917788d060c66403888a88f527627266725dc59501c49dc0df29de62ca70b573d2240f79c877559a648fe68eb471eb0ed74ad92358610f65a3ec8b7cf41cbba + languageName: node + linkType: hard + +"@pixi/graphics@npm:7.3.3": + version: 7.3.3 + resolution: "@pixi/graphics@npm:7.3.3" + peerDependencies: + "@pixi/core": 7.3.3 + "@pixi/display": 7.3.3 + "@pixi/sprite": 7.3.3 + checksum: 952b6bf0df1a511a21d96cca7dc3febaa946082457347a394d4bb4e8426589c4399a17ef90aacb620c1385605e5c57a3dcee89e2a95c436ede3092459ae4f46a + languageName: node + linkType: hard + +"@pixi/math@npm:7.3.3": + version: 7.3.3 + resolution: "@pixi/math@npm:7.3.3" + checksum: 9dd0dc84525de2e5fce642f0cbc6161426c42d21cdf5e146506d00ae6a22d5d2cb7c7baa79e5fd3a0e0f5b74d56845fda7e31b379e5d75a283fd6aa4bf9fe334 + languageName: node + linkType: hard + +"@pixi/mesh-extras@npm:7.3.3": + version: 7.3.3 + resolution: "@pixi/mesh-extras@npm:7.3.3" + peerDependencies: + "@pixi/core": 7.3.3 + "@pixi/mesh": 7.3.3 + checksum: c392b990cdfc5e2a64848ff31123a7743dd57a6ca87e298cbc3881e88aa14e44410354593408d1fc00158f197f42465d15570c98e866a344bc725e8ba310bf65 + languageName: node + linkType: hard + +"@pixi/mesh@npm:7.3.3": + version: 7.3.3 + resolution: "@pixi/mesh@npm:7.3.3" + peerDependencies: + "@pixi/core": 7.3.3 + "@pixi/display": 7.3.3 + checksum: 902b50ac0ad9a7ad95e77f83b49ea684e0cc160a8bca89f9fe9f5b157ae7375ffb3ccd542d8a79972423cebda0307cbb76eb4cc6c030abfc404ac10b98b4de02 + languageName: node + linkType: hard + +"@pixi/mixin-cache-as-bitmap@npm:7.3.3": + version: 7.3.3 + resolution: "@pixi/mixin-cache-as-bitmap@npm:7.3.3" + peerDependencies: + "@pixi/core": 7.3.3 + "@pixi/display": 7.3.3 + "@pixi/sprite": 7.3.3 + checksum: 87beb527f8fb5d7e8090c339ffe7bdb6e6b7387538c63dabea8def45dbce21293adb7e2c79739a6c4b4ffaef34b0853d37cb5c4c7134a774de79c5be3a52b305 + languageName: node + linkType: hard + +"@pixi/mixin-get-child-by-name@npm:7.3.3": + version: 7.3.3 + resolution: "@pixi/mixin-get-child-by-name@npm:7.3.3" + peerDependencies: + "@pixi/display": 7.3.3 + checksum: d65127ad0ebb148e76d918a2a6817fd34ca2c801c7ecb46f86ff74172467fe4349809f776f160387231d32736e7ad322f8218f71818755aaf063560cb3bc6331 + languageName: node + linkType: hard + +"@pixi/mixin-get-global-position@npm:7.3.3": + version: 7.3.3 + resolution: "@pixi/mixin-get-global-position@npm:7.3.3" + peerDependencies: + "@pixi/core": 7.3.3 + "@pixi/display": 7.3.3 + checksum: ee784ecf3186bddfd942cb4e3bb31639012639753db32bfcab22c996bd0e4845478c61b4b108ae67f294f0345aee72968a84030dcf04291bd44a4113192b899a + languageName: node + linkType: hard + +"@pixi/particle-container@npm:7.3.3": + version: 7.3.3 + resolution: "@pixi/particle-container@npm:7.3.3" + peerDependencies: + "@pixi/core": 7.3.3 + "@pixi/display": 7.3.3 + "@pixi/sprite": 7.3.3 + checksum: 5d6b93008d561e40664f556c927145bdb858853e7d752c7750a35b17471f80c74c84adf706fc775e87e94d8aebb8759028a65ba47ba3b1883cc5e1888beb081f + languageName: node + linkType: hard + +"@pixi/prepare@npm:7.3.3": + version: 7.3.3 + resolution: "@pixi/prepare@npm:7.3.3" + peerDependencies: + "@pixi/core": 7.3.3 + "@pixi/display": 7.3.3 + "@pixi/graphics": 7.3.3 + "@pixi/text": 7.3.3 + checksum: 9413e07c40f5fc0bb827753aacdf0195453eeef0257473f85fb5b3ec102bb52df5430b0e8e2d3a845f843f51d078e8e2e714d5f2aaadaea68e52aa81c0e94a34 + languageName: node + linkType: hard + +"@pixi/runner@npm:7.3.3": + version: 7.3.3 + resolution: "@pixi/runner@npm:7.3.3" + checksum: 2c38f45a92d4d31493e36a90b12322c574069abc6fc9e1c0183490ec8160d03cbc823d3ea2a89ba4f05b367cc0bee0a99e6288a67c1e16689646838768f87529 + languageName: node + linkType: hard + +"@pixi/settings@npm:7.3.3": + version: 7.3.3 + resolution: "@pixi/settings@npm:7.3.3" + dependencies: + "@pixi/constants": "npm:7.3.3" + "@types/css-font-loading-module": "npm:^0.0.12" + ismobilejs: "npm:^1.1.0" + checksum: c248e931cde401053d91d5deb114a45252e2a0e25aa0cf8fec6485163165c7172622b628f489d74521ff592dfaa283a570f4e9600ccdd1396c8444a754f925f7 + languageName: node + linkType: hard + +"@pixi/sprite-animated@npm:7.3.3": + version: 7.3.3 + resolution: "@pixi/sprite-animated@npm:7.3.3" + peerDependencies: + "@pixi/core": 7.3.3 + "@pixi/sprite": 7.3.3 + checksum: 1cf94e24ca54f22c28dd57ec6b79f58b90c2b57a7c3176e356e046a3b5ce12395aaa91fd9e5fd9dbc52f7e49a4f021f4ddc581050b94da5b0a9da6a72014d9df + languageName: node + linkType: hard + +"@pixi/sprite-tiling@npm:7.3.3": + version: 7.3.3 + resolution: "@pixi/sprite-tiling@npm:7.3.3" + peerDependencies: + "@pixi/core": 7.3.3 + "@pixi/display": 7.3.3 + "@pixi/sprite": 7.3.3 + checksum: 1a59a4b061f1c04c964def36af2f3a3c16f0b4e3f2a2d6999752e23cb5a93f37646f75738ef4e6a7735b99ce77e438aea342bf969d5e066106c94b9d428a010b + languageName: node + linkType: hard + +"@pixi/sprite@npm:7.3.3": + version: 7.3.3 + resolution: "@pixi/sprite@npm:7.3.3" + peerDependencies: + "@pixi/core": 7.3.3 + "@pixi/display": 7.3.3 + checksum: 1816e7fd2b9484b1bf702c17aad90a060b8c6c21c3e0316caab7fb094f54ade7acedeec310a4d356e8a776da476a69ca9c906a9c74dde3f4bf9a2e1e728516ed + languageName: node + linkType: hard + +"@pixi/spritesheet@npm:7.3.3": + version: 7.3.3 + resolution: "@pixi/spritesheet@npm:7.3.3" + peerDependencies: + "@pixi/assets": 7.3.3 + "@pixi/core": 7.3.3 + checksum: 62055b59ebc5c6e519e47e0312e3d48be039cf1a4a81471308a6d2596a6171483542eab8f40e09a60e1bedaddb05cb1ae81b9243df50dc253d8f365de99d3e19 + languageName: node + linkType: hard + +"@pixi/text-bitmap@npm:7.3.3": + version: 7.3.3 + resolution: "@pixi/text-bitmap@npm:7.3.3" + peerDependencies: + "@pixi/assets": 7.3.3 + "@pixi/core": 7.3.3 + "@pixi/display": 7.3.3 + "@pixi/mesh": 7.3.3 + "@pixi/text": 7.3.3 + checksum: 3af9996d3ade42a549a74bd5de95bbb465aa13d9ce35823715191f813a9a73e3d54fd0ebf9a69f6ddedab11c4d4e9cb21f1fac329ee6bec595a6b59cf8558725 + languageName: node + linkType: hard + +"@pixi/text-html@npm:7.3.3": + version: 7.3.3 + resolution: "@pixi/text-html@npm:7.3.3" + peerDependencies: + "@pixi/core": 7.3.3 + "@pixi/display": 7.3.3 + "@pixi/sprite": 7.3.3 + "@pixi/text": 7.3.3 + checksum: e81e1a7ebe0f18514d23541321841082a0b628ac36bbcd582b5a6f26c99c34bc2c8f6dcdbb16c6918b4be4a58d1e0ca6633cd14397a0f059de21a56a9dfba7e5 + languageName: node + linkType: hard + +"@pixi/text@npm:7.3.3": + version: 7.3.3 + resolution: "@pixi/text@npm:7.3.3" + peerDependencies: + "@pixi/core": 7.3.3 + "@pixi/sprite": 7.3.3 + checksum: 4ef27e761ed902a719b00253b7ba299396c993e1d4406e03095a80749b05a2d18052e05a1b8e6b7a45f9fef651dae6ba86d288841edfabc6fe2bf1719c1962fa + languageName: node + linkType: hard + +"@pixi/ticker@npm:7.3.3": + version: 7.3.3 + resolution: "@pixi/ticker@npm:7.3.3" + dependencies: + "@pixi/extensions": "npm:7.3.3" + "@pixi/settings": "npm:7.3.3" + "@pixi/utils": "npm:7.3.3" + checksum: 2a2a3954ccd7e91b9dd1c0a4481af3cf15a1a7036f70fca7eb102e6816dac1abd6a18a8a9995ddabfa7a2d0503869a1cb3c221cc513fe5602829facc001ad3a7 + languageName: node + linkType: hard + +"@pixi/utils@npm:7.3.3": + version: 7.3.3 + resolution: "@pixi/utils@npm:7.3.3" + dependencies: + "@pixi/color": "npm:7.3.3" + "@pixi/constants": "npm:7.3.3" + "@pixi/settings": "npm:7.3.3" + "@types/earcut": "npm:^2.1.0" + earcut: "npm:^2.2.4" + eventemitter3: "npm:^4.0.0" + url: "npm:^0.11.0" + checksum: 5b86a1830910dbad906288c0c0330cb60940dd8d719abd882da1d7102e7ec9beb313b4e899a03c40a96132e54c016341dcb4be22a56ece58f33c88b085c3627e + languageName: node + linkType: hard + +"@pkgjs/parseargs@npm:^0.11.0": + version: 0.11.0 + resolution: "@pkgjs/parseargs@npm:0.11.0" + checksum: 5bd7576bb1b38a47a7fc7b51ac9f38748e772beebc56200450c4a817d712232b8f1d3ef70532c80840243c657d491cf6a6be1e3a214cff907645819fdc34aadd + languageName: node + linkType: hard + +"@swc/core-darwin-arm64@npm:1.3.105": + version: 1.3.105 + resolution: "@swc/core-darwin-arm64@npm:1.3.105" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@swc/core-darwin-x64@npm:1.3.105": + version: 1.3.105 + resolution: "@swc/core-darwin-x64@npm:1.3.105" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@swc/core-linux-arm-gnueabihf@npm:1.3.105": + version: 1.3.105 + resolution: "@swc/core-linux-arm-gnueabihf@npm:1.3.105" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + +"@swc/core-linux-arm64-gnu@npm:1.3.105": + version: 1.3.105 + resolution: "@swc/core-linux-arm64-gnu@npm:1.3.105" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + +"@swc/core-linux-arm64-musl@npm:1.3.105": + version: 1.3.105 + resolution: "@swc/core-linux-arm64-musl@npm:1.3.105" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + +"@swc/core-linux-x64-gnu@npm:1.3.105": + version: 1.3.105 + resolution: "@swc/core-linux-x64-gnu@npm:1.3.105" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + +"@swc/core-linux-x64-musl@npm:1.3.105": + version: 1.3.105 + resolution: "@swc/core-linux-x64-musl@npm:1.3.105" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + +"@swc/core-win32-arm64-msvc@npm:1.3.105": + version: 1.3.105 + resolution: "@swc/core-win32-arm64-msvc@npm:1.3.105" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@swc/core-win32-ia32-msvc@npm:1.3.105": + version: 1.3.105 + resolution: "@swc/core-win32-ia32-msvc@npm:1.3.105" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + +"@swc/core-win32-x64-msvc@npm:1.3.105": + version: 1.3.105 + resolution: "@swc/core-win32-x64-msvc@npm:1.3.105" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"@swc/core@npm:^1.3.36": + version: 1.3.105 + resolution: "@swc/core@npm:1.3.105" + dependencies: + "@swc/core-darwin-arm64": "npm:1.3.105" + "@swc/core-darwin-x64": "npm:1.3.105" + "@swc/core-linux-arm-gnueabihf": "npm:1.3.105" + "@swc/core-linux-arm64-gnu": "npm:1.3.105" + "@swc/core-linux-arm64-musl": "npm:1.3.105" + "@swc/core-linux-x64-gnu": "npm:1.3.105" + "@swc/core-linux-x64-musl": "npm:1.3.105" + "@swc/core-win32-arm64-msvc": "npm:1.3.105" + "@swc/core-win32-ia32-msvc": "npm:1.3.105" + "@swc/core-win32-x64-msvc": "npm:1.3.105" + "@swc/counter": "npm:^0.1.1" + "@swc/types": "npm:^0.1.5" + peerDependencies: + "@swc/helpers": ^0.5.0 + dependenciesMeta: + "@swc/core-darwin-arm64": + optional: true + "@swc/core-darwin-x64": + optional: true + "@swc/core-linux-arm-gnueabihf": + optional: true + "@swc/core-linux-arm64-gnu": + optional: true + "@swc/core-linux-arm64-musl": + optional: true + "@swc/core-linux-x64-gnu": + optional: true + "@swc/core-linux-x64-musl": + optional: true + "@swc/core-win32-arm64-msvc": + optional: true + "@swc/core-win32-ia32-msvc": + optional: true + "@swc/core-win32-x64-msvc": + optional: true + peerDependenciesMeta: + "@swc/helpers": + optional: true + checksum: 719283fa1bb7e25a9e3bfb4bb2fca8dec98a1cbbcd53cdd6a8cc9d9e2ac701d0fe409b2f3f9b6ddd466b2c1592cdae9c2302a114036bb5adc08e8f95549543e0 + languageName: node + linkType: hard + +"@swc/counter@npm:^0.1.1": + version: 0.1.2 + resolution: "@swc/counter@npm:0.1.2" + checksum: 18be012107d4ba1f79776c48d83391ca2159103d7d31a59ff52fcc8024db51b71c5f46714a9fb73981739bc8a38dc6f385a046b71cc08f6043f3c47f5c409eab + languageName: node + linkType: hard + +"@swc/helpers@npm:^0.5.0": + version: 0.5.3 + resolution: "@swc/helpers@npm:0.5.3" + dependencies: + tslib: "npm:^2.4.0" + checksum: 7003b9dafad38e27a4474a3dcf78d2aee85ce4bb7ee171ecc2d5b533768fb4f8fc9dbd6a1c3a9df5f8001e61ff416b93681e0a7dcbdc0df109b3e09c50cd4615 + languageName: node + linkType: hard + +"@swc/types@npm:^0.1.5": + version: 0.1.5 + resolution: "@swc/types@npm:0.1.5" + checksum: b35f93fe896a2240f6f10544e408f9648c2bd4bcff9bd8d022d9a6942d31cf859f86119fb0bbb04a12eefa1f6a6745ffc7d18f3a490d76d7b6a074a7c9608144 + languageName: node + linkType: hard + +"@trysound/sax@npm:0.2.0": + version: 0.2.0 + resolution: "@trysound/sax@npm:0.2.0" + checksum: 44907308549ce775a41c38a815f747009ac45929a45d642b836aa6b0a536e4978d30b8d7d680bbd116e9dd73b7dbe2ef0d1369dcfc2d09e83ba381e485ecbe12 + languageName: node + linkType: hard + +"@types/css-font-loading-module@npm:^0.0.12": + version: 0.0.12 + resolution: "@types/css-font-loading-module@npm:0.0.12" + checksum: b969a8f14f1b6c1f677d4cd7072683766dff3c9cbcb18edd6072f3b10b7c83ed50a5ee3cd050ad6a95bfd1df1ab677339e33a6e34bafc20193014cb6566cc8f3 + languageName: node + linkType: hard + +"@types/d3-array@npm:*": + version: 3.2.1 + resolution: "@types/d3-array@npm:3.2.1" + checksum: 38bf2c778451f4b79ec81a2288cb4312fe3d6449ecdf562970cc339b60f280f31c93a024c7ff512607795e79d3beb0cbda123bb07010167bce32927f71364bca + languageName: node + linkType: hard + +"@types/d3-axis@npm:*": + version: 3.0.6 + resolution: "@types/d3-axis@npm:3.0.6" + dependencies: + "@types/d3-selection": "npm:*" + checksum: d756d42360261f44d8eefd0950c5bb0a4f67a46dd92069da3f723ac36a1e8cb2b9ce6347d836ef19d5b8aef725dbcf8fdbbd6cfbff676ca4b0642df2f78b599a + languageName: node + linkType: hard + +"@types/d3-brush@npm:*": + version: 3.0.6 + resolution: "@types/d3-brush@npm:3.0.6" + dependencies: + "@types/d3-selection": "npm:*" + checksum: fd6e2ac7657a354f269f6b9c58451ffae9d01b89ccb1eb6367fd36d635d2f1990967215ab498e0c0679ff269429c57fad6a2958b68f4d45bc9f81d81672edc01 + languageName: node + linkType: hard + +"@types/d3-chord@npm:*": + version: 3.0.6 + resolution: "@types/d3-chord@npm:3.0.6" + checksum: c5a25eb5389db01e63faec0c5c2ec7cc41c494e9b3201630b494c4e862a60f1aa83fabbc33a829e7e1403941e3c30d206c741559b14406ac2a4239cfdf4b4c17 + languageName: node + linkType: hard + +"@types/d3-color@npm:*": + version: 3.1.3 + resolution: "@types/d3-color@npm:3.1.3" + checksum: 65eb0487de606eb5ad81735a9a5b3142d30bc5ea801ed9b14b77cb14c9b909f718c059f13af341264ee189acf171508053342142bdf99338667cea26a2d8d6ae + languageName: node + linkType: hard + +"@types/d3-contour@npm:*": + version: 3.0.6 + resolution: "@types/d3-contour@npm:3.0.6" + dependencies: + "@types/d3-array": "npm:*" + "@types/geojson": "npm:*" + checksum: e7d83e94719af4576ceb5ac7f277c5806f83ba6c3631744ae391cffc3641f09dfa279470b83053cd0b2acd6784e8749c71141d05bdffa63ca58ffb5b31a0f27c + languageName: node + linkType: hard + +"@types/d3-delaunay@npm:*": + version: 6.0.4 + resolution: "@types/d3-delaunay@npm:6.0.4" + checksum: d154a8864f08c4ea23ecb9bdabcef1c406a25baa8895f0cb08a0ed2799de0d360e597552532ce7086ff0cdffa8f3563f9109d18f0191459d32bb620a36939123 + languageName: node + linkType: hard + +"@types/d3-dispatch@npm:*": + version: 3.0.6 + resolution: "@types/d3-dispatch@npm:3.0.6" + checksum: 405eb7d0ec139fbf72fa6a43b0f3ca8a1f913bb2cb38f607827e63fca8d4393f021f32f3b96b33c93ddbd37789453a0b3624f14f504add5308fd9aec8a46dda0 + languageName: node + linkType: hard + +"@types/d3-drag@npm:*": + version: 3.0.7 + resolution: "@types/d3-drag@npm:3.0.7" + dependencies: + "@types/d3-selection": "npm:*" + checksum: 65e29fa32a87c72d26c44b5e2df3bf15af21cd128386bcc05bcacca255927c0397d0cd7e6062aed5f0abd623490544a9d061c195f5ed9f018fe0b698d99c079d + languageName: node + linkType: hard + +"@types/d3-dsv@npm:*": + version: 3.0.7 + resolution: "@types/d3-dsv@npm:3.0.7" + checksum: c0f01da862465594c8a28278b51c850af3b4239cc22b14fd1a19d7a98f93d94efa477bf59d8071beb285dca45bf614630811451e18e7c52add3a0abfee0a1871 + languageName: node + linkType: hard + +"@types/d3-ease@npm:*": + version: 3.0.2 + resolution: "@types/d3-ease@npm:3.0.2" + checksum: aff5a1e572a937ee9bff6465225d7ba27d5e0c976bd9eacdac2e6f10700a7cb0c9ea2597aff6b43a6ed850a3210030870238894a77ec73e309b4a9d0333f099c + languageName: node + linkType: hard + +"@types/d3-fetch@npm:*": + version: 3.0.7 + resolution: "@types/d3-fetch@npm:3.0.7" + dependencies: + "@types/d3-dsv": "npm:*" + checksum: 3d147efa52a26da1a5d40d4d73e6cebaaa964463c378068062999b93ea3731b27cc429104c21ecbba98c6090e58ef13429db6399238c5e3500162fb3015697a0 + languageName: node + linkType: hard + +"@types/d3-force@npm:*": + version: 3.0.9 + resolution: "@types/d3-force@npm:3.0.9" + checksum: 6d791a48ea570daaada6df93af8c877d58e6b940b3ab4515cde08ed6ed1d4e8e59fd8407efe37a1b3f5fe95867fe83a2974c4314a7924dc19860a5e955c26211 + languageName: node + linkType: hard + +"@types/d3-format@npm:*": + version: 3.0.4 + resolution: "@types/d3-format@npm:3.0.4" + checksum: 3ac1600bf9061a59a228998f7cd3f29e85cbf522997671ba18d4d84d10a2a1aff4f95aceb143fa9960501c3ec351e113fc75884e6a504ace44dc1744083035ee + languageName: node + linkType: hard + +"@types/d3-geo@npm:*": + version: 3.1.0 + resolution: "@types/d3-geo@npm:3.1.0" + dependencies: + "@types/geojson": "npm:*" + checksum: 3745a93439038bb5b0b38facf435f7079812921d46406f5d38deaee59e90084ff742443c7ea0a8446df81a0d81eaf622fe7068cf4117a544bd4aa3b2dc182f88 + languageName: node + linkType: hard + +"@types/d3-hierarchy@npm:*": + version: 3.1.6 + resolution: "@types/d3-hierarchy@npm:3.1.6" + checksum: b4a3704e94285b0ea6d2d44eae803d608bcce3d523b1d31c911a406a81200632a9097d0d397d9f647659cebde6be109d64a828052de4382dc5310d1d5b265dd5 + languageName: node + linkType: hard + +"@types/d3-interpolate@npm:*": + version: 3.0.4 + resolution: "@types/d3-interpolate@npm:3.0.4" + dependencies: + "@types/d3-color": "npm:*" + checksum: 066ebb8da570b518dd332df6b12ae3b1eaa0a7f4f0c702e3c57f812cf529cc3500ec2aac8dc094f31897790346c6b1ebd8cd7a077176727f4860c2b181a65ca4 + languageName: node + linkType: hard + +"@types/d3-path@npm:*": + version: 3.0.2 + resolution: "@types/d3-path@npm:3.0.2" + checksum: 04f0622f766c0a5ead4656d49285e65203ecc6ab3da439895155db6f425dea733bf1dd9372c3ccbbe25992fe27b485896e3e58e7ac3b5d084beb1fd3dd87de6b + languageName: node + linkType: hard + +"@types/d3-polygon@npm:*": + version: 3.0.2 + resolution: "@types/d3-polygon@npm:3.0.2" + checksum: f46307bb32b6c2aef8c7624500e0f9b518de8f227ccc10170b869dc43e4c542560f6c8d62e9f087fac45e198d6e4b623e579c0422e34c85baf56717456d3f439 + languageName: node + linkType: hard + +"@types/d3-quadtree@npm:*": + version: 3.0.6 + resolution: "@types/d3-quadtree@npm:3.0.6" + checksum: 7eaa0a4d404adc856971c9285e1c4ab17e9135ea669d847d6db7e0066126a28ac751864e7ce99c65d526e130f56754a2e437a1617877098b3bdcc3ef23a23616 + languageName: node + linkType: hard + +"@types/d3-random@npm:*": + version: 3.0.3 + resolution: "@types/d3-random@npm:3.0.3" + checksum: 5f4fea40080cd6d4adfee05183d00374e73a10c530276a6455348983dda341003a251def28565a27c25d9cf5296a33e870e397c9d91ff83fb7495a21c96b6882 + languageName: node + linkType: hard + +"@types/d3-scale-chromatic@npm:*": + version: 3.0.3 + resolution: "@types/d3-scale-chromatic@npm:3.0.3" + checksum: 2f48c6f370edba485b57b73573884ded71914222a4580140ff87ee96e1d55ccd05b1d457f726e234a31269b803270ac95d5554229ab6c43c7e4a9894e20dd490 + languageName: node + linkType: hard + +"@types/d3-scale@npm:*": + version: 4.0.8 + resolution: "@types/d3-scale@npm:4.0.8" + dependencies: + "@types/d3-time": "npm:*" + checksum: 57de90e4016f640b83cb960b7e3a0ab3ed02e720898840ddc5105264ffcfea73336161442fdc91895377c2d2f91904d637282f16852b8535b77e15a761c8e99e + languageName: node + linkType: hard + +"@types/d3-selection@npm:*": + version: 3.0.10 + resolution: "@types/d3-selection@npm:3.0.10" + checksum: de1f99ab186a08999bf394a645fd76911add1b02316270d4c07616c8383903a2b068d7e02b73b6a99a1f26bb49a2e99ef4b55a5d2ddfa165f6f3c53144897920 + languageName: node + linkType: hard + +"@types/d3-shape@npm:*": + version: 3.1.6 + resolution: "@types/d3-shape@npm:3.1.6" + dependencies: + "@types/d3-path": "npm:*" + checksum: 0625715925d3c7ed3d44ce998b42c993f063c31605b6e4a8046c4be0fe724e2d214fc83e86d04f429a30a6e1f439053e92b0d9e59e1180c3a5327b4a6e79fa0a + languageName: node + linkType: hard + +"@types/d3-time-format@npm:*": + version: 4.0.3 + resolution: "@types/d3-time-format@npm:4.0.3" + checksum: 9ef5e8e2b96b94799b821eed5d61a3d432c7903247966d8ad951b8ce5797fe46554b425cb7888fa5bf604b4663c369d7628c0328ffe80892156671c58d1a7f90 + languageName: node + linkType: hard + +"@types/d3-time@npm:*": + version: 3.0.3 + resolution: "@types/d3-time@npm:3.0.3" + checksum: 245a8aadca504df27edf730de502e47a68f16ae795c86b5ca35e7afa91c133aa9ef4d08778f8cf1ed2be732f89a4105ba4b437ce2afbdfd17d3d937b6ba5f568 + languageName: node + linkType: hard + +"@types/d3-timer@npm:*": + version: 3.0.2 + resolution: "@types/d3-timer@npm:3.0.2" + checksum: c644dd9571fcc62b1aa12c03bcad40571553020feeb5811f1d8a937ac1e65b8a04b759b4873aef610e28b8714ac71c9885a4d6c127a048d95118f7e5b506d9e1 + languageName: node + linkType: hard + +"@types/d3-transition@npm:*": + version: 3.0.8 + resolution: "@types/d3-transition@npm:3.0.8" + dependencies: + "@types/d3-selection": "npm:*" + checksum: feba7845bd1e1d49e38b0d55562e01e90bfbcf0a56fbe0de4279c12e43a687032d22ed559629c0412145d25d61e4e53ddfef34c89c6bf043d48b6c2cd3a929dc + languageName: node + linkType: hard + +"@types/d3-zoom@npm:*": + version: 3.0.8 + resolution: "@types/d3-zoom@npm:3.0.8" + dependencies: + "@types/d3-interpolate": "npm:*" + "@types/d3-selection": "npm:*" + checksum: 1dbdbcafddcae12efb5beb6948546963f29599e18bc7f2a91fb69cc617c2299a65354f2d47e282dfb86fec0968406cd4fb7f76ba2d2fb67baa8e8d146eb4a547 + languageName: node + linkType: hard + +"@types/d3@npm:^7.4.3": + version: 7.4.3 + resolution: "@types/d3@npm:7.4.3" + dependencies: + "@types/d3-array": "npm:*" + "@types/d3-axis": "npm:*" + "@types/d3-brush": "npm:*" + "@types/d3-chord": "npm:*" + "@types/d3-color": "npm:*" + "@types/d3-contour": "npm:*" + "@types/d3-delaunay": "npm:*" + "@types/d3-dispatch": "npm:*" + "@types/d3-drag": "npm:*" + "@types/d3-dsv": "npm:*" + "@types/d3-ease": "npm:*" + "@types/d3-fetch": "npm:*" + "@types/d3-force": "npm:*" + "@types/d3-format": "npm:*" + "@types/d3-geo": "npm:*" + "@types/d3-hierarchy": "npm:*" + "@types/d3-interpolate": "npm:*" + "@types/d3-path": "npm:*" + "@types/d3-polygon": "npm:*" + "@types/d3-quadtree": "npm:*" + "@types/d3-random": "npm:*" + "@types/d3-scale": "npm:*" + "@types/d3-scale-chromatic": "npm:*" + "@types/d3-selection": "npm:*" + "@types/d3-shape": "npm:*" + "@types/d3-time": "npm:*" + "@types/d3-time-format": "npm:*" + "@types/d3-timer": "npm:*" + "@types/d3-transition": "npm:*" + "@types/d3-zoom": "npm:*" + checksum: a9c6d65b13ef3b42c87f2a89ea63a6d5640221869f97d0657b0cb2f1dac96a0f164bf5605643c0794e0de3aa2bf05df198519aaf15d24ca135eb0e8bd8a9d879 + languageName: node + linkType: hard + +"@types/earcut@npm:^2.1.0": + version: 2.1.4 + resolution: "@types/earcut@npm:2.1.4" + checksum: ab76940f1cc66ac861932f254b8c0344ebdcfed69e356606416d562e17cd112221b08340d52232f73ff1ad08d4dcf9caa5352c73258df4b8a41c9110ba370262 + languageName: node + linkType: hard + +"@types/geojson@npm:*": + version: 7946.0.13 + resolution: "@types/geojson@npm:7946.0.13" + checksum: 4450d070f2591500bd3ce13a898d8e4b53a6b75dfb08c002c2553a1bb135cdde9980dee6193d9fe2179c7b5fb6c52470acd116a3db91b33d8c6ba9ae3ae44e11 + languageName: node + linkType: hard + +"@types/offscreencanvas@npm:^2019.6.4": + version: 2019.7.3 + resolution: "@types/offscreencanvas@npm:2019.7.3" + checksum: 6d1dfae721d321cd2b5435f347a0e53b09f33b2f9e9333396480f592823bc323847b8169f7d251d2285cb93dbc1ba2e30741ac5cf4b1c003d660fd4c24526963 + languageName: node + linkType: hard + +"abbrev@npm:^2.0.0": + version: 2.0.0 + resolution: "abbrev@npm:2.0.0" + checksum: f742a5a107473946f426c691c08daba61a1d15942616f300b5d32fd735be88fef5cba24201757b6c407fd564555fb48c751cfa33519b2605c8a7aadd22baf372 + languageName: node + linkType: hard + +"abortcontroller-polyfill@npm:^1.1.9": + version: 1.7.5 + resolution: "abortcontroller-polyfill@npm:1.7.5" + checksum: d7a5ab6fda4f9a54f22ddeb233a2564d2f4f857ec17be25fee21a91bb5090bee57c630c454634b5c4b93fc06bd90d592d1f2fc69f77cd28791ac0fe361feb7d2 + languageName: node + linkType: hard + +"agent-base@npm:^7.0.2, agent-base@npm:^7.1.0": + version: 7.1.0 + resolution: "agent-base@npm:7.1.0" + dependencies: + debug: "npm:^4.3.4" + checksum: fc974ab57ffdd8421a2bc339644d312a9cca320c20c3393c9d8b1fd91731b9bbabdb985df5fc860f5b79d81c3e350daa3fcb31c5c07c0bb385aafc817df004ce + languageName: node + linkType: hard + +"aggregate-error@npm:^3.0.0": + version: 3.1.0 + resolution: "aggregate-error@npm:3.1.0" + dependencies: + clean-stack: "npm:^2.0.0" + indent-string: "npm:^4.0.0" + checksum: a42f67faa79e3e6687a4923050e7c9807db3848a037076f791d10e092677d65c1d2d863b7848560699f40fc0502c19f40963fb1cd1fb3d338a7423df8e45e039 + languageName: node + linkType: hard + +"ansi-regex@npm:^5.0.1": + version: 5.0.1 + resolution: "ansi-regex@npm:5.0.1" + checksum: 9a64bb8627b434ba9327b60c027742e5d17ac69277960d041898596271d992d4d52ba7267a63ca10232e29f6107fc8a835f6ce8d719b88c5f8493f8254813737 + languageName: node + linkType: hard + +"ansi-regex@npm:^6.0.1": + version: 6.0.1 + resolution: "ansi-regex@npm:6.0.1" + checksum: cbe16dbd2c6b2735d1df7976a7070dd277326434f0212f43abf6d87674095d247968209babdaad31bb00882fa68807256ba9be340eec2f1004de14ca75f52a08 + languageName: node + linkType: hard + +"ansi-styles@npm:^3.2.1": + version: 3.2.1 + resolution: "ansi-styles@npm:3.2.1" + dependencies: + color-convert: "npm:^1.9.0" + checksum: ece5a8ef069fcc5298f67e3f4771a663129abd174ea2dfa87923a2be2abf6cd367ef72ac87942da00ce85bd1d651d4cd8595aebdb1b385889b89b205860e977b + languageName: node + linkType: hard + +"ansi-styles@npm:^4.0.0, ansi-styles@npm:^4.1.0": + version: 4.3.0 + resolution: "ansi-styles@npm:4.3.0" + dependencies: + color-convert: "npm:^2.0.1" + checksum: 895a23929da416f2bd3de7e9cb4eabd340949328ab85ddd6e484a637d8f6820d485f53933446f5291c3b760cbc488beb8e88573dd0f9c7daf83dccc8fe81b041 + languageName: node + linkType: hard + +"ansi-styles@npm:^6.1.0": + version: 6.2.1 + resolution: "ansi-styles@npm:6.2.1" + checksum: 5d1ec38c123984bcedd996eac680d548f31828bd679a66db2bdf11844634dde55fec3efa9c6bb1d89056a5e79c1ac540c4c784d592ea1d25028a92227d2f2d5c + languageName: node + linkType: hard + +"argparse@npm:^2.0.1": + version: 2.0.1 + resolution: "argparse@npm:2.0.1" + checksum: c5640c2d89045371c7cedd6a70212a04e360fd34d6edeae32f6952c63949e3525ea77dbec0289d8213a99bbaeab5abfa860b5c12cf88a2e6cf8106e90dd27a7e + languageName: node + linkType: hard + +"balanced-match@npm:^1.0.0": + version: 1.0.2 + resolution: "balanced-match@npm:1.0.2" + checksum: 9308baf0a7e4838a82bbfd11e01b1cb0f0cf2893bc1676c27c2a8c0e70cbae1c59120c3268517a8ae7fb6376b4639ef81ca22582611dbee4ed28df945134aaee + languageName: node + linkType: hard + +"base-x@npm:^3.0.8": + version: 3.0.9 + resolution: "base-x@npm:3.0.9" + dependencies: + safe-buffer: "npm:^5.0.1" + checksum: e6bbeae30b24f748b546005affb710c5fbc8b11a83f6cd0ca999bd1ab7ad3a22e42888addc40cd145adc4edfe62fcfab4ebc91da22e4259aae441f95a77aee1a + languageName: node + linkType: hard + +"boolbase@npm:^1.0.0": + version: 1.0.0 + resolution: "boolbase@npm:1.0.0" + checksum: e4b53deb4f2b85c52be0e21a273f2045c7b6a6ea002b0e139c744cb6f95e9ec044439a52883b0d74dedd1ff3da55ed140cfdddfed7fb0cccbed373de5dce1bcf + languageName: node + linkType: hard + +"brace-expansion@npm:^2.0.1": + version: 2.0.1 + resolution: "brace-expansion@npm:2.0.1" + dependencies: + balanced-match: "npm:^1.0.0" + checksum: b358f2fe060e2d7a87aa015979ecea07f3c37d4018f8d6deb5bd4c229ad3a0384fe6029bb76cd8be63c81e516ee52d1a0673edbe2023d53a5191732ae3c3e49f + languageName: node + linkType: hard + +"braces@npm:^3.0.2": + version: 3.0.2 + resolution: "braces@npm:3.0.2" + dependencies: + fill-range: "npm:^7.0.1" + checksum: 321b4d675791479293264019156ca322163f02dc06e3c4cab33bb15cd43d80b51efef69b0930cfde3acd63d126ebca24cd0544fa6f261e093a0fb41ab9dda381 + languageName: node + linkType: hard + +"browserslist@npm:^4.6.6": + version: 4.22.2 + resolution: "browserslist@npm:4.22.2" + dependencies: + caniuse-lite: "npm:^1.0.30001565" + electron-to-chromium: "npm:^1.4.601" + node-releases: "npm:^2.0.14" + update-browserslist-db: "npm:^1.0.13" + bin: + browserslist: cli.js + checksum: 2a331aab90503130043ca41dd5d281fa1e89d5e076d07a2d75e76bf4d693bd56e73d5abcd8c4f39119da6328d450578c216cf1cd5c99b82d8a90a2ae6271b465 + languageName: node + linkType: hard + +"cacache@npm:^18.0.0": + version: 18.0.2 + resolution: "cacache@npm:18.0.2" + dependencies: + "@npmcli/fs": "npm:^3.1.0" + fs-minipass: "npm:^3.0.0" + glob: "npm:^10.2.2" + lru-cache: "npm:^10.0.1" + minipass: "npm:^7.0.3" + minipass-collect: "npm:^2.0.1" + minipass-flush: "npm:^1.0.5" + minipass-pipeline: "npm:^1.2.4" + p-map: "npm:^4.0.0" + ssri: "npm:^10.0.0" + tar: "npm:^6.1.11" + unique-filename: "npm:^3.0.0" + checksum: 7992665305cc251a984f4fdbab1449d50e88c635bc43bf2785530c61d239c61b349e5734461baa461caaee65f040ab14e2d58e694f479c0810cffd181ba5eabc + languageName: node + linkType: hard + +"call-bind@npm:^1.0.0": + version: 1.0.5 + resolution: "call-bind@npm:1.0.5" + dependencies: + function-bind: "npm:^1.1.2" + get-intrinsic: "npm:^1.2.1" + set-function-length: "npm:^1.1.1" + checksum: a6172c168fd6dacf744fcde745099218056bd755c50415b592655dcd6562157ed29f130f56c3f6db2250f67e4bd62e5c218cdc56d7bfd76e0bda50770fce2d10 + languageName: node + linkType: hard + +"callsites@npm:^3.0.0": + version: 3.1.0 + resolution: "callsites@npm:3.1.0" + checksum: fff92277400eb06c3079f9e74f3af120db9f8ea03bad0e84d9aede54bbe2d44a56cccb5f6cf12211f93f52306df87077ecec5b712794c5a9b5dac6d615a3f301 + languageName: node + linkType: hard + +"caniuse-lite@npm:^1.0.30001565": + version: 1.0.30001579 + resolution: "caniuse-lite@npm:1.0.30001579" + checksum: 4003970f8d01a5fa314e39f4a21751dc750a530f3d19aed225e18e8e02892b590b8b0debfa0961eae9bc0e49b77bfb17cf30d2469540e428a8305e3cc9164fb8 + languageName: node + linkType: hard + +"chalk@npm:^2.4.2": + version: 2.4.2 + resolution: "chalk@npm:2.4.2" + dependencies: + ansi-styles: "npm:^3.2.1" + escape-string-regexp: "npm:^1.0.5" + supports-color: "npm:^5.3.0" + checksum: e6543f02ec877732e3a2d1c3c3323ddb4d39fbab687c23f526e25bd4c6a9bf3b83a696e8c769d078e04e5754921648f7821b2a2acfd16c550435fd630026e073 + languageName: node + linkType: hard + +"chalk@npm:^4.1.0": + version: 4.1.2 + resolution: "chalk@npm:4.1.2" + dependencies: + ansi-styles: "npm:^4.1.0" + supports-color: "npm:^7.1.0" + checksum: 4a3fef5cc34975c898ffe77141450f679721df9dde00f6c304353fa9c8b571929123b26a0e4617bde5018977eb655b31970c297b91b63ee83bb82aeb04666880 + languageName: node + linkType: hard + +"chownr@npm:^2.0.0": + version: 2.0.0 + resolution: "chownr@npm:2.0.0" + checksum: 594754e1303672171cc04e50f6c398ae16128eb134a88f801bf5354fd96f205320f23536a045d9abd8b51024a149696e51231565891d4efdab8846021ecf88e6 + languageName: node + linkType: hard + +"chrome-trace-event@npm:^1.0.2, chrome-trace-event@npm:^1.0.3": + version: 1.0.3 + resolution: "chrome-trace-event@npm:1.0.3" + checksum: 080ce2d20c2b9e0f8461a380e9585686caa768b1c834a464470c9dc74cda07f27611c7b727a2cd768a9cecd033297fdec4ce01f1e58b62227882c1059dec321c + languageName: node + linkType: hard + +"clean-stack@npm:^2.0.0": + version: 2.2.0 + resolution: "clean-stack@npm:2.2.0" + checksum: 1f90262d5f6230a17e27d0c190b09d47ebe7efdd76a03b5a1127863f7b3c9aec4c3e6c8bb3a7bbf81d553d56a1fd35728f5a8ef4c63f867ac8d690109742a8c1 + languageName: node + linkType: hard + +"cli-progress@npm:^3.12.0": + version: 3.12.0 + resolution: "cli-progress@npm:3.12.0" + dependencies: + string-width: "npm:^4.2.3" + checksum: f464cb19ebde2f3880620a2adfaeeefaec6cb15c8e610c8a659ca1047ee90d69f3bf2fdabbb1fe33ac408678e882e3e0eecdb84ab5df0edf930b269b8a72682d + languageName: node + linkType: hard + +"clone@npm:^2.1.1": + version: 2.1.2 + resolution: "clone@npm:2.1.2" + checksum: ed0601cd0b1606bc7d82ee7175b97e68d1dd9b91fd1250a3617b38d34a095f8ee0431d40a1a611122dcccb4f93295b4fdb94942aa763392b5fe44effa50c2d5e + languageName: node + linkType: hard + +"color-convert@npm:^1.9.0": + version: 1.9.3 + resolution: "color-convert@npm:1.9.3" + dependencies: + color-name: "npm:1.1.3" + checksum: 5ad3c534949a8c68fca8fbc6f09068f435f0ad290ab8b2f76841b9e6af7e0bb57b98cb05b0e19fe33f5d91e5a8611ad457e5f69e0a484caad1f7487fd0e8253c + languageName: node + linkType: hard + +"color-convert@npm:^2.0.1": + version: 2.0.1 + resolution: "color-convert@npm:2.0.1" + dependencies: + color-name: "npm:~1.1.4" + checksum: 37e1150172f2e311fe1b2df62c6293a342ee7380da7b9cfdba67ea539909afbd74da27033208d01d6d5cfc65ee7868a22e18d7e7648e004425441c0f8a15a7d7 + languageName: node + linkType: hard + +"color-name@npm:1.1.3": + version: 1.1.3 + resolution: "color-name@npm:1.1.3" + checksum: 566a3d42cca25b9b3cd5528cd7754b8e89c0eb646b7f214e8e2eaddb69994ac5f0557d9c175eb5d8f0ad73531140d9c47525085ee752a91a2ab15ab459caf6d6 + languageName: node + linkType: hard + +"color-name@npm:~1.1.4": + version: 1.1.4 + resolution: "color-name@npm:1.1.4" + checksum: a1a3f914156960902f46f7f56bc62effc6c94e84b2cae157a526b1c1f74b677a47ec602bf68a61abfa2b42d15b7c5651c6dbe72a43af720bc588dff885b10f95 + languageName: node + linkType: hard + +"commander@npm:7, commander@npm:^7.0.0, commander@npm:^7.2.0": + version: 7.2.0 + resolution: "commander@npm:7.2.0" + checksum: 8d690ff13b0356df7e0ebbe6c59b4712f754f4b724d4f473d3cc5b3fdcf978e3a5dc3078717858a2ceb50b0f84d0660a7f22a96cdc50fb877d0c9bb31593d23a + languageName: node + linkType: hard + +"cosmiconfig@npm:^8.0.0": + version: 8.3.6 + resolution: "cosmiconfig@npm:8.3.6" + dependencies: + import-fresh: "npm:^3.3.0" + js-yaml: "npm:^4.1.0" + parse-json: "npm:^5.2.0" + path-type: "npm:^4.0.0" + peerDependencies: + typescript: ">=4.9.5" + peerDependenciesMeta: + typescript: + optional: true + checksum: 0382a9ed13208f8bfc22ca2f62b364855207dffdb73dc26e150ade78c3093f1cf56172df2dd460c8caf2afa91c0ed4ec8a88c62f8f9cd1cf423d26506aa8797a + languageName: node + linkType: hard + +"cross-spawn@npm:^7.0.0": + version: 7.0.3 + resolution: "cross-spawn@npm:7.0.3" + dependencies: + path-key: "npm:^3.1.0" + shebang-command: "npm:^2.0.0" + which: "npm:^2.0.1" + checksum: 5738c312387081c98d69c98e105b6327b069197f864a60593245d64c8089c8a0a744e16349281210d56835bb9274130d825a78b2ad6853ca13cfbeffc0c31750 + languageName: node + linkType: hard + +"css-select@npm:^4.1.3": + version: 4.3.0 + resolution: "css-select@npm:4.3.0" + dependencies: + boolbase: "npm:^1.0.0" + css-what: "npm:^6.0.1" + domhandler: "npm:^4.3.1" + domutils: "npm:^2.8.0" + nth-check: "npm:^2.0.1" + checksum: a489d8e5628e61063d5a8fe0fa1cc7ae2478cb334a388a354e91cf2908154be97eac9fa7ed4dffe87a3e06cf6fcaa6016553115335c4fd3377e13dac7bd5a8e1 + languageName: node + linkType: hard + +"css-tree@npm:^1.1.2, css-tree@npm:^1.1.3": + version: 1.1.3 + resolution: "css-tree@npm:1.1.3" + dependencies: + mdn-data: "npm:2.0.14" + source-map: "npm:^0.6.1" + checksum: 499a507bfa39b8b2128f49736882c0dd636b0cd3370f2c69f4558ec86d269113286b7df469afc955de6a68b0dba00bc533e40022a73698081d600072d5d83c1c + languageName: node + linkType: hard + +"css-what@npm:^6.0.1": + version: 6.1.0 + resolution: "css-what@npm:6.1.0" + checksum: a09f5a6b14ba8dcf57ae9a59474722e80f20406c53a61e9aedb0eedc693b135113ffe2983f4efc4b5065ae639442e9ae88df24941ef159c218b231011d733746 + languageName: node + linkType: hard + +"csso@npm:^4.2.0": + version: 4.2.0 + resolution: "csso@npm:4.2.0" + dependencies: + css-tree: "npm:^1.1.2" + checksum: f8c6b1300efaa0f8855a7905ae3794a29c6496e7f16a71dec31eb6ca7cfb1f058a4b03fd39b66c4deac6cb06bf6b4ba86da7b67d7320389cb9994d52b924b903 + languageName: node + linkType: hard + +"d3-array@npm:2 - 3, d3-array@npm:2.10.0 - 3, d3-array@npm:2.5.0 - 3, d3-array@npm:3, d3-array@npm:^3.2.0": + version: 3.2.4 + resolution: "d3-array@npm:3.2.4" + dependencies: + internmap: "npm:1 - 2" + checksum: 08b95e91130f98c1375db0e0af718f4371ccacef7d5d257727fe74f79a24383e79aba280b9ffae655483ffbbad4fd1dec4ade0119d88c4749f388641c8bf8c50 + languageName: node + linkType: hard + +"d3-axis@npm:3": + version: 3.0.0 + resolution: "d3-axis@npm:3.0.0" + checksum: a271e70ba1966daa5aaf6a7f959ceca3e12997b43297e757c7b945db2e1ead3c6ee226f2abcfa22abbd4e2e28bd2b71a0911794c4e5b911bbba271328a582c78 + languageName: node + linkType: hard + +"d3-brush@npm:3": + version: 3.0.0 + resolution: "d3-brush@npm:3.0.0" + dependencies: + d3-dispatch: "npm:1 - 3" + d3-drag: "npm:2 - 3" + d3-interpolate: "npm:1 - 3" + d3-selection: "npm:3" + d3-transition: "npm:3" + checksum: 07baf00334c576da2f68a91fc0da5732c3a5fa19bd3d7aed7fd24d1d674a773f71a93e9687c154176f7246946194d77c48c2d8fed757f5dcb1a4740067ec50a8 + languageName: node + linkType: hard + +"d3-chord@npm:3": + version: 3.0.1 + resolution: "d3-chord@npm:3.0.1" + dependencies: + d3-path: "npm:1 - 3" + checksum: baa6013914af3f4fe1521f0d16de31a38eb8a71d08ff1dec4741f6f45a828661e5cd3935e39bd14e3032bdc78206c283ca37411da21d46ec3cfc520be6e7a7ce + languageName: node + linkType: hard + +"d3-color@npm:1 - 3, d3-color@npm:3": + version: 3.1.0 + resolution: "d3-color@npm:3.1.0" + checksum: a4e20e1115fa696fce041fbe13fbc80dc4c19150fa72027a7c128ade980bc0eeeba4bcf28c9e21f0bce0e0dbfe7ca5869ef67746541dcfda053e4802ad19783c + languageName: node + linkType: hard + +"d3-contour@npm:4": + version: 4.0.2 + resolution: "d3-contour@npm:4.0.2" + dependencies: + d3-array: "npm:^3.2.0" + checksum: 98bc5fbed6009e08707434a952076f39f1cd6ed8b9288253cc3e6a3286e4e80c63c62d84954b20e64bf6e4ededcc69add54d3db25e990784a59c04edd3449032 + languageName: node + linkType: hard + +"d3-delaunay@npm:6": + version: 6.0.4 + resolution: "d3-delaunay@npm:6.0.4" + dependencies: + delaunator: "npm:5" + checksum: 57c3aecd2525664b07c4c292aa11cf49b2752c0cf3f5257f752999399fe3c592de2d418644d79df1f255471eec8057a9cc0c3062ed7128cb3348c45f69597754 + languageName: node + linkType: hard + +"d3-dispatch@npm:1 - 3, d3-dispatch@npm:3": + version: 3.0.1 + resolution: "d3-dispatch@npm:3.0.1" + checksum: 6eca77008ce2dc33380e45d4410c67d150941df7ab45b91d116dbe6d0a3092c0f6ac184dd4602c796dc9e790222bad3ff7142025f5fd22694efe088d1d941753 + languageName: node + linkType: hard + +"d3-drag@npm:2 - 3, d3-drag@npm:3": + version: 3.0.0 + resolution: "d3-drag@npm:3.0.0" + dependencies: + d3-dispatch: "npm:1 - 3" + d3-selection: "npm:3" + checksum: d2556e8dc720741a443b595a30af403dd60642dfd938d44d6e9bfc4c71a962142f9a028c56b61f8b4790b65a34acad177d1263d66f103c3c527767b0926ef5aa + languageName: node + linkType: hard + +"d3-dsv@npm:1 - 3, d3-dsv@npm:3": + version: 3.0.1 + resolution: "d3-dsv@npm:3.0.1" + dependencies: + commander: "npm:7" + iconv-lite: "npm:0.6" + rw: "npm:1" + bin: + csv2json: bin/dsv2json.js + csv2tsv: bin/dsv2dsv.js + dsv2dsv: bin/dsv2dsv.js + dsv2json: bin/dsv2json.js + json2csv: bin/json2dsv.js + json2dsv: bin/json2dsv.js + json2tsv: bin/json2dsv.js + tsv2csv: bin/dsv2dsv.js + tsv2json: bin/dsv2json.js + checksum: 10e6af9e331950ed258f34ab49ac1b7060128ef81dcf32afc790bd1f7e8c3cc2aac7f5f875250a83f21f39bb5925fbd0872bb209f8aca32b3b77d32bab8a65ab + languageName: node + linkType: hard + +"d3-ease@npm:1 - 3, d3-ease@npm:3": + version: 3.0.1 + resolution: "d3-ease@npm:3.0.1" + checksum: fec8ef826c0cc35cda3092c6841e07672868b1839fcaf556e19266a3a37e6bc7977d8298c0fcb9885e7799bfdcef7db1baaba9cd4dcf4bc5e952cf78574a88b0 + languageName: node + linkType: hard + +"d3-fetch@npm:3": + version: 3.0.1 + resolution: "d3-fetch@npm:3.0.1" + dependencies: + d3-dsv: "npm:1 - 3" + checksum: 4f467a79bf290395ac0cbb5f7562483f6a18668adc4c8eb84c9d3eff048b6f6d3b6f55079ba1ebf1908dabe000c941d46be447f8d78453b2dad5fb59fb6aa93b + languageName: node + linkType: hard + +"d3-force@npm:3": + version: 3.0.0 + resolution: "d3-force@npm:3.0.0" + dependencies: + d3-dispatch: "npm:1 - 3" + d3-quadtree: "npm:1 - 3" + d3-timer: "npm:1 - 3" + checksum: 220a16a1a1ac62ba56df61028896e4b52be89c81040d20229c876efc8852191482c233f8a52bb5a4e0875c321b8e5cb6413ef3dfa4d8fe79eeb7d52c587f52cf + languageName: node + linkType: hard + +"d3-format@npm:1 - 3, d3-format@npm:3": + version: 3.1.0 + resolution: "d3-format@npm:3.1.0" + checksum: 049f5c0871ebce9859fc5e2f07f336b3c5bfff52a2540e0bac7e703fce567cd9346f4ad1079dd18d6f1e0eaa0599941c1810898926f10ac21a31fd0a34b4aa75 + languageName: node + linkType: hard + +"d3-geo@npm:3": + version: 3.1.0 + resolution: "d3-geo@npm:3.1.0" + dependencies: + d3-array: "npm:2.5.0 - 3" + checksum: 5b0a26d232787ca9e824a660827c28626a51004328dde7c76a1bd300d3cad8c7eeb55fea64c8cd6495d5a34fea434fb1418d59926a6cb24e6fb6e2b6f62c6bd9 + languageName: node + linkType: hard + +"d3-hierarchy@npm:3": + version: 3.1.2 + resolution: "d3-hierarchy@npm:3.1.2" + checksum: 6dcdb480539644aa7fc0d72dfc7b03f99dfbcdf02714044e8c708577e0d5981deb9d3e99bbbb2d26422b55bcc342ac89a0fa2ea6c9d7302e2fc0951dd96f89cf + languageName: node + linkType: hard + +"d3-interpolate@npm:1 - 3, d3-interpolate@npm:1.2.0 - 3, d3-interpolate@npm:3": + version: 3.0.1 + resolution: "d3-interpolate@npm:3.0.1" + dependencies: + d3-color: "npm:1 - 3" + checksum: 19f4b4daa8d733906671afff7767c19488f51a43d251f8b7f484d5d3cfc36c663f0a66c38fe91eee30f40327443d799be17169f55a293a3ba949e84e57a33e6a + languageName: node + linkType: hard + +"d3-path@npm:1 - 3, d3-path@npm:3, d3-path@npm:^3.1.0": + version: 3.1.0 + resolution: "d3-path@npm:3.1.0" + checksum: dc1d58ec87fa8319bd240cf7689995111a124b141428354e9637aa83059eb12e681f77187e0ada5dedfce346f7e3d1f903467ceb41b379bfd01cd8e31721f5da + languageName: node + linkType: hard + +"d3-polygon@npm:3": + version: 3.0.1 + resolution: "d3-polygon@npm:3.0.1" + checksum: e236aa7f33efa9a4072907af7dc119f85b150a0716759d4fe5f12f62573018264a6cbde8617fbfa6944a7ae48c1c0c8d3f39ae72e11f66dd471e9b5e668385df + languageName: node + linkType: hard + +"d3-quadtree@npm:1 - 3, d3-quadtree@npm:3": + version: 3.0.1 + resolution: "d3-quadtree@npm:3.0.1" + checksum: 18302d2548bfecaef788152397edec95a76400fd97d9d7f42a089ceb68d910f685c96579d74e3712d57477ed042b056881b47cd836a521de683c66f47ce89090 + languageName: node + linkType: hard + +"d3-random@npm:3": + version: 3.0.1 + resolution: "d3-random@npm:3.0.1" + checksum: 987a1a1bcbf26e6cf01fd89d5a265b463b2cea93560fc17d9b1c45e8ed6ff2db5924601bcceb808de24c94133f000039eb7fa1c469a7a844ccbf1170cbb25b41 + languageName: node + linkType: hard + +"d3-scale-chromatic@npm:3": + version: 3.0.0 + resolution: "d3-scale-chromatic@npm:3.0.0" + dependencies: + d3-color: "npm:1 - 3" + d3-interpolate: "npm:1 - 3" + checksum: 920a80f2e31b5686798c116e99d1671c32f55fb60fa920b742aa4ac5175b878c615adb4e55a246d65367e6e1061fdbcc55807be731fb5b18ae628d1df62bfac1 + languageName: node + linkType: hard + +"d3-scale@npm:4": + version: 4.0.2 + resolution: "d3-scale@npm:4.0.2" + dependencies: + d3-array: "npm:2.10.0 - 3" + d3-format: "npm:1 - 3" + d3-interpolate: "npm:1.2.0 - 3" + d3-time: "npm:2.1.1 - 3" + d3-time-format: "npm:2 - 4" + checksum: 65d9ad8c2641aec30ed5673a7410feb187a224d6ca8d1a520d68a7d6eac9d04caedbff4713d1e8545be33eb7fec5739983a7ab1d22d4e5ad35368c6729d362f1 + languageName: node + linkType: hard + +"d3-selection@npm:2 - 3, d3-selection@npm:3": + version: 3.0.0 + resolution: "d3-selection@npm:3.0.0" + checksum: e59096bbe8f0cb0daa1001d9bdd6dbc93a688019abc97d1d8b37f85cd3c286a6875b22adea0931b0c88410d025563e1643019161a883c516acf50c190a11b56b + languageName: node + linkType: hard + +"d3-shape@npm:3": + version: 3.2.0 + resolution: "d3-shape@npm:3.2.0" + dependencies: + d3-path: "npm:^3.1.0" + checksum: f1c9d1f09926daaf6f6193ae3b4c4b5521e81da7d8902d24b38694517c7f527ce3c9a77a9d3a5722ad1e3ff355860b014557b450023d66a944eabf8cfde37132 + languageName: node + linkType: hard + +"d3-time-format@npm:2 - 4, d3-time-format@npm:4": + version: 4.1.0 + resolution: "d3-time-format@npm:4.1.0" + dependencies: + d3-time: "npm:1 - 3" + checksum: 735e00fb25a7fd5d418fac350018713ae394eefddb0d745fab12bbff0517f9cdb5f807c7bbe87bb6eeb06249662f8ea84fec075f7d0cd68609735b2ceb29d206 + languageName: node + linkType: hard + +"d3-time@npm:1 - 3, d3-time@npm:2.1.1 - 3, d3-time@npm:3": + version: 3.1.0 + resolution: "d3-time@npm:3.1.0" + dependencies: + d3-array: "npm:2 - 3" + checksum: a984f77e1aaeaa182679b46fbf57eceb6ebdb5f67d7578d6f68ef933f8eeb63737c0949991618a8d29472dbf43736c7d7f17c452b2770f8c1271191cba724ca1 + languageName: node + linkType: hard + +"d3-timer@npm:1 - 3, d3-timer@npm:3": + version: 3.0.1 + resolution: "d3-timer@npm:3.0.1" + checksum: d4c63cb4bb5461d7038aac561b097cd1c5673969b27cbdd0e87fa48d9300a538b9e6f39b4a7f0e3592ef4f963d858c8a9f0e92754db73116770856f2fc04561a + languageName: node + linkType: hard + +"d3-transition@npm:2 - 3, d3-transition@npm:3": + version: 3.0.1 + resolution: "d3-transition@npm:3.0.1" + dependencies: + d3-color: "npm:1 - 3" + d3-dispatch: "npm:1 - 3" + d3-ease: "npm:1 - 3" + d3-interpolate: "npm:1 - 3" + d3-timer: "npm:1 - 3" + peerDependencies: + d3-selection: 2 - 3 + checksum: 4e74535dda7024aa43e141635b7522bb70cf9d3dfefed975eb643b36b864762eca67f88fafc2ca798174f83ca7c8a65e892624f824b3f65b8145c6a1a88dbbad + languageName: node + linkType: hard + +"d3-zoom@npm:3": + version: 3.0.0 + resolution: "d3-zoom@npm:3.0.0" + dependencies: + d3-dispatch: "npm:1 - 3" + d3-drag: "npm:2 - 3" + d3-interpolate: "npm:1 - 3" + d3-selection: "npm:2 - 3" + d3-transition: "npm:2 - 3" + checksum: ee2036479049e70d8c783d594c444fe00e398246048e3f11a59755cd0e21de62ece3126181b0d7a31bf37bcf32fd726f83ae7dea4495ff86ec7736ce5ad36fd3 + languageName: node + linkType: hard + +"d3@npm:^7.8.5": + version: 7.8.5 + resolution: "d3@npm:7.8.5" + dependencies: + d3-array: "npm:3" + d3-axis: "npm:3" + d3-brush: "npm:3" + d3-chord: "npm:3" + d3-color: "npm:3" + d3-contour: "npm:4" + d3-delaunay: "npm:6" + d3-dispatch: "npm:3" + d3-drag: "npm:3" + d3-dsv: "npm:3" + d3-ease: "npm:3" + d3-fetch: "npm:3" + d3-force: "npm:3" + d3-format: "npm:3" + d3-geo: "npm:3" + d3-hierarchy: "npm:3" + d3-interpolate: "npm:3" + d3-path: "npm:3" + d3-polygon: "npm:3" + d3-quadtree: "npm:3" + d3-random: "npm:3" + d3-scale: "npm:4" + d3-scale-chromatic: "npm:3" + d3-selection: "npm:3" + d3-shape: "npm:3" + d3-time: "npm:3" + d3-time-format: "npm:4" + d3-timer: "npm:3" + d3-transition: "npm:3" + d3-zoom: "npm:3" + checksum: 408758dcc2437cbff8cd207b9d82760030b5c53c1df6a2ce5b1a76633388a6892fd65c0632cfa83da963e239722d49805062e5fb05d99e0fb078bda14cb22222 + languageName: node + linkType: hard + +"debug@npm:4, debug@npm:^4.3.4": + version: 4.3.4 + resolution: "debug@npm:4.3.4" + dependencies: + ms: "npm:2.1.2" + peerDependenciesMeta: + supports-color: + optional: true + checksum: cedbec45298dd5c501d01b92b119cd3faebe5438c3917ff11ae1bff86a6c722930ac9c8659792824013168ba6db7c4668225d845c633fbdafbbf902a6389f736 + languageName: node + linkType: hard + +"define-data-property@npm:^1.1.1": + version: 1.1.1 + resolution: "define-data-property@npm:1.1.1" + dependencies: + get-intrinsic: "npm:^1.2.1" + gopd: "npm:^1.0.1" + has-property-descriptors: "npm:^1.0.0" + checksum: 77ef6e0bceb515e05b5913ab635a84d537cee84f8a7c37c77fdcb31fc5b80f6dbe81b33375e4b67d96aa04e6a0d8d4ea099e431d83f089af8d93adfb584bcb94 + languageName: node + linkType: hard + +"delaunator@npm:5": + version: 5.0.0 + resolution: "delaunator@npm:5.0.0" + dependencies: + robust-predicates: "npm:^3.0.0" + checksum: 8655c1ad12dc58bd6350f882c12065ea415cfc809e4cac12b7b5c4941e981aaabee1afdcf13985dcd545d13d0143eb3805836f50e2b097af8137b204dfbea4f6 + languageName: node + linkType: hard + +"detect-libc@npm:^1.0.3": + version: 1.0.3 + resolution: "detect-libc@npm:1.0.3" + bin: + detect-libc: ./bin/detect-libc.js + checksum: 4da0deae9f69e13bc37a0902d78bf7169480004b1fed3c19722d56cff578d16f0e11633b7fbf5fb6249181236c72e90024cbd68f0b9558ae06e281f47326d50d + languageName: node + linkType: hard + +"detect-libc@npm:^2.0.1": + version: 2.0.2 + resolution: "detect-libc@npm:2.0.2" + checksum: a9f4ffcd2701525c589617d98afe5a5d0676c8ea82bcc4ed6f3747241b79f781d36437c59a5e855254c864d36a3e9f8276568b6b531c28d6e53b093a15703f11 + languageName: node + linkType: hard + +"dom-serializer@npm:^1.0.1": + version: 1.4.1 + resolution: "dom-serializer@npm:1.4.1" + dependencies: + domelementtype: "npm:^2.0.1" + domhandler: "npm:^4.2.0" + entities: "npm:^2.0.0" + checksum: 67d775fa1ea3de52035c98168ddcd59418356943b5eccb80e3c8b3da53adb8e37edb2cc2f885802b7b1765bf5022aec21dfc32910d7f9e6de4c3148f095ab5e0 + languageName: node + linkType: hard + +"domelementtype@npm:^2.0.1, domelementtype@npm:^2.2.0": + version: 2.3.0 + resolution: "domelementtype@npm:2.3.0" + checksum: 686f5a9ef0fff078c1412c05db73a0dce096190036f33e400a07e2a4518e9f56b1e324f5c576a0a747ef0e75b5d985c040b0d51945ce780c0dd3c625a18cd8c9 + languageName: node + linkType: hard + +"domhandler@npm:^4.2.0, domhandler@npm:^4.2.2, domhandler@npm:^4.3.1": + version: 4.3.1 + resolution: "domhandler@npm:4.3.1" + dependencies: + domelementtype: "npm:^2.2.0" + checksum: 5c199c7468cb052a8b5ab80b13528f0db3d794c64fc050ba793b574e158e67c93f8336e87fd81e9d5ee43b0e04aea4d8b93ed7be4899cb726a1601b3ba18538b + languageName: node + linkType: hard + +"domutils@npm:^2.8.0": + version: 2.8.0 + resolution: "domutils@npm:2.8.0" + dependencies: + dom-serializer: "npm:^1.0.1" + domelementtype: "npm:^2.2.0" + domhandler: "npm:^4.2.0" + checksum: d58e2ae01922f0dd55894e61d18119924d88091837887bf1438f2327f32c65eb76426bd9384f81e7d6dcfb048e0f83c19b222ad7101176ad68cdc9c695b563db + languageName: node + linkType: hard + +"dotenv-expand@npm:^5.1.0": + version: 5.1.0 + resolution: "dotenv-expand@npm:5.1.0" + checksum: 24ac633de853ef474d0421cc639328b7134109c8dc2baaa5e3afb7495af5e9237136d7e6971e55668e4dce915487eb140967cdd2b3e99aa439e0f6bf8b56faeb + languageName: node + linkType: hard + +"dotenv@npm:^7.0.0": + version: 7.0.0 + resolution: "dotenv@npm:7.0.0" + checksum: 4d834d09d23ebd284e701c4204172659a7dcd51116f11c29c575ae6d918ccd4760a3383bdfd83cfbed42f061266b787f8e56452b952638867ea5476be875eb27 + languageName: node + linkType: hard + +"earcut@npm:^2.2.4": + version: 2.2.4 + resolution: "earcut@npm:2.2.4" + checksum: 01ca51830edd2787819f904ae580087d37351f6048b4565e7add4b3da8a86b7bc19262ab2aa7fdc64129ab03af2d9cec8cccee4d230c82275f97ef285c79aafb + languageName: node + linkType: hard + +"eastasianwidth@npm:^0.2.0": + version: 0.2.0 + resolution: "eastasianwidth@npm:0.2.0" + checksum: 26f364ebcdb6395f95124fda411f63137a4bfb5d3a06453f7f23dfe52502905bd84e0488172e0f9ec295fdc45f05c23d5d91baf16bd26f0fe9acd777a188dc39 + languageName: node + linkType: hard + +"electron-to-chromium@npm:^1.4.601": + version: 1.4.643 + resolution: "electron-to-chromium@npm:1.4.643" + checksum: 3a5d836089b220a9da7ebaf4ac8817f021aa11e71b81d055c3bdde7276d8e60f691de6dcb0afe0eda4014923638b3fd74c0e548ba36d747e1eb51027d276ed9b + languageName: node + linkType: hard + +"emoji-regex@npm:^8.0.0": + version: 8.0.0 + resolution: "emoji-regex@npm:8.0.0" + checksum: b6053ad39951c4cf338f9092d7bfba448cdfd46fe6a2a034700b149ac9ffbc137e361cbd3c442297f86bed2e5f7576c1b54cc0a6bf8ef5106cc62f496af35010 + languageName: node + linkType: hard + +"emoji-regex@npm:^9.2.2": + version: 9.2.2 + resolution: "emoji-regex@npm:9.2.2" + checksum: af014e759a72064cf66e6e694a7fc6b0ed3d8db680427b021a89727689671cefe9d04151b2cad51dbaf85d5ba790d061cd167f1cf32eb7b281f6368b3c181639 + languageName: node + linkType: hard + +"encoding@npm:^0.1.13": + version: 0.1.13 + resolution: "encoding@npm:0.1.13" + dependencies: + iconv-lite: "npm:^0.6.2" + checksum: 36d938712ff00fe1f4bac88b43bcffb5930c1efa57bbcdca9d67e1d9d6c57cfb1200fb01efe0f3109b2ce99b231f90779532814a81370a1bd3274a0f58585039 + languageName: node + linkType: hard + +"entities@npm:^2.0.0": + version: 2.2.0 + resolution: "entities@npm:2.2.0" + checksum: 7fba6af1f116300d2ba1c5673fc218af1961b20908638391b4e1e6d5850314ee2ac3ec22d741b3a8060479911c99305164aed19b6254bde75e7e6b1b2c3f3aa3 + languageName: node + linkType: hard + +"entities@npm:^3.0.1": + version: 3.0.1 + resolution: "entities@npm:3.0.1" + checksum: 2d93f48fd86de0b0ed8ee34456aa47b4e74a916a5e663cfcc7048302e2c7e932002926daf5a00ad6d5691e3c90673a15d413704d86d7e1b9532f9bc00d975590 + languageName: node + linkType: hard + +"env-paths@npm:^2.2.0": + version: 2.2.1 + resolution: "env-paths@npm:2.2.1" + checksum: 285325677bf00e30845e330eec32894f5105529db97496ee3f598478e50f008c5352a41a30e5e72ec9de8a542b5a570b85699cd63bd2bc646dbcb9f311d83bc4 + languageName: node + linkType: hard + +"err-code@npm:^2.0.2": + version: 2.0.3 + resolution: "err-code@npm:2.0.3" + checksum: b642f7b4dd4a376e954947550a3065a9ece6733ab8e51ad80db727aaae0817c2e99b02a97a3d6cecc648a97848305e728289cf312d09af395403a90c9d4d8a66 + languageName: node + linkType: hard + +"error-ex@npm:^1.3.1": + version: 1.3.2 + resolution: "error-ex@npm:1.3.2" + dependencies: + is-arrayish: "npm:^0.2.1" + checksum: ba827f89369b4c93382cfca5a264d059dfefdaa56ecc5e338ffa58a6471f5ed93b71a20add1d52290a4873d92381174382658c885ac1a2305f7baca363ce9cce + languageName: node + linkType: hard + +"escalade@npm:^3.1.1": + version: 3.1.1 + resolution: "escalade@npm:3.1.1" + checksum: afd02e6ca91ffa813e1108b5e7756566173d6bc0d1eb951cb44d6b21702ec17c1cf116cfe75d4a2b02e05acb0b808a7a9387d0d1ca5cf9c04ad03a8445c3e46d + languageName: node + linkType: hard + +"escape-string-regexp@npm:^1.0.5": + version: 1.0.5 + resolution: "escape-string-regexp@npm:1.0.5" + checksum: a968ad453dd0c2724e14a4f20e177aaf32bb384ab41b674a8454afe9a41c5e6fe8903323e0a1052f56289d04bd600f81278edf140b0fcc02f5cac98d0f5b5371 + languageName: node + linkType: hard + +"eventemitter3@npm:^4.0.0": + version: 4.0.7 + resolution: "eventemitter3@npm:4.0.7" + checksum: 5f6d97cbcbac47be798e6355e3a7639a84ee1f7d9b199a07017f1d2f1e2fe236004d14fa5dfaeba661f94ea57805385e326236a6debbc7145c8877fbc0297c6b + languageName: node + linkType: hard + +"exponential-backoff@npm:^3.1.1": + version: 3.1.1 + resolution: "exponential-backoff@npm:3.1.1" + checksum: 160456d2d647e6019640bd07111634d8c353038d9fa40176afb7cd49b0548bdae83b56d05e907c2cce2300b81cae35d800ef92fefb9d0208e190fa3b7d6bb579 + languageName: node + linkType: hard + +"fill-range@npm:^7.0.1": + version: 7.0.1 + resolution: "fill-range@npm:7.0.1" + dependencies: + to-regex-range: "npm:^5.0.1" + checksum: 7cdad7d426ffbaadf45aeb5d15ec675bbd77f7597ad5399e3d2766987ed20bda24d5fac64b3ee79d93276f5865608bb22344a26b9b1ae6c4d00bd94bf611623f + languageName: node + linkType: hard + +"foreground-child@npm:^3.1.0": + version: 3.1.1 + resolution: "foreground-child@npm:3.1.1" + dependencies: + cross-spawn: "npm:^7.0.0" + signal-exit: "npm:^4.0.1" + checksum: 9700a0285628abaeb37007c9a4d92bd49f67210f09067638774338e146c8e9c825c5c877f072b2f75f41dc6a2d0be8664f79ffc03f6576649f54a84fb9b47de0 + languageName: node + linkType: hard + +"fs-minipass@npm:^2.0.0": + version: 2.1.0 + resolution: "fs-minipass@npm:2.1.0" + dependencies: + minipass: "npm:^3.0.0" + checksum: 703d16522b8282d7299337539c3ed6edddd1afe82435e4f5b76e34a79cd74e488a8a0e26a636afc2440e1a23b03878e2122e3a2cfe375a5cf63c37d92b86a004 + languageName: node + linkType: hard + +"fs-minipass@npm:^3.0.0": + version: 3.0.3 + resolution: "fs-minipass@npm:3.0.3" + dependencies: + minipass: "npm:^7.0.3" + checksum: 63e80da2ff9b621e2cb1596abcb9207f1cf82b968b116ccd7b959e3323144cce7fb141462200971c38bbf2ecca51695069db45265705bed09a7cd93ae5b89f94 + languageName: node + linkType: hard + +"function-bind@npm:^1.1.2": + version: 1.1.2 + resolution: "function-bind@npm:1.1.2" + checksum: d8680ee1e5fcd4c197e4ac33b2b4dce03c71f4d91717292785703db200f5c21f977c568d28061226f9b5900cbcd2c84463646134fd5337e7925e0942bc3f46d5 + languageName: node + linkType: hard + +"get-intrinsic@npm:^1.0.2, get-intrinsic@npm:^1.1.3, get-intrinsic@npm:^1.2.1, get-intrinsic@npm:^1.2.2": + version: 1.2.2 + resolution: "get-intrinsic@npm:1.2.2" + dependencies: + function-bind: "npm:^1.1.2" + has-proto: "npm:^1.0.1" + has-symbols: "npm:^1.0.3" + hasown: "npm:^2.0.0" + checksum: 4e7fb8adc6172bae7c4fe579569b4d5238b3667c07931cd46b4eee74bbe6ff6b91329bec311a638d8e60f5b51f44fe5445693c6be89ae88d4b5c49f7ff12db0b + languageName: node + linkType: hard + +"get-port@npm:^4.2.0": + version: 4.2.0 + resolution: "get-port@npm:4.2.0" + checksum: ecce4233b720e7c6612aedc334ee8bb62b7d44db7ad6a55e58f7b3a17993ecfcb1bb218b8bb1ee197d0971c12e420aad2b3f95a93e4a117f2186f926ebcd2d42 + languageName: node + linkType: hard + +"glob@npm:^10.2.2, glob@npm:^10.3.10": + version: 10.3.10 + resolution: "glob@npm:10.3.10" + dependencies: + foreground-child: "npm:^3.1.0" + jackspeak: "npm:^2.3.5" + minimatch: "npm:^9.0.1" + minipass: "npm:^5.0.0 || ^6.0.2 || ^7.0.0" + path-scurry: "npm:^1.10.1" + bin: + glob: dist/esm/bin.mjs + checksum: 13d8a1feb7eac7945f8c8480e11cd4a44b24d26503d99a8d8ac8d5aefbf3e9802a2b6087318a829fad04cb4e829f25c5f4f1110c68966c498720dd261c7e344d + languageName: node + linkType: hard + +"globals@npm:^13.2.0": + version: 13.24.0 + resolution: "globals@npm:13.24.0" + dependencies: + type-fest: "npm:^0.20.2" + checksum: d3c11aeea898eb83d5ec7a99508600fbe8f83d2cf00cbb77f873dbf2bcb39428eff1b538e4915c993d8a3b3473fa71eeebfe22c9bb3a3003d1e26b1f2c8a42cd + languageName: node + linkType: hard + +"gopd@npm:^1.0.1": + version: 1.0.1 + resolution: "gopd@npm:1.0.1" + dependencies: + get-intrinsic: "npm:^1.1.3" + checksum: 505c05487f7944c552cee72087bf1567debb470d4355b1335f2c262d218ebbff805cd3715448fe29b4b380bae6912561d0467233e4165830efd28da241418c63 + languageName: node + linkType: hard + +"graceful-fs@npm:^4.2.6": + version: 4.2.11 + resolution: "graceful-fs@npm:4.2.11" + checksum: 386d011a553e02bc594ac2ca0bd6d9e4c22d7fa8cfbfc448a6d148c59ea881b092db9dbe3547ae4b88e55f1b01f7c4a2ecc53b310c042793e63aa44cf6c257f2 + languageName: node + linkType: hard + +"has-flag@npm:^3.0.0": + version: 3.0.0 + resolution: "has-flag@npm:3.0.0" + checksum: 1c6c83b14b8b1b3c25b0727b8ba3e3b647f99e9e6e13eb7322107261de07a4c1be56fc0d45678fc376e09772a3a1642ccdaf8fc69bdf123b6c086598397ce473 + languageName: node + linkType: hard + +"has-flag@npm:^4.0.0": + version: 4.0.0 + resolution: "has-flag@npm:4.0.0" + checksum: 2e789c61b7888d66993e14e8331449e525ef42aac53c627cc53d1c3334e768bcb6abdc4f5f0de1478a25beec6f0bd62c7549058b7ac53e924040d4f301f02fd1 + languageName: node + linkType: hard + +"has-property-descriptors@npm:^1.0.0, has-property-descriptors@npm:^1.0.1": + version: 1.0.1 + resolution: "has-property-descriptors@npm:1.0.1" + dependencies: + get-intrinsic: "npm:^1.2.2" + checksum: d62ba94b40150b00d621bc64a6aedb5bf0ee495308b4b7ed6bac856043db3cdfb1db553ae81cec91c9d2bd82057ff0e94145e7fa25d5aa5985ed32e0921927f6 + languageName: node + linkType: hard + +"has-proto@npm:^1.0.1": + version: 1.0.1 + resolution: "has-proto@npm:1.0.1" + checksum: c8a8fe411f810b23a564bd5546a8f3f0fff6f1b692740eb7a2fdc9df716ef870040806891e2f23ff4653f1083e3895bf12088703dd1a0eac3d9202d3a4768cd0 + languageName: node + linkType: hard + +"has-symbols@npm:^1.0.3": + version: 1.0.3 + resolution: "has-symbols@npm:1.0.3" + checksum: e6922b4345a3f37069cdfe8600febbca791c94988c01af3394d86ca3360b4b93928bbf395859158f88099cb10b19d98e3bbab7c9ff2c1bd09cf665ee90afa2c3 + languageName: node + linkType: hard + +"hasown@npm:^2.0.0": + version: 2.0.0 + resolution: "hasown@npm:2.0.0" + dependencies: + function-bind: "npm:^1.1.2" + checksum: 5d415b114f410661208c95e7ab4879f1cc2765b8daceff4dc8718317d1cb7b9ffa7c5d1eafd9a4389c9aab7445d6ea88e05f3096cb1e529618b55304956b87fc + languageName: node + linkType: hard + +"htmlnano@npm:^2.0.0": + version: 2.1.0 + resolution: "htmlnano@npm:2.1.0" + dependencies: + cosmiconfig: "npm:^8.0.0" + posthtml: "npm:^0.16.5" + timsort: "npm:^0.3.0" + peerDependencies: + cssnano: ^6.0.0 + postcss: ^8.3.11 + purgecss: ^5.0.0 + relateurl: ^0.2.7 + srcset: 4.0.0 + svgo: ^3.0.2 + terser: ^5.10.0 + uncss: ^0.17.3 + peerDependenciesMeta: + cssnano: + optional: true + postcss: + optional: true + purgecss: + optional: true + relateurl: + optional: true + srcset: + optional: true + svgo: + optional: true + terser: + optional: true + uncss: + optional: true + checksum: 33e78a18e044c6db671626babfdab60bd483c432164e6e38ef70c895a5698a91215972ebf2dbd7f7f8c05fbac80fa169ee1dde4bc0f1427d7dc3c162e0300610 + languageName: node + linkType: hard + +"htmlparser2@npm:^7.1.1": + version: 7.2.0 + resolution: "htmlparser2@npm:7.2.0" + dependencies: + domelementtype: "npm:^2.0.1" + domhandler: "npm:^4.2.2" + domutils: "npm:^2.8.0" + entities: "npm:^3.0.1" + checksum: 7e1fa7f3b2635f2a1c5272765e25aab33b241d84a43e9d27f28a0b7166b51a8025dec40a6a29af38d6a698a2f1d2983cb43e5c61d4e07ec5aa9df672a7460e16 + languageName: node + linkType: hard + +"http-cache-semantics@npm:^4.1.1": + version: 4.1.1 + resolution: "http-cache-semantics@npm:4.1.1" + checksum: ce1319b8a382eb3cbb4a37c19f6bfe14e5bb5be3d09079e885e8c513ab2d3cd9214902f8a31c9dc4e37022633ceabfc2d697405deeaf1b8f3552bb4ed996fdfc + languageName: node + linkType: hard + +"http-proxy-agent@npm:^7.0.0": + version: 7.0.0 + resolution: "http-proxy-agent@npm:7.0.0" + dependencies: + agent-base: "npm:^7.1.0" + debug: "npm:^4.3.4" + checksum: a11574ff39436cee3c7bc67f259444097b09474605846ddd8edf0bf4ad8644be8533db1aa463426e376865047d05dc22755e638632819317c0c2f1b2196657c8 + languageName: node + linkType: hard + +"https-proxy-agent@npm:^7.0.1": + version: 7.0.2 + resolution: "https-proxy-agent@npm:7.0.2" + dependencies: + agent-base: "npm:^7.0.2" + debug: "npm:4" + checksum: 7735eb90073db087e7e79312e3d97c8c04baf7ea7ca7b013382b6a45abbaa61b281041a98f4e13c8c80d88f843785bcc84ba189165b4b4087b1e3496ba656d77 + languageName: node + linkType: hard + +"iconv-lite@npm:0.6, iconv-lite@npm:^0.6.2": + version: 0.6.3 + resolution: "iconv-lite@npm:0.6.3" + dependencies: + safer-buffer: "npm:>= 2.1.2 < 3.0.0" + checksum: 98102bc66b33fcf5ac044099d1257ba0b7ad5e3ccd3221f34dd508ab4070edff183276221684e1e0555b145fce0850c9f7d2b60a9fcac50fbb4ea0d6e845a3b1 + languageName: node + linkType: hard + +"import-fresh@npm:^3.3.0": + version: 3.3.0 + resolution: "import-fresh@npm:3.3.0" + dependencies: + parent-module: "npm:^1.0.0" + resolve-from: "npm:^4.0.0" + checksum: 7f882953aa6b740d1f0e384d0547158bc86efbf2eea0f1483b8900a6f65c5a5123c2cf09b0d542cc419d0b98a759ecaeb394237e97ea427f2da221dc3cd80cc3 + languageName: node + linkType: hard + +"imurmurhash@npm:^0.1.4": + version: 0.1.4 + resolution: "imurmurhash@npm:0.1.4" + checksum: 8b51313850dd33605c6c9d3fd9638b714f4c4c40250cff658209f30d40da60f78992fb2df5dabee4acf589a6a82bbc79ad5486550754bd9ec4e3fc0d4a57d6a6 + languageName: node + linkType: hard + +"indent-string@npm:^4.0.0": + version: 4.0.0 + resolution: "indent-string@npm:4.0.0" + checksum: 1e1904ddb0cb3d6cce7cd09e27a90184908b7a5d5c21b92e232c93579d314f0b83c246ffb035493d0504b1e9147ba2c9b21df0030f48673fba0496ecd698161f + languageName: node + linkType: hard + +"internmap@npm:1 - 2": + version: 2.0.3 + resolution: "internmap@npm:2.0.3" + checksum: 8cedd57f07bbc22501516fbfc70447f0c6812871d471096fad9ea603516eacc2137b633633daf432c029712df0baefd793686388ddf5737e3ea15074b877f7ed + languageName: node + linkType: hard + +"ip@npm:^2.0.0": + version: 2.0.0 + resolution: "ip@npm:2.0.0" + checksum: 8d186cc5585f57372847ae29b6eba258c68862055e18a75cc4933327232cb5c107f89800ce29715d542eef2c254fbb68b382e780a7414f9ee7caf60b7a473958 + languageName: node + linkType: hard + +"is-arrayish@npm:^0.2.1": + version: 0.2.1 + resolution: "is-arrayish@npm:0.2.1" + checksum: e7fb686a739068bb70f860b39b67afc62acc62e36bb61c5f965768abce1873b379c563e61dd2adad96ebb7edf6651111b385e490cf508378959b0ed4cac4e729 + languageName: node + linkType: hard + +"is-extglob@npm:^2.1.1": + version: 2.1.1 + resolution: "is-extglob@npm:2.1.1" + checksum: 5487da35691fbc339700bbb2730430b07777a3c21b9ebaecb3072512dfd7b4ba78ac2381a87e8d78d20ea08affb3f1971b4af629173a6bf435ff8a4c47747912 + languageName: node + linkType: hard + +"is-fullwidth-code-point@npm:^3.0.0": + version: 3.0.0 + resolution: "is-fullwidth-code-point@npm:3.0.0" + checksum: bb11d825e049f38e04c06373a8d72782eee0205bda9d908cc550ccb3c59b99d750ff9537982e01733c1c94a58e35400661f57042158ff5e8f3e90cf936daf0fc + languageName: node + linkType: hard + +"is-glob@npm:^4.0.3": + version: 4.0.3 + resolution: "is-glob@npm:4.0.3" + dependencies: + is-extglob: "npm:^2.1.1" + checksum: 17fb4014e22be3bbecea9b2e3a76e9e34ff645466be702f1693e8f1ee1adac84710d0be0bd9f967d6354036fd51ab7c2741d954d6e91dae6bb69714de92c197a + languageName: node + linkType: hard + +"is-json@npm:^2.0.1": + version: 2.0.1 + resolution: "is-json@npm:2.0.1" + checksum: 49233aa560396e6365186be2f3a4618bf8b8067c1a97f2a25b8de09a9d7f326985f0163508067abeae5a21c69594a2a537f0147a5c4050ef097c15964e994cb4 + languageName: node + linkType: hard + +"is-lambda@npm:^1.0.1": + version: 1.0.1 + resolution: "is-lambda@npm:1.0.1" + checksum: 85fee098ae62ba6f1e24cf22678805473c7afd0fb3978a3aa260e354cb7bcb3a5806cf0a98403188465efedec41ab4348e8e4e79305d409601323855b3839d4d + languageName: node + linkType: hard + +"is-number@npm:^7.0.0": + version: 7.0.0 + resolution: "is-number@npm:7.0.0" + checksum: b4686d0d3053146095ccd45346461bc8e53b80aeb7671cc52a4de02dbbf7dc0d1d2a986e2fe4ae206984b4d34ef37e8b795ebc4f4295c978373e6575e295d811 + languageName: node + linkType: hard + +"isexe@npm:^2.0.0": + version: 2.0.0 + resolution: "isexe@npm:2.0.0" + checksum: 228cfa503fadc2c31596ab06ed6aa82c9976eec2bfd83397e7eaf06d0ccf42cd1dfd6743bf9aeb01aebd4156d009994c5f76ea898d2832c1fe342da923ca457d + languageName: node + linkType: hard + +"isexe@npm:^3.1.1": + version: 3.1.1 + resolution: "isexe@npm:3.1.1" + checksum: 9ec257654093443eb0a528a9c8cbba9c0ca7616ccb40abd6dde7202734d96bb86e4ac0d764f0f8cd965856aacbff2f4ce23e730dc19dfb41e3b0d865ca6fdcc7 + languageName: node + linkType: hard + +"ismobilejs@npm:^1.1.0": + version: 1.1.1 + resolution: "ismobilejs@npm:1.1.1" + checksum: 3f15f3bd8fe2290bc2f7398c95ceee7525db7d8cf76b8def201c19c49b3a37be33d9ecedc4e316aadcc67a70859ae491981e07cf998db1ec3e5ad0df905bc16a + languageName: node + linkType: hard + +"jackspeak@npm:^2.3.5": + version: 2.3.6 + resolution: "jackspeak@npm:2.3.6" + dependencies: + "@isaacs/cliui": "npm:^8.0.2" + "@pkgjs/parseargs": "npm:^0.11.0" + dependenciesMeta: + "@pkgjs/parseargs": + optional: true + checksum: f01d8f972d894cd7638bc338e9ef5ddb86f7b208ce177a36d718eac96ec86638a6efa17d0221b10073e64b45edc2ce15340db9380b1f5d5c5d000cbc517dc111 + languageName: node + linkType: hard + +"js-tokens@npm:^4.0.0": + version: 4.0.0 + resolution: "js-tokens@npm:4.0.0" + checksum: e248708d377aa058eacf2037b07ded847790e6de892bbad3dac0abba2e759cb9f121b00099a65195616badcb6eca8d14d975cb3e89eb1cfda644756402c8aeed + languageName: node + linkType: hard + +"js-yaml@npm:^4.1.0": + version: 4.1.0 + resolution: "js-yaml@npm:4.1.0" + dependencies: + argparse: "npm:^2.0.1" + bin: + js-yaml: bin/js-yaml.js + checksum: 184a24b4eaacfce40ad9074c64fd42ac83cf74d8c8cd137718d456ced75051229e5061b8633c3366b8aada17945a7a356b337828c19da92b51ae62126575018f + languageName: node + linkType: hard + +"json-parse-even-better-errors@npm:^2.3.0": + version: 2.3.1 + resolution: "json-parse-even-better-errors@npm:2.3.1" + checksum: 140932564c8f0b88455432e0f33c4cb4086b8868e37524e07e723f4eaedb9425bdc2bafd71bd1d9765bd15fd1e2d126972bc83990f55c467168c228c24d665f3 + languageName: node + linkType: hard + +"json5@npm:^2.2.0, json5@npm:^2.2.1": + version: 2.2.3 + resolution: "json5@npm:2.2.3" + bin: + json5: lib/cli.js + checksum: 5a04eed94810fa55c5ea138b2f7a5c12b97c3750bc63d11e511dcecbfef758003861522a070c2272764ee0f4e3e323862f386945aeb5b85b87ee43f084ba586c + languageName: node + linkType: hard + +"lightningcss-darwin-arm64@npm:1.23.0": + version: 1.23.0 + resolution: "lightningcss-darwin-arm64@npm:1.23.0" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"lightningcss-darwin-x64@npm:1.23.0": + version: 1.23.0 + resolution: "lightningcss-darwin-x64@npm:1.23.0" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"lightningcss-freebsd-x64@npm:1.23.0": + version: 1.23.0 + resolution: "lightningcss-freebsd-x64@npm:1.23.0" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + +"lightningcss-linux-arm-gnueabihf@npm:1.23.0": + version: 1.23.0 + resolution: "lightningcss-linux-arm-gnueabihf@npm:1.23.0" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + +"lightningcss-linux-arm64-gnu@npm:1.23.0": + version: 1.23.0 + resolution: "lightningcss-linux-arm64-gnu@npm:1.23.0" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + +"lightningcss-linux-arm64-musl@npm:1.23.0": + version: 1.23.0 + resolution: "lightningcss-linux-arm64-musl@npm:1.23.0" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + +"lightningcss-linux-x64-gnu@npm:1.23.0": + version: 1.23.0 + resolution: "lightningcss-linux-x64-gnu@npm:1.23.0" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + +"lightningcss-linux-x64-musl@npm:1.23.0": + version: 1.23.0 + resolution: "lightningcss-linux-x64-musl@npm:1.23.0" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + +"lightningcss-win32-x64-msvc@npm:1.23.0": + version: 1.23.0 + resolution: "lightningcss-win32-x64-msvc@npm:1.23.0" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"lightningcss@npm:^1.22.1": + version: 1.23.0 + resolution: "lightningcss@npm:1.23.0" + dependencies: + detect-libc: "npm:^1.0.3" + lightningcss-darwin-arm64: "npm:1.23.0" + lightningcss-darwin-x64: "npm:1.23.0" + lightningcss-freebsd-x64: "npm:1.23.0" + lightningcss-linux-arm-gnueabihf: "npm:1.23.0" + lightningcss-linux-arm64-gnu: "npm:1.23.0" + lightningcss-linux-arm64-musl: "npm:1.23.0" + lightningcss-linux-x64-gnu: "npm:1.23.0" + lightningcss-linux-x64-musl: "npm:1.23.0" + lightningcss-win32-x64-msvc: "npm:1.23.0" + dependenciesMeta: + lightningcss-darwin-arm64: + optional: true + lightningcss-darwin-x64: + optional: true + lightningcss-freebsd-x64: + optional: true + lightningcss-linux-arm-gnueabihf: + optional: true + lightningcss-linux-arm64-gnu: + optional: true + lightningcss-linux-arm64-musl: + optional: true + lightningcss-linux-x64-gnu: + optional: true + lightningcss-linux-x64-musl: + optional: true + lightningcss-win32-x64-msvc: + optional: true + checksum: d8ba1e9a4533a98c239ed2baede87c0b9128a26ea152552935769d40ee22c7c2d658d51d285a30535e197668daf856364774ce2a8f855f07143b91a1fab49d55 + languageName: node + linkType: hard + +"lines-and-columns@npm:^1.1.6": + version: 1.2.4 + resolution: "lines-and-columns@npm:1.2.4" + checksum: 3da6ee62d4cd9f03f5dc90b4df2540fb85b352081bee77fe4bbcd12c9000ead7f35e0a38b8d09a9bb99b13223446dd8689ff3c4959807620726d788701a83d2d + languageName: node + linkType: hard + +"lmdb@npm:2.8.5": + version: 2.8.5 + resolution: "lmdb@npm:2.8.5" + dependencies: + "@lmdb/lmdb-darwin-arm64": "npm:2.8.5" + "@lmdb/lmdb-darwin-x64": "npm:2.8.5" + "@lmdb/lmdb-linux-arm": "npm:2.8.5" + "@lmdb/lmdb-linux-arm64": "npm:2.8.5" + "@lmdb/lmdb-linux-x64": "npm:2.8.5" + "@lmdb/lmdb-win32-x64": "npm:2.8.5" + msgpackr: "npm:^1.9.5" + node-addon-api: "npm:^6.1.0" + node-gyp: "npm:latest" + node-gyp-build-optional-packages: "npm:5.1.1" + ordered-binary: "npm:^1.4.1" + weak-lru-cache: "npm:^1.2.2" + dependenciesMeta: + "@lmdb/lmdb-darwin-arm64": + optional: true + "@lmdb/lmdb-darwin-x64": + optional: true + "@lmdb/lmdb-linux-arm": + optional: true + "@lmdb/lmdb-linux-arm64": + optional: true + "@lmdb/lmdb-linux-x64": + optional: true + "@lmdb/lmdb-win32-x64": + optional: true + bin: + download-lmdb-prebuilds: bin/download-prebuilds.js + checksum: 5c95ae636611f32d3583b26bca0d4b0dc236378f785b5735420edda62f88ddacc17c7586d586779a49f3377422c85c3e0b416c4a47f1c21945f76f001551afc9 + languageName: node + linkType: hard + +"lru-cache@npm:^10.0.1, lru-cache@npm:^9.1.1 || ^10.0.0": + version: 10.1.0 + resolution: "lru-cache@npm:10.1.0" + checksum: 778bc8b2626daccd75f24c4b4d10632496e21ba064b126f526c626fbdbc5b28c472013fccd45d7646b9e1ef052444824854aed617b59cd570d01a8b7d651fc1e + languageName: node + linkType: hard + +"lru-cache@npm:^6.0.0": + version: 6.0.0 + resolution: "lru-cache@npm:6.0.0" + dependencies: + yallist: "npm:^4.0.0" + checksum: cb53e582785c48187d7a188d3379c181b5ca2a9c78d2bce3e7dee36f32761d1c42983da3fe12b55cb74e1779fa94cdc2e5367c028a9b35317184ede0c07a30a9 + languageName: node + linkType: hard + +"make-fetch-happen@npm:^13.0.0": + version: 13.0.0 + resolution: "make-fetch-happen@npm:13.0.0" + dependencies: + "@npmcli/agent": "npm:^2.0.0" + cacache: "npm:^18.0.0" + http-cache-semantics: "npm:^4.1.1" + is-lambda: "npm:^1.0.1" + minipass: "npm:^7.0.2" + minipass-fetch: "npm:^3.0.0" + minipass-flush: "npm:^1.0.5" + minipass-pipeline: "npm:^1.2.4" + negotiator: "npm:^0.6.3" + promise-retry: "npm:^2.0.1" + ssri: "npm:^10.0.0" + checksum: 43b9f6dcbc6fe8b8604cb6396957c3698857a15ba4dbc38284f7f0e61f248300585ef1eb8cc62df54e9c724af977e45b5cdfd88320ef7f53e45070ed3488da55 + languageName: node + linkType: hard + +"mdn-data@npm:2.0.14": + version: 2.0.14 + resolution: "mdn-data@npm:2.0.14" + checksum: 67241f8708c1e665a061d2b042d2d243366e93e5bf1f917693007f6d55111588b952dcbfd3ea9c2d0969fb754aad81b30fdcfdcc24546495fc3b24336b28d4bd + languageName: node + linkType: hard + +"micromatch@npm:^4.0.5": + version: 4.0.5 + resolution: "micromatch@npm:4.0.5" + dependencies: + braces: "npm:^3.0.2" + picomatch: "npm:^2.3.1" + checksum: 3d6505b20f9fa804af5d8c596cb1c5e475b9b0cd05f652c5b56141cf941bd72adaeb7a436fda344235cef93a7f29b7472efc779fcdb83b478eab0867b95cdeff + languageName: node + linkType: hard + +"minimatch@npm:^9.0.1": + version: 9.0.3 + resolution: "minimatch@npm:9.0.3" + dependencies: + brace-expansion: "npm:^2.0.1" + checksum: 85f407dcd38ac3e180f425e86553911d101455ca3ad5544d6a7cec16286657e4f8a9aa6695803025c55e31e35a91a2252b5dc8e7d527211278b8b65b4dbd5eac + languageName: node + linkType: hard + +"minipass-collect@npm:^2.0.1": + version: 2.0.1 + resolution: "minipass-collect@npm:2.0.1" + dependencies: + minipass: "npm:^7.0.3" + checksum: 5167e73f62bb74cc5019594709c77e6a742051a647fe9499abf03c71dca75515b7959d67a764bdc4f8b361cf897fbf25e2d9869ee039203ed45240f48b9aa06e + languageName: node + linkType: hard + +"minipass-fetch@npm:^3.0.0": + version: 3.0.4 + resolution: "minipass-fetch@npm:3.0.4" + dependencies: + encoding: "npm:^0.1.13" + minipass: "npm:^7.0.3" + minipass-sized: "npm:^1.0.3" + minizlib: "npm:^2.1.2" + dependenciesMeta: + encoding: + optional: true + checksum: 1b63c1f3313e88eeac4689f1b71c9f086598db9a189400e3ee960c32ed89e06737fa23976c9305c2d57464fb3fcdc12749d3378805c9d6176f5569b0d0ee8a75 + languageName: node + linkType: hard + +"minipass-flush@npm:^1.0.5": + version: 1.0.5 + resolution: "minipass-flush@npm:1.0.5" + dependencies: + minipass: "npm:^3.0.0" + checksum: 2a51b63feb799d2bb34669205eee7c0eaf9dce01883261a5b77410c9408aa447e478efd191b4de6fc1101e796ff5892f8443ef20d9544385819093dbb32d36bd + languageName: node + linkType: hard + +"minipass-pipeline@npm:^1.2.4": + version: 1.2.4 + resolution: "minipass-pipeline@npm:1.2.4" + dependencies: + minipass: "npm:^3.0.0" + checksum: cbda57cea20b140b797505dc2cac71581a70b3247b84480c1fed5ca5ba46c25ecc25f68bfc9e6dcb1a6e9017dab5c7ada5eab73ad4f0a49d84e35093e0c643f2 + languageName: node + linkType: hard + +"minipass-sized@npm:^1.0.3": + version: 1.0.3 + resolution: "minipass-sized@npm:1.0.3" + dependencies: + minipass: "npm:^3.0.0" + checksum: 298f124753efdc745cfe0f2bdfdd81ba25b9f4e753ca4a2066eb17c821f25d48acea607dfc997633ee5bf7b6dfffb4eee4f2051eb168663f0b99fad2fa4829cb + languageName: node + linkType: hard + +"minipass@npm:^3.0.0": + version: 3.3.6 + resolution: "minipass@npm:3.3.6" + dependencies: + yallist: "npm:^4.0.0" + checksum: a114746943afa1dbbca8249e706d1d38b85ed1298b530f5808ce51f8e9e941962e2a5ad2e00eae7dd21d8a4aae6586a66d4216d1a259385e9d0358f0c1eba16c + languageName: node + linkType: hard + +"minipass@npm:^5.0.0": + version: 5.0.0 + resolution: "minipass@npm:5.0.0" + checksum: a91d8043f691796a8ac88df039da19933ef0f633e3d7f0d35dcd5373af49131cf2399bfc355f41515dc495e3990369c3858cd319e5c2722b4753c90bf3152462 + languageName: node + linkType: hard + +"minipass@npm:^5.0.0 || ^6.0.2 || ^7.0.0, minipass@npm:^7.0.2, minipass@npm:^7.0.3": + version: 7.0.4 + resolution: "minipass@npm:7.0.4" + checksum: 6c7370a6dfd257bf18222da581ba89a5eaedca10e158781232a8b5542a90547540b4b9b7e7f490e4cda43acfbd12e086f0453728ecf8c19e0ef6921bc5958ac5 + languageName: node + linkType: hard + +"minizlib@npm:^2.1.1, minizlib@npm:^2.1.2": + version: 2.1.2 + resolution: "minizlib@npm:2.1.2" + dependencies: + minipass: "npm:^3.0.0" + yallist: "npm:^4.0.0" + checksum: 64fae024e1a7d0346a1102bb670085b17b7f95bf6cfdf5b128772ec8faf9ea211464ea4add406a3a6384a7d87a0cd1a96263692134323477b4fb43659a6cab78 + languageName: node + linkType: hard + +"mkdirp@npm:^1.0.3": + version: 1.0.4 + resolution: "mkdirp@npm:1.0.4" + bin: + mkdirp: bin/cmd.js + checksum: 46ea0f3ffa8bc6a5bc0c7081ffc3907777f0ed6516888d40a518c5111f8366d97d2678911ad1a6882bf592fa9de6c784fea32e1687bb94e1f4944170af48a5cf + languageName: node + linkType: hard + +"ms@npm:2.1.2": + version: 2.1.2 + resolution: "ms@npm:2.1.2" + checksum: a437714e2f90dbf881b5191d35a6db792efbca5badf112f87b9e1c712aace4b4b9b742dd6537f3edf90fd6f684de897cec230abde57e87883766712ddda297cc + languageName: node + linkType: hard + +"msgpackr-extract@npm:^3.0.2": + version: 3.0.2 + resolution: "msgpackr-extract@npm:3.0.2" + dependencies: + "@msgpackr-extract/msgpackr-extract-darwin-arm64": "npm:3.0.2" + "@msgpackr-extract/msgpackr-extract-darwin-x64": "npm:3.0.2" + "@msgpackr-extract/msgpackr-extract-linux-arm": "npm:3.0.2" + "@msgpackr-extract/msgpackr-extract-linux-arm64": "npm:3.0.2" + "@msgpackr-extract/msgpackr-extract-linux-x64": "npm:3.0.2" + "@msgpackr-extract/msgpackr-extract-win32-x64": "npm:3.0.2" + node-gyp: "npm:latest" + node-gyp-build-optional-packages: "npm:5.0.7" + dependenciesMeta: + "@msgpackr-extract/msgpackr-extract-darwin-arm64": + optional: true + "@msgpackr-extract/msgpackr-extract-darwin-x64": + optional: true + "@msgpackr-extract/msgpackr-extract-linux-arm": + optional: true + "@msgpackr-extract/msgpackr-extract-linux-arm64": + optional: true + "@msgpackr-extract/msgpackr-extract-linux-x64": + optional: true + "@msgpackr-extract/msgpackr-extract-win32-x64": + optional: true + bin: + download-msgpackr-prebuilds: bin/download-prebuilds.js + checksum: f14727e0121c241a11cf75824f87822c0a08d65e6b8eba8a3fbf26c7d7287ea3f8ca3ab76887fda781a203bd16e51705207d82593ba6f06abca3181c743a352d + languageName: node + linkType: hard + +"msgpackr@npm:^1.9.5, msgpackr@npm:^1.9.9": + version: 1.10.1 + resolution: "msgpackr@npm:1.10.1" + dependencies: + msgpackr-extract: "npm:^3.0.2" + dependenciesMeta: + msgpackr-extract: + optional: true + checksum: 2e6ed91af89ec15d1e5595c5b837a4adcbb185b0fbd4773d728ced89ab4abbdd3401f6777b193d487d9807e1cb0cf3da1ba9a0bd2d5a553e22355cea84a36bab + languageName: node + linkType: hard + +"negotiator@npm:^0.6.3": + version: 0.6.3 + resolution: "negotiator@npm:0.6.3" + checksum: 3ec9fd413e7bf071c937ae60d572bc67155262068ed522cf4b3be5edbe6ddf67d095ec03a3a14ebf8fc8e95f8e1d61be4869db0dbb0de696f6b837358bd43fc2 + languageName: node + linkType: hard + +"node-addon-api@npm:^6.1.0": + version: 6.1.0 + resolution: "node-addon-api@npm:6.1.0" + dependencies: + node-gyp: "npm:latest" + checksum: d2699c4ad15740fd31482a3b6fca789af7723ab9d393adc6ac45250faaee72edad8f0b10b2b9d087df0de93f1bdc16d97afdd179b26b9ebc9ed68b569faa4bac + languageName: node + linkType: hard + +"node-addon-api@npm:^7.0.0": + version: 7.1.0 + resolution: "node-addon-api@npm:7.1.0" + dependencies: + node-gyp: "npm:latest" + checksum: 2e096ab079e3c46d33b0e252386e9c239c352f7cc6d75363d9a3c00bdff34c1a5da170da861917512843f213c32d024ced9dc9552b968029786480d18727ec66 + languageName: node + linkType: hard + +"node-gyp-build-optional-packages@npm:5.0.7": + version: 5.0.7 + resolution: "node-gyp-build-optional-packages@npm:5.0.7" + bin: + node-gyp-build-optional-packages: bin.js + node-gyp-build-optional-packages-optional: optional.js + node-gyp-build-optional-packages-test: build-test.js + checksum: e0edb57358dfa8e31c26b38310ddc5ae81d19fd13b3bf095c41215dfd6a033b1269b510c3ce5e73f7a4ed3d36f101ea47716ec75be38f5e31916d185e7f18905 + languageName: node + linkType: hard + +"node-gyp-build-optional-packages@npm:5.1.1": + version: 5.1.1 + resolution: "node-gyp-build-optional-packages@npm:5.1.1" + dependencies: + detect-libc: "npm:^2.0.1" + bin: + node-gyp-build-optional-packages: bin.js + node-gyp-build-optional-packages-optional: optional.js + node-gyp-build-optional-packages-test: build-test.js + checksum: f9fad2061c48fb0fc90831cd11d6a7670d731d22a5b00c7d3441b43b4003543299ff64ff2729afe2cefd7d14928e560d469336e5bb00f613932ec2cd56b3665b + languageName: node + linkType: hard + +"node-gyp@npm:latest": + version: 10.0.1 + resolution: "node-gyp@npm:10.0.1" + dependencies: + env-paths: "npm:^2.2.0" + exponential-backoff: "npm:^3.1.1" + glob: "npm:^10.3.10" + graceful-fs: "npm:^4.2.6" + make-fetch-happen: "npm:^13.0.0" + nopt: "npm:^7.0.0" + proc-log: "npm:^3.0.0" + semver: "npm:^7.3.5" + tar: "npm:^6.1.2" + which: "npm:^4.0.0" + bin: + node-gyp: bin/node-gyp.js + checksum: abddfff7d873312e4ed4a5fb75ce893a5c4fb69e7fcb1dfa71c28a6b92a7f1ef6b62790dffb39181b5a82728ba8f2f32d229cf8cbe66769fe02cea7db4a555aa + languageName: node + linkType: hard + +"node-releases@npm:^2.0.14": + version: 2.0.14 + resolution: "node-releases@npm:2.0.14" + checksum: 199fc93773ae70ec9969bc6d5ac5b2bbd6eb986ed1907d751f411fef3ede0e4bfdb45ceb43711f8078bea237b6036db8b1bf208f6ff2b70c7d615afd157f3ab9 + languageName: node + linkType: hard + +"nopt@npm:^7.0.0": + version: 7.2.0 + resolution: "nopt@npm:7.2.0" + dependencies: + abbrev: "npm:^2.0.0" + bin: + nopt: bin/nopt.js + checksum: 9bd7198df6f16eb29ff16892c77bcf7f0cc41f9fb5c26280ac0def2cf8cf319f3b821b3af83eba0e74c85807cc430a16efe0db58fe6ae1f41e69519f585b6aff + languageName: node + linkType: hard + +"nth-check@npm:^2.0.1": + version: 2.1.1 + resolution: "nth-check@npm:2.1.1" + dependencies: + boolbase: "npm:^1.0.0" + checksum: 5fee7ff309727763689cfad844d979aedd2204a817fbaaf0e1603794a7c20db28548d7b024692f953557df6ce4a0ee4ae46cd8ebd9b36cfb300b9226b567c479 + languageName: node + linkType: hard + +"nullthrows@npm:^1.1.1": + version: 1.1.1 + resolution: "nullthrows@npm:1.1.1" + checksum: 56f34bd7c3dcb3bd23481a277fa22918120459d3e9d95ca72976c72e9cac33a97483f0b95fc420e2eb546b9fe6db398273aba9a938650cdb8c98ee8f159dcb30 + languageName: node + linkType: hard + +"object-inspect@npm:^1.9.0": + version: 1.13.1 + resolution: "object-inspect@npm:1.13.1" + checksum: fad603f408e345c82e946abdf4bfd774260a5ed3e5997a0b057c44153ac32c7271ff19e3a5ae39c858da683ba045ccac2f65245c12763ce4e8594f818f4a648d + languageName: node + linkType: hard + +"ordered-binary@npm:^1.4.1": + version: 1.5.1 + resolution: "ordered-binary@npm:1.5.1" + checksum: fb4c74e07436d0bf33d3b537c18dccafb39a60750a64d8b8fbd55f0b0f8eb7dad710f663b9c2edd1d59e9a27e13b638099da901ecf1cc95cd40173f42cf70f9e + languageName: node + linkType: hard + +"p-map@npm:^4.0.0": + version: 4.0.0 + resolution: "p-map@npm:4.0.0" + dependencies: + aggregate-error: "npm:^3.0.0" + checksum: 592c05bd6262c466ce269ff172bb8de7c6975afca9b50c975135b974e9bdaafbfe80e61aaaf5be6d1200ba08b30ead04b88cfa7e25ff1e3b93ab28c9f62a2c75 + languageName: node + linkType: hard + +"parcel@npm:^2.11.0": + version: 2.11.0 + resolution: "parcel@npm:2.11.0" + dependencies: + "@parcel/config-default": "npm:2.11.0" + "@parcel/core": "npm:2.11.0" + "@parcel/diagnostic": "npm:2.11.0" + "@parcel/events": "npm:2.11.0" + "@parcel/fs": "npm:2.11.0" + "@parcel/logger": "npm:2.11.0" + "@parcel/package-manager": "npm:2.11.0" + "@parcel/reporter-cli": "npm:2.11.0" + "@parcel/reporter-dev-server": "npm:2.11.0" + "@parcel/reporter-tracer": "npm:2.11.0" + "@parcel/utils": "npm:2.11.0" + chalk: "npm:^4.1.0" + commander: "npm:^7.0.0" + get-port: "npm:^4.2.0" + bin: + parcel: lib/bin.js + checksum: 75599d36792e4f8b42e51e3a2117ca37f4a57074c33e757bf8eaffa92579b85adaf9ca68eed44117041481340aaac3a543ac083099643d2bd08fc93e102f0607 + languageName: node + linkType: hard + +"parent-module@npm:^1.0.0": + version: 1.0.1 + resolution: "parent-module@npm:1.0.1" + dependencies: + callsites: "npm:^3.0.0" + checksum: c63d6e80000d4babd11978e0d3fee386ca7752a02b035fd2435960ffaa7219dc42146f07069fb65e6e8bf1caef89daf9af7535a39bddf354d78bf50d8294f556 + languageName: node + linkType: hard + +"parse-json@npm:^5.2.0": + version: 5.2.0 + resolution: "parse-json@npm:5.2.0" + dependencies: + "@babel/code-frame": "npm:^7.0.0" + error-ex: "npm:^1.3.1" + json-parse-even-better-errors: "npm:^2.3.0" + lines-and-columns: "npm:^1.1.6" + checksum: 77947f2253005be7a12d858aedbafa09c9ae39eb4863adf330f7b416ca4f4a08132e453e08de2db46459256fb66afaac5ee758b44fe6541b7cdaf9d252e59585 + languageName: node + linkType: hard + +"path-key@npm:^3.1.0": + version: 3.1.1 + resolution: "path-key@npm:3.1.1" + checksum: 748c43efd5a569c039d7a00a03b58eecd1d75f3999f5a28303d75f521288df4823bc057d8784eb72358b2895a05f29a070bc9f1f17d28226cc4e62494cc58c4c + languageName: node + linkType: hard + +"path-scurry@npm:^1.10.1": + version: 1.10.1 + resolution: "path-scurry@npm:1.10.1" + dependencies: + lru-cache: "npm:^9.1.1 || ^10.0.0" + minipass: "npm:^5.0.0 || ^6.0.2 || ^7.0.0" + checksum: e5dc78a7348d25eec61ab166317e9e9c7b46818aa2c2b9006c507a6ff48c672d011292d9662527213e558f5652ce0afcc788663a061d8b59ab495681840c0c1e + languageName: node + linkType: hard + +"path-type@npm:^4.0.0": + version: 4.0.0 + resolution: "path-type@npm:4.0.0" + checksum: 666f6973f332f27581371efaf303fd6c272cc43c2057b37aa99e3643158c7e4b2626549555d88626e99ea9e046f82f32e41bbde5f1508547e9a11b149b52387c + languageName: node + linkType: hard + +"picocolors@npm:^1.0.0": + version: 1.0.0 + resolution: "picocolors@npm:1.0.0" + checksum: 20a5b249e331c14479d94ec6817a182fd7a5680debae82705747b2db7ec50009a5f6648d0621c561b0572703f84dbef0858abcbd5856d3c5511426afcb1961f7 + languageName: node + linkType: hard + +"picomatch@npm:^2.3.1": + version: 2.3.1 + resolution: "picomatch@npm:2.3.1" + checksum: 26c02b8d06f03206fc2ab8d16f19960f2ff9e81a658f831ecb656d8f17d9edc799e8364b1f4a7873e89d9702dff96204be0fa26fe4181f6843f040f819dac4be + languageName: node + linkType: hard + +"pixi-viewport@npm:^5.0.2": + version: 5.0.2 + resolution: "pixi-viewport@npm:5.0.2" + checksum: 03487c6058be518bbd9b0120ce9a78db10aba9d6cdd61c88f5292f947d874031bfa7d275ee806501d8470b7bba5a5f6da25d492735a5ff271a42f94bead14651 + languageName: node + linkType: hard + +"pixi.js@npm:^7.3.3": + version: 7.3.3 + resolution: "pixi.js@npm:7.3.3" + dependencies: + "@pixi/accessibility": "npm:7.3.3" + "@pixi/app": "npm:7.3.3" + "@pixi/assets": "npm:7.3.3" + "@pixi/compressed-textures": "npm:7.3.3" + "@pixi/core": "npm:7.3.3" + "@pixi/display": "npm:7.3.3" + "@pixi/events": "npm:7.3.3" + "@pixi/extensions": "npm:7.3.3" + "@pixi/extract": "npm:7.3.3" + "@pixi/filter-alpha": "npm:7.3.3" + "@pixi/filter-blur": "npm:7.3.3" + "@pixi/filter-color-matrix": "npm:7.3.3" + "@pixi/filter-displacement": "npm:7.3.3" + "@pixi/filter-fxaa": "npm:7.3.3" + "@pixi/filter-noise": "npm:7.3.3" + "@pixi/graphics": "npm:7.3.3" + "@pixi/mesh": "npm:7.3.3" + "@pixi/mesh-extras": "npm:7.3.3" + "@pixi/mixin-cache-as-bitmap": "npm:7.3.3" + "@pixi/mixin-get-child-by-name": "npm:7.3.3" + "@pixi/mixin-get-global-position": "npm:7.3.3" + "@pixi/particle-container": "npm:7.3.3" + "@pixi/prepare": "npm:7.3.3" + "@pixi/sprite": "npm:7.3.3" + "@pixi/sprite-animated": "npm:7.3.3" + "@pixi/sprite-tiling": "npm:7.3.3" + "@pixi/spritesheet": "npm:7.3.3" + "@pixi/text": "npm:7.3.3" + "@pixi/text-bitmap": "npm:7.3.3" + "@pixi/text-html": "npm:7.3.3" + checksum: 56cef6b8113d63ee75b793f5020e2d2f5baa7b990b24a81feff87f9288e9588ad3100b8d3f31344819c9a0966e9bff8179f78ea171e03c83c317b53d5ef70155 + languageName: node + linkType: hard + +"postcss-value-parser@npm:^4.2.0": + version: 4.2.0 + resolution: "postcss-value-parser@npm:4.2.0" + checksum: f4142a4f56565f77c1831168e04e3effd9ffcc5aebaf0f538eee4b2d465adfd4b85a44257bb48418202a63806a7da7fe9f56c330aebb3cac898e46b4cbf49161 + languageName: node + linkType: hard + +"posthtml-parser@npm:^0.10.1": + version: 0.10.2 + resolution: "posthtml-parser@npm:0.10.2" + dependencies: + htmlparser2: "npm:^7.1.1" + checksum: 90c7c2e0892c18577a56a5dd60a54c40feb0be7c712a79f711e1730b5eea468f8d521d387af9f08d78e6bca9df613286c3ff8a95ac9426671cbe9021d7ec2ae5 + languageName: node + linkType: hard + +"posthtml-parser@npm:^0.11.0": + version: 0.11.0 + resolution: "posthtml-parser@npm:0.11.0" + dependencies: + htmlparser2: "npm:^7.1.1" + checksum: 89bf980a60124790f776a9f21aec0f154eba5412d16f0f3a95de7a53d31b9acb9264bf317ab40c080413e3018a8e65c86278e6e8c0731c8e0363418982ed4296 + languageName: node + linkType: hard + +"posthtml-render@npm:^3.0.0": + version: 3.0.0 + resolution: "posthtml-render@npm:3.0.0" + dependencies: + is-json: "npm:^2.0.1" + checksum: 7adb9c20d0908663019c3c2dede3f6cc8bd19c17c81a1f42a1d8772195be4e5252aeb72a764e92d3424aebfa8c5d35c7ef1ec25243a802d35897aa928858505b + languageName: node + linkType: hard + +"posthtml@npm:^0.16.4, posthtml@npm:^0.16.5": + version: 0.16.6 + resolution: "posthtml@npm:0.16.6" + dependencies: + posthtml-parser: "npm:^0.11.0" + posthtml-render: "npm:^3.0.0" + checksum: 0505cb70ece051206ffa932394181372be6390a974fd2f50e4e6fdd5d11e41feffba9a5f5e22809ca42899f79bd489d53ceac1d7ad0d782db9521b578e5b7f5a + languageName: node + linkType: hard + +"prettier@npm:^3.2.4": + version: 3.2.4 + resolution: "prettier@npm:3.2.4" + bin: + prettier: bin/prettier.cjs + checksum: 88dfeb78ac6096522c9a5b81f1413d875f568420d9bb6a5e5103527912519b993f2bcdcac311fcff5718d5869671d44e4f85827d3626f3a6ce32b9abc65d88e0 + languageName: node + linkType: hard + +"proc-log@npm:^3.0.0": + version: 3.0.0 + resolution: "proc-log@npm:3.0.0" + checksum: f66430e4ff947dbb996058f6fd22de2c66612ae1a89b097744e17fb18a4e8e7a86db99eda52ccf15e53f00b63f4ec0b0911581ff2aac0355b625c8eac509b0dc + languageName: node + linkType: hard + +"promise-retry@npm:^2.0.1": + version: 2.0.1 + resolution: "promise-retry@npm:2.0.1" + dependencies: + err-code: "npm:^2.0.2" + retry: "npm:^0.12.0" + checksum: 9c7045a1a2928094b5b9b15336dcd2a7b1c052f674550df63cc3f36cd44028e5080448175b6f6ca32b642de81150f5e7b1a98b728f15cb069f2dd60ac2616b96 + languageName: node + linkType: hard + +"punycode@npm:^1.4.1": + version: 1.4.1 + resolution: "punycode@npm:1.4.1" + checksum: 354b743320518aef36f77013be6e15da4db24c2b4f62c5f1eb0529a6ed02fbaf1cb52925785f6ab85a962f2b590d9cd5ad730b70da72b5f180e2556b8bd3ca08 + languageName: node + linkType: hard + +"qs@npm:^6.11.2": + version: 6.11.2 + resolution: "qs@npm:6.11.2" + dependencies: + side-channel: "npm:^1.0.4" + checksum: 4f95d4ff18ed480befcafa3390022817ffd3087fc65f146cceb40fc5edb9fa96cb31f648cae2fa96ca23818f0798bd63ad4ca369a0e22702fcd41379b3ab6571 + languageName: node + linkType: hard + +"react-error-overlay@npm:6.0.9": + version: 6.0.9 + resolution: "react-error-overlay@npm:6.0.9" + checksum: 02f51337f34589305f827249acb597446489794cc5b5e721a6260111325b56942a7471b76967cba304e797d7e4ef16dd0bd989c112dd0bb9586270df0d75a4a9 + languageName: node + linkType: hard + +"react-refresh@npm:^0.9.0": + version: 0.9.0 + resolution: "react-refresh@npm:0.9.0" + checksum: fa20f605e19dc10342e5cec8dcbb88cd4a473d26a7ff0acf1f0402e78f94ec309837be07a3cc3646f88d19f9ed07fa13a275f4656b5e3ced8fa23ce488984609 + languageName: node + linkType: hard + +"regenerator-runtime@npm:^0.13.7": + version: 0.13.11 + resolution: "regenerator-runtime@npm:0.13.11" + checksum: 12b069dc774001fbb0014f6a28f11c09ebfe3c0d984d88c9bced77fdb6fedbacbca434d24da9ae9371bfbf23f754869307fb51a4c98a8b8b18e5ef748677ca24 + languageName: node + linkType: hard + +"resolve-from@npm:^4.0.0": + version: 4.0.0 + resolution: "resolve-from@npm:4.0.0" + checksum: 8408eec31a3112ef96e3746c37be7d64020cda07c03a920f5024e77290a218ea758b26ca9529fd7b1ad283947f34b2291c1c0f6aa0ed34acfdda9c6014c8d190 + languageName: node + linkType: hard + +"retry@npm:^0.12.0": + version: 0.12.0 + resolution: "retry@npm:0.12.0" + checksum: 59933e8501727ba13ad73ef4a04d5280b3717fd650408460c987392efe9d7be2040778ed8ebe933c5cbd63da3dcc37919c141ef8af0a54a6e4fca5a2af177bfe + languageName: node + linkType: hard + +"robust-predicates@npm:^3.0.0": + version: 3.0.2 + resolution: "robust-predicates@npm:3.0.2" + checksum: 4ecd53649f1c2d49529c85518f2fa69ffb2f7a4453f7fd19c042421c7b4d76c3efb48bc1c740c8f7049346d7cb58cf08ee0c9adaae595cc23564d360adb1fde4 + languageName: node + linkType: hard + +"rw@npm:1": + version: 1.3.3 + resolution: "rw@npm:1.3.3" + checksum: b1e1ef37d1e79d9dc7050787866e30b6ddcb2625149276045c262c6b4d53075ddc35f387a856a8e76f0d0df59f4cd58fe24707e40797ebee66e542b840ed6a53 + languageName: node + linkType: hard + +"safe-buffer@npm:^5.0.1": + version: 5.2.1 + resolution: "safe-buffer@npm:5.2.1" + checksum: 6501914237c0a86e9675d4e51d89ca3c21ffd6a31642efeba25ad65720bce6921c9e7e974e5be91a786b25aa058b5303285d3c15dbabf983a919f5f630d349f3 + languageName: node + linkType: hard + +"safer-buffer@npm:>= 2.1.2 < 3.0.0": + version: 2.1.2 + resolution: "safer-buffer@npm:2.1.2" + checksum: 7e3c8b2e88a1841c9671094bbaeebd94448111dd90a81a1f606f3f67708a6ec57763b3b47f06da09fc6054193e0e6709e77325415dc8422b04497a8070fa02d4 + languageName: node + linkType: hard + +"semver@npm:^7.3.5, semver@npm:^7.5.2": + version: 7.5.4 + resolution: "semver@npm:7.5.4" + dependencies: + lru-cache: "npm:^6.0.0" + bin: + semver: bin/semver.js + checksum: 5160b06975a38b11c1ab55950cb5b8a23db78df88275d3d8a42ccf1f29e55112ac995b3a26a522c36e3b5f76b0445f1eef70d696b8c7862a2b4303d7b0e7609e + languageName: node + linkType: hard + +"set-function-length@npm:^1.1.1": + version: 1.2.0 + resolution: "set-function-length@npm:1.2.0" + dependencies: + define-data-property: "npm:^1.1.1" + function-bind: "npm:^1.1.2" + get-intrinsic: "npm:^1.2.2" + gopd: "npm:^1.0.1" + has-property-descriptors: "npm:^1.0.1" + checksum: b4fdf68bbfa9944284a9469c04e0d9cdb7924942fab75cd11fb61e8a7518f0d40bbbbc1b46871f648a93b97d170d8047fe3492cdadff066a8a8ae4ce68d0564a + languageName: node + linkType: hard + +"shebang-command@npm:^2.0.0": + version: 2.0.0 + resolution: "shebang-command@npm:2.0.0" + dependencies: + shebang-regex: "npm:^3.0.0" + checksum: a41692e7d89a553ef21d324a5cceb5f686d1f3c040759c50aab69688634688c5c327f26f3ecf7001ebfd78c01f3c7c0a11a7c8bfd0a8bc9f6240d4f40b224e4e + languageName: node + linkType: hard + +"shebang-regex@npm:^3.0.0": + version: 3.0.0 + resolution: "shebang-regex@npm:3.0.0" + checksum: 1dbed0726dd0e1152a92696c76c7f06084eb32a90f0528d11acd764043aacf76994b2fb30aa1291a21bd019d6699164d048286309a278855ee7bec06cf6fb690 + languageName: node + linkType: hard + +"side-channel@npm:^1.0.4": + version: 1.0.4 + resolution: "side-channel@npm:1.0.4" + dependencies: + call-bind: "npm:^1.0.0" + get-intrinsic: "npm:^1.0.2" + object-inspect: "npm:^1.9.0" + checksum: 054a5d23ee35054b2c4609b9fd2a0587760737782b5d765a9c7852264710cc39c6dcb56a9bbd6c12cd84071648aea3edb2359d2f6e560677eedadce511ac1da5 + languageName: node + linkType: hard + +"signal-exit@npm:^4.0.1": + version: 4.1.0 + resolution: "signal-exit@npm:4.1.0" + checksum: 41602dce540e46d599edba9d9860193398d135f7ff72cab629db5171516cfae628d21e7bfccde1bbfdf11c48726bc2a6d1a8fb8701125852fbfda7cf19c6aa83 + languageName: node + linkType: hard + +"smart-buffer@npm:^4.2.0": + version: 4.2.0 + resolution: "smart-buffer@npm:4.2.0" + checksum: a16775323e1404dd43fabafe7460be13a471e021637bc7889468eb45ce6a6b207261f454e4e530a19500cc962c4cc5348583520843b363f4193cee5c00e1e539 + languageName: node + linkType: hard + +"socks-proxy-agent@npm:^8.0.1": + version: 8.0.2 + resolution: "socks-proxy-agent@npm:8.0.2" + dependencies: + agent-base: "npm:^7.0.2" + debug: "npm:^4.3.4" + socks: "npm:^2.7.1" + checksum: a842402fc9b8848a31367f2811ca3cd14c4106588b39a0901cd7a69029998adfc6456b0203617c18ed090542ad0c24ee4e9d4c75a0c4b75071e214227c177eb7 + languageName: node + linkType: hard + +"socks@npm:^2.7.1": + version: 2.7.1 + resolution: "socks@npm:2.7.1" + dependencies: + ip: "npm:^2.0.0" + smart-buffer: "npm:^4.2.0" + checksum: 43f69dbc9f34fc8220bc51c6eea1c39715ab3cfdb115d6e3285f6c7d1a603c5c75655668a5bbc11e3c7e2c99d60321fb8d7ab6f38cda6a215fadd0d6d0b52130 + languageName: node + linkType: hard + +"source-map@npm:^0.6.1": + version: 0.6.1 + resolution: "source-map@npm:0.6.1" + checksum: ab55398007c5e5532957cb0beee2368529618ac0ab372d789806f5718123cc4367d57de3904b4e6a4170eb5a0b0f41373066d02ca0735a0c4d75c7d328d3e011 + languageName: node + linkType: hard + +"srcset@npm:4": + version: 4.0.0 + resolution: "srcset@npm:4.0.0" + checksum: 0685c3bd2423b33831734fb71560cd8784f024895e70ee2ac2c392e30047c27ffd9481e001950fb0503f4906bc3fe963145935604edad77944d09c9800990660 + languageName: node + linkType: hard + +"ssri@npm:^10.0.0": + version: 10.0.5 + resolution: "ssri@npm:10.0.5" + dependencies: + minipass: "npm:^7.0.3" + checksum: b091f2ae92474183c7ac5ed3f9811457e1df23df7a7e70c9476eaa9a0c4a0c8fc190fb45acefbf023ca9ee864dd6754237a697dc52a0fb182afe65d8e77443d8 + languageName: node + linkType: hard + +"stable@npm:^0.1.8": + version: 0.1.8 + resolution: "stable@npm:0.1.8" + checksum: df74b5883075076e78f8e365e4068ecd977af6c09da510cfc3148a303d4b87bc9aa8f7c48feb67ed4ef970b6140bd9eabba2129e28024aa88df5ea0114cba39d + languageName: node + linkType: hard + +"string-width-cjs@npm:string-width@^4.2.0, string-width@npm:^4.1.0, string-width@npm:^4.2.3": + version: 4.2.3 + resolution: "string-width@npm:4.2.3" + dependencies: + emoji-regex: "npm:^8.0.0" + is-fullwidth-code-point: "npm:^3.0.0" + strip-ansi: "npm:^6.0.1" + checksum: 1e525e92e5eae0afd7454086eed9c818ee84374bb80328fc41217ae72ff5f065ef1c9d7f72da41de40c75fa8bb3dee63d92373fd492c84260a552c636392a47b + languageName: node + linkType: hard + +"string-width@npm:^5.0.1, string-width@npm:^5.1.2": + version: 5.1.2 + resolution: "string-width@npm:5.1.2" + dependencies: + eastasianwidth: "npm:^0.2.0" + emoji-regex: "npm:^9.2.2" + strip-ansi: "npm:^7.0.1" + checksum: ab9c4264443d35b8b923cbdd513a089a60de339216d3b0ed3be3ba57d6880e1a192b70ae17225f764d7adbf5994e9bb8df253a944736c15a0240eff553c678ca + languageName: node + linkType: hard + +"strip-ansi-cjs@npm:strip-ansi@^6.0.1, strip-ansi@npm:^6.0.0, strip-ansi@npm:^6.0.1": + version: 6.0.1 + resolution: "strip-ansi@npm:6.0.1" + dependencies: + ansi-regex: "npm:^5.0.1" + checksum: 1ae5f212a126fe5b167707f716942490e3933085a5ff6c008ab97ab2f272c8025d3aa218b7bd6ab25729ca20cc81cddb252102f8751e13482a5199e873680952 + languageName: node + linkType: hard + +"strip-ansi@npm:^7.0.1": + version: 7.1.0 + resolution: "strip-ansi@npm:7.1.0" + dependencies: + ansi-regex: "npm:^6.0.1" + checksum: a198c3762e8832505328cbf9e8c8381de14a4fa50a4f9b2160138158ea88c0f5549fb50cb13c651c3088f47e63a108b34622ec18c0499b6c8c3a5ddf6b305ac4 + languageName: node + linkType: hard + +"supports-color@npm:^5.3.0": + version: 5.5.0 + resolution: "supports-color@npm:5.5.0" + dependencies: + has-flag: "npm:^3.0.0" + checksum: 6ae5ff319bfbb021f8a86da8ea1f8db52fac8bd4d499492e30ec17095b58af11f0c55f8577390a749b1c4dde691b6a0315dab78f5f54c9b3d83f8fb5905c1c05 + languageName: node + linkType: hard + +"supports-color@npm:^7.1.0": + version: 7.2.0 + resolution: "supports-color@npm:7.2.0" + dependencies: + has-flag: "npm:^4.0.0" + checksum: afb4c88521b8b136b5f5f95160c98dee7243dc79d5432db7efc27efb219385bbc7d9427398e43dd6cc730a0f87d5085ce1652af7efbe391327bc0a7d0f7fc124 + languageName: node + linkType: hard + +"svgo@npm:^2.4.0": + version: 2.8.0 + resolution: "svgo@npm:2.8.0" + dependencies: + "@trysound/sax": "npm:0.2.0" + commander: "npm:^7.2.0" + css-select: "npm:^4.1.3" + css-tree: "npm:^1.1.3" + csso: "npm:^4.2.0" + picocolors: "npm:^1.0.0" + stable: "npm:^0.1.8" + bin: + svgo: bin/svgo + checksum: 0741f5d5cad63111a90a0ce7a1a5a9013f6d293e871b75efe39addb57f29a263e45294e485a4d2ff9cc260a5d142c8b5937b2234b4ef05efdd2706fb2d360ecc + languageName: node + linkType: hard + +"tar@npm:^6.1.11, tar@npm:^6.1.2": + version: 6.2.0 + resolution: "tar@npm:6.2.0" + dependencies: + chownr: "npm:^2.0.0" + fs-minipass: "npm:^2.0.0" + minipass: "npm:^5.0.0" + minizlib: "npm:^2.1.1" + mkdirp: "npm:^1.0.3" + yallist: "npm:^4.0.0" + checksum: 02ca064a1a6b4521fef88c07d389ac0936730091f8c02d30ea60d472e0378768e870769ab9e986d87807bfee5654359cf29ff4372746cc65e30cbddc352660d8 + languageName: node + linkType: hard + +"term-size@npm:^2.2.1": + version: 2.2.1 + resolution: "term-size@npm:2.2.1" + checksum: 89f6bba1d05d425156c0910982f9344d9e4aebf12d64bfa1f460d93c24baa7bc4c4a21d355fbd7153c316433df0538f64d0ae6e336cc4a69fdda4f85d62bc79d + languageName: node + linkType: hard + +"timsort@npm:^0.3.0": + version: 0.3.0 + resolution: "timsort@npm:0.3.0" + checksum: 571b2054a0db3cf80eb255f8609a1f798cae9176f9ec6e3fbd03d64186c015cc9e1e75b88ba38e1d71aebcc03a931352522c7387dcb90caeb148375c7bc106f4 + languageName: node + linkType: hard + +"to-regex-range@npm:^5.0.1": + version: 5.0.1 + resolution: "to-regex-range@npm:5.0.1" + dependencies: + is-number: "npm:^7.0.0" + checksum: 487988b0a19c654ff3e1961b87f471702e708fa8a8dd02a298ef16da7206692e8552a0250e8b3e8759270f62e9d8314616f6da274734d3b558b1fc7b7724e892 + languageName: node + linkType: hard + +"tslib@npm:^2.4.0": + version: 2.6.2 + resolution: "tslib@npm:2.6.2" + checksum: e03a8a4271152c8b26604ed45535954c0a45296e32445b4b87f8a5abdb2421f40b59b4ca437c4346af0f28179780d604094eb64546bee2019d903d01c6c19bdb + languageName: node + linkType: hard + +"type-fest@npm:^0.20.2": + version: 0.20.2 + resolution: "type-fest@npm:0.20.2" + checksum: dea9df45ea1f0aaa4e2d3bed3f9a0bfe9e5b2592bddb92eb1bf06e50bcf98dbb78189668cd8bc31a0511d3fc25539b4cd5c704497e53e93e2d40ca764b10bfc3 + languageName: node + linkType: hard + +"typescript@npm:^5.3.3": + version: 5.3.3 + resolution: "typescript@npm:5.3.3" + bin: + tsc: bin/tsc + tsserver: bin/tsserver + checksum: e33cef99d82573624fc0f854a2980322714986bc35b9cb4d1ce736ed182aeab78e2cb32b385efa493b2a976ef52c53e20d6c6918312353a91850e2b76f1ea44f + languageName: node + linkType: hard + +"typescript@patch:typescript@npm%3A^5.3.3#optional!builtin": + version: 5.3.3 + resolution: "typescript@patch:typescript@npm%3A5.3.3#optional!builtin::version=5.3.3&hash=e012d7" + bin: + tsc: bin/tsc + tsserver: bin/tsserver + checksum: 1d0a5f4ce496c42caa9a30e659c467c5686eae15d54b027ee7866744952547f1be1262f2d40de911618c242b510029d51d43ff605dba8fb740ec85ca2d3f9500 + languageName: node + linkType: hard + +"unique-filename@npm:^3.0.0": + version: 3.0.0 + resolution: "unique-filename@npm:3.0.0" + dependencies: + unique-slug: "npm:^4.0.0" + checksum: 6363e40b2fa758eb5ec5e21b3c7fb83e5da8dcfbd866cc0c199d5534c42f03b9ea9ab069769cc388e1d7ab93b4eeef28ef506ab5f18d910ef29617715101884f + languageName: node + linkType: hard + +"unique-slug@npm:^4.0.0": + version: 4.0.0 + resolution: "unique-slug@npm:4.0.0" + dependencies: + imurmurhash: "npm:^0.1.4" + checksum: cb811d9d54eb5821b81b18205750be84cb015c20a4a44280794e915f5a0a70223ce39066781a354e872df3572e8155c228f43ff0cce94c7cbf4da2cc7cbdd635 + languageName: node + linkType: hard + +"update-browserslist-db@npm:^1.0.13": + version: 1.0.13 + resolution: "update-browserslist-db@npm:1.0.13" + dependencies: + escalade: "npm:^3.1.1" + picocolors: "npm:^1.0.0" + peerDependencies: + browserslist: ">= 4.21.0" + bin: + update-browserslist-db: cli.js + checksum: e52b8b521c78ce1e0c775f356cd16a9c22c70d25f3e01180839c407a5dc787fb05a13f67560cbaf316770d26fa99f78f1acd711b1b54a4f35d4820d4ea7136e6 + languageName: node + linkType: hard + +"url@npm:^0.11.0": + version: 0.11.3 + resolution: "url@npm:0.11.3" + dependencies: + punycode: "npm:^1.4.1" + qs: "npm:^6.11.2" + checksum: 7546b878ee7927cfc62ca21dbe2dc395cf70e889c3488b2815bf2c63355cb3c7db555128176a01b0af6cccf265667b6fd0b4806de00cb71c143c53986c08c602 + languageName: node + linkType: hard + +"utility-types@npm:^3.10.0": + version: 3.11.0 + resolution: "utility-types@npm:3.11.0" + checksum: 2f1580137b0c3e6cf5405f37aaa8f5249961a76d26f1ca8efc0ff49a2fc0e0b2db56de8e521a174d075758e0c7eb3e590edec0832eb44478b958f09914920f19 + languageName: node + linkType: hard + +"vis-client@workspace:.": + version: 0.0.0-use.local + resolution: "vis-client@workspace:." + dependencies: + "@parcel/packager-raw-url": "npm:2.11.0" + "@parcel/transformer-inline-string": "npm:2.11.0" + "@parcel/transformer-webmanifest": "npm:2.11.0" + "@pixi/core": "npm:^7.3.3" + "@pixi/display": "npm:^7.3.3" + "@types/d3": "npm:^7.4.3" + d3: "npm:^7.8.5" + parcel: "npm:^2.11.0" + pixi-viewport: "npm:^5.0.2" + pixi.js: "npm:^7.3.3" + prettier: "npm:^3.2.4" + punycode: "npm:^1.4.1" + typescript: "npm:^5.3.3" + url: "npm:^0.11.0" + languageName: unknown + linkType: soft + +"weak-lru-cache@npm:^1.2.2": + version: 1.2.2 + resolution: "weak-lru-cache@npm:1.2.2" + checksum: 744847bd5b96ca86db1cb40d0aea7e92c02bbdb05f501181bf9c581e82fa2afbda32a327ffbe75749302b8492ab449f1c657ca02410d725f5d412d1e6c607d72 + languageName: node + linkType: hard + +"which@npm:^2.0.1": + version: 2.0.2 + resolution: "which@npm:2.0.2" + dependencies: + isexe: "npm:^2.0.0" + bin: + node-which: ./bin/node-which + checksum: 66522872a768b60c2a65a57e8ad184e5372f5b6a9ca6d5f033d4b0dc98aff63995655a7503b9c0a2598936f532120e81dd8cc155e2e92ed662a2b9377cc4374f + languageName: node + linkType: hard + +"which@npm:^4.0.0": + version: 4.0.0 + resolution: "which@npm:4.0.0" + dependencies: + isexe: "npm:^3.1.1" + bin: + node-which: bin/which.js + checksum: 449fa5c44ed120ccecfe18c433296a4978a7583bf2391c50abce13f76878d2476defde04d0f79db8165bdf432853c1f8389d0485ca6e8ebce3bbcded513d5e6a + languageName: node + linkType: hard + +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": + version: 7.0.0 + resolution: "wrap-ansi@npm:7.0.0" + dependencies: + ansi-styles: "npm:^4.0.0" + string-width: "npm:^4.1.0" + strip-ansi: "npm:^6.0.0" + checksum: d15fc12c11e4cbc4044a552129ebc75ee3f57aa9c1958373a4db0292d72282f54373b536103987a4a7594db1ef6a4f10acf92978f79b98c49306a4b58c77d4da + languageName: node + linkType: hard + +"wrap-ansi@npm:^8.1.0": + version: 8.1.0 + resolution: "wrap-ansi@npm:8.1.0" + dependencies: + ansi-styles: "npm:^6.1.0" + string-width: "npm:^5.0.1" + strip-ansi: "npm:^7.0.1" + checksum: 138ff58a41d2f877eae87e3282c0630fc2789012fc1af4d6bd626eeb9a2f9a65ca92005e6e69a75c7b85a68479fe7443c7dbe1eb8fbaa681a4491364b7c55c60 + languageName: node + linkType: hard + +"yallist@npm:^4.0.0": + version: 4.0.0 + resolution: "yallist@npm:4.0.0" + checksum: 2286b5e8dbfe22204ab66e2ef5cc9bbb1e55dfc873bbe0d568aa943eb255d131890dfd5bf243637273d31119b870f49c18fcde2c6ffbb7a7a092b870dc90625a + languageName: node + linkType: hard