diff --git a/.github/workflows/universe-ci.yml b/.github/workflows/universe-ci.yml index df58a557887..f45b8a093c3 100644 --- a/.github/workflows/universe-ci.yml +++ b/.github/workflows/universe-ci.yml @@ -31,6 +31,18 @@ jobs: - name: Protocol coverage table matches the recorded manifest run: node scripts/universe/generate-protocol-coverage.mjs --check + - name: No em dash anywhere + run: node scripts/universe/check-text.mjs + + - name: No obsolete upstream product marks + run: node scripts/universe/check-branding.mjs + + - name: No third-party data origins + run: node scripts/universe/check-origins.mjs + + - name: Gateway routing + run: node --test scripts/universe/gateway.test.mjs + backend: name: Backend build and test runs-on: [self-hosted, linux-ultra] @@ -91,4 +103,10 @@ jobs: - name: Production build working-directory: frontend - run: npm run build + run: npm run build:universe + + - name: Built bundle carries no upstream marks + run: node scripts/universe/check-branding.mjs frontend/dist + + - name: Built bundle calls no third-party origin + run: node scripts/universe/check-origins.mjs frontend/dist diff --git a/.gitignore b/.gitignore index faeb8b85b59..f154cf0ef3a 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,10 @@ target docker/backend/start_ci.sh # Universe: docs/data holds evidence-model documentation, not runtime data !docs/data/ + +# Dependencies are never committed, at any depth. +node_modules/ + +# Visual QA working output. Curated review sets are committed under docs/design. +scripts/universe/visual-qa/artifacts/ +scripts/universe/visual-qa/node_modules/ diff --git a/README.md b/README.md index 7e426f1550a..f50150b732f 100644 --- a/README.md +++ b/README.md @@ -1,38 +1,162 @@ -# The Mempool Open Source Project® [![mempool](https://img.shields.io/endpoint?url=https://dashboard.cypress.io/badge/simple/ry4br7/master&style=flat-square)](https://dashboard.cypress.io/projects/ry4br7/runs) +# Universe Explorer -https://user-images.githubusercontent.com/93150691/226236121-375ea64f-b4a1-4cc0-8fad-a6fb33226840.mp4 +The Bitcoin Universe mempool and block explorer. It shows what is happening on +Bitcoin right now, and what transactions actually do across Bitcoin Universe +protocols, with the evidence behind every claim. -
+Live at [explorer.bitcoinuniverse.io](https://explorer.bitcoinuniverse.io). -Mempool is the fully-featured mempool visualizer, explorer, and API service running at [mempool.space](https://mempool.space/). +## What makes it different -It is an open-source project developed and operated for the benefit of the Bitcoin community, with a focus on the emerging transaction fee market that is evolving Bitcoin into a multi-layer ecosystem. +Most explorers answer one of two questions. A mempool explorer tells you what +is pending and what it will cost to confirm. A protocol explorer tells you what +assets exist. Universe Explorer answers both in one place, and it never guesses. -# Installation Methods +- **Exact asset flows.** A transaction page names the inputs and outputs that + carry protocol assets, the action the authority reported, and the block that + proves it. Nothing is inferred from transaction shape. +- **Outputs are first class.** `/outpoint/:txid/:vout` is a real page. An output + is the unit that carries assets on Bitcoin, so it gets its own address. +- **States that mean something.** Proven, partly proven, outside coverage, + pending, and unavailable are five different answers. A missing indexer never + becomes a false zero. +- **Live protocol activity, measured.** The pulse page publishes its own + denominator: how many arriving transactions were checked, and how many carried + each protocol. Every number on it can be reproduced. +- **No trackers, no accounts.** Search is matched in your browser. Saved pages + and history live in local storage and never leave the device. +- **First-party data only.** Every figure comes from Bitcoin Universe's own + node, Electrum index, and protocol authorities. -Mempool can be self-hosted on a wide variety of your own hardware, ranging from a simple one-click installation on a Raspberry Pi full-node distro all the way to a robust production instance on a powerful FreeBSD server. +## Protocol coverage -Most people should use a one-click install method. +The registry carries every protocol in the Bitcoin Universe ecosystem, and the +explorer states plainly which ones it can actually read. -Other install methods are meant for developers and others with experience managing servers. If you want support for your own production instance of Mempool, or if you'd like to have your own instance of Mempool run by the mempool.space team on their own global ISP infrastructure—check out Mempool Enterprise®. +| State | Meaning | +| --- | --- | +| Live, read only | A first-party authority is running and its evidence is shown. | +| Not yet available | No first-party authority for it is configured or answering here. The explorer makes no claim about it. | +| Different chain | The protocol lives on a chain this explorer does not serve. | - -## One-Click Installation +Live today, backed by the first-party Ord 0.29 authority: **Ordinals**, +**Rare Sats**, **Runes**. -Mempool can be conveniently installed on the following full-node distros: -- [Umbrel](https://github.com/getumbrel/umbrel) -- [RaspiBlitz](https://github.com/rootzoll/raspiblitz) -- [RoninDojo](https://code.samourai.io/ronindojo/RoninDojo) -- [myNode](https://github.com/mynodebtc/mynode) -- [StartOS](https://github.com/Start9Labs/start-os) -- [nix-bitcoin](https://github.com/fort-nix/nix-bitcoin/blob/a1eacce6768ca4894f365af8f79be5bbd594e1c3/examples/configuration.nix#L129) +`docs/protocols/PROTOCOL-COVERAGE.md` is generated from the registry and lists +every entry with its authority. Run `node scripts/universe/generate-protocol-coverage.mjs --check` +to verify the table still matches. -**We highly recommend you deploy your own Mempool instance this way.** No matter which option you pick, you'll be able to get your own fully-sovereign instance of Mempool up quickly without needing to fiddle with any settings. +## Architecture -## Advanced Installation Methods +Three processes behind one HTTPS origin: -Mempool can be installed in other ways too, but we only recommend doing so if you're a developer, have experience managing servers, or otherwise know what you're doing. +| Component | What it is | +| --- | --- | +| Explorer backend | `backend/` in this repository. Reads Bitcoin Core, Fulcrum, and MariaDB. | +| Protocol overlay | `backend-apis` standalone service. Serves `/api/v1/universe/*` and holds every indexer credential server side. | +| Frontend | `frontend/`, an Angular application served as static files with SPA fallback. | -- See the [`docker/`](./docker/) directory for instructions on deploying Mempool with Docker. -- See the [`backend/`](./backend/) and [`frontend/`](./frontend/) directories for manual install instructions oriented for developers. -- See the [`production/`](./production/) directory for guidance on setting up a more serious Mempool instance designed for high performance at scale. +The browser never talks to an indexer, and no indexer origin or credential is +ever exposed to it. See `docs/architecture/` for the overlay design and +`docs/data/ASSET-EVIDENCE.md` for the evidence contract. + +## First-party data policy + +No third-party blockchain API, public explorer, hosted indexer, analytics +service, or remote font is called at any point, from the server or the browser. +Collection-level artwork and metadata are the only permitted external sources, +and they are fetched server side and cached. + +`node scripts/universe/check-origins.mjs` fails the build if a forbidden origin +appears in the source or in a production bundle. The production build also skips +asset synchronization, so nothing is downloaded from a third party at build time +either; mining pool logos fall back to the bundled default. + +## Local development + +Requires Node 24.19.0 and npm 11.17.0, both pinned in `.nvmrc` and +`package.json`. + +```bash +cd backend && npm ci && npm run build && npm run start +``` + +```bash +cd frontend && npm ci && npm run serve +``` + +The frontend proxies `/api` to the backend. To point it at a running deployment +instead, set `MEMPOOL_BACKEND` in `frontend/proxy.conf.json`. + +## Testing + +```bash +cd frontend && npm run build:universe # production build, no third-party fetches +cd frontend && npm run test # Universe unit suite +cd frontend && npm run lint +cd backend && npm run test:ci && npm run lint +node scripts/universe/generate-protocol-coverage.mjs --check +node scripts/universe/check-text.mjs # no em dash anywhere +node scripts/universe/check-branding.mjs # no obsolete upstream marks +node scripts/universe/check-origins.mjs # no third-party data origins +``` + +The same checks run in `.github/workflows/universe-ci.yml` on the self-hosted +runner fleet. The branding and origin gates also accept a built bundle path, and +the release workflow runs them against `frontend/dist` before anything ships. + +## Configuration + +The backend reads `backend/mempool-config.json`. The overlay reads +`UNIVERSE_EXPLORER_SOURCES_JSON`, a JSON array of authority descriptors whose +bearer tokens are named, never embedded: + +```json +[{ "authorityId": "ord", + "origin": "http://127.0.0.1:8382", + "bearerTokenEnv": "UNIVERSE_ORD_TOKEN", + "protocols": ["ordinals", "rare_sats", "runes"], + "network": "bitcoin:mainnet" }] +``` + +Parsing is strict and all or nothing: one invalid descriptor disables the whole +registry rather than serving partially trusted data. + +## Deployment + +`docs/operations/DEPLOYMENT.md` documents the release procedure. Releases are +deployed beside the running one and the gateway upstream is flipped, so a +rollback is a single flip back. Every deployment publishes its own commit on +`/api/v1/backend-info` and on the public `/source` page. + +## Source and licence + +Universe Explorer is free software under the +[GNU Affero General Public License, version 3](LICENSE) or later. Section 13 +requires that anyone interacting with it over a network can get the +corresponding source, which is what `/source` provides. + +This repository is a fork of the upstream Mempool Open Source Project. Upstream +copyright notices and the full licence text in [COPYING.md](COPYING.md) are +preserved. Upstream trademarks are not used: see +`docs/legal/TRADEMARK-AUDIT.md` and `docs/legal/AGPL-COMPLIANCE.md`. + +## Upstream relationship + +[UPSTREAM.md](UPSTREAM.md) records the exact upstream base, every subsystem this +fork modifies, and the known conflict points. `docs/operations/UPSTREAM-SYNC.md` +is the synchronization procedure. Universe changes are deliberately isolated so +upstream security fixes stay easy to take. + +## Security + +Report a suspected vulnerability privately to the Bitcoin Universe security +contact rather than opening a public issue. `docs/security/THREAT-MODEL.md` +records the trust boundaries this deployment assumes. + +## Contributing + +Work happens on `develop`. Open a pull request against it, keep Universe changes +inside `frontend/src/app/universe/` and the documented integration points where +possible, and make sure the checks above pass. [CONTRIBUTING.md](CONTRIBUTING.md) +covers the details inherited from upstream. diff --git a/UPSTREAM.md b/UPSTREAM.md index 753d413d498..791973136b5 100644 --- a/UPSTREAM.md +++ b/UPSTREAM.md @@ -45,6 +45,16 @@ synchronization procedure. | `.github/workflows/universe-ci.yml`, `upstream-sync.yml` | Added. Upstream workflows are unchanged. | | `scripts/universe/` | Added. Protocol coverage documentation generator and its CI check. | | `.nvmrc` | Pinned to the Universe toolchain version (24.19.0). | +| `backend/src/index.ts`, `backend/src/config.ts` | `MEMPOOL.HTTP_HOST` added, defaulting to loopback. Upstream binds every interface. | +| `backend/src/api/backend-info.ts` | Publishes the node's own sync state so the explorer can say when its data is behind the chain. | +| `frontend/src/app/services/enterprise.service.ts` | Hosted analytics reduced to a no-op; the upstream redirect on an unknown subdomain removed; no hostname treated as an enterprise subdomain. | +| `frontend/src/app/services/state.service.ts`, `seo.service.ts` | Cross-network links, the services API, and the canonical domain point at this deployment or are unset. | +| `frontend/sync-assets.js`, `frontend/package.json` | `build:universe` omits localization and asset synchronization; the hosted CDN rewrite is removed. | +| Deleted upstream surfaces | `components/about/`, `components/trademark-policy/`, `components/accelerate-checkout/`, `lightning/group/`, the sponsor index variants, and the upstream node fleet scripts. | +| Rewritten upstream surfaces | `components/privacy-policy/`, `components/terms-of-service/`, `docs/api-docs/`. | +| Renamed identifiers | `activeGoggles$`, `goggleCycle`, `goggleIndex` are now `activeLens$`, `lensCycle`, `lensIndex`, so the trademark does not survive minification. | +| Accessibility | Accessible names added to the icon-only navigation, the search submit button, and the blockchain toggles. | +| `scripts/universe/` | Gateway, protocol coverage generator, and the branding, origin, and text gates. | ## Known upstream conflicts @@ -53,6 +63,8 @@ synchronization procedure. | `frontend/src/app/master-page.module.ts` | Upstream edits its route table regularly. The two Universe routes sit at the end of the child route array to keep the conflict small and mechanical. | | Branding templates | Any upstream change to a rebranded template conflicts by construction. `docs/legal/TRADEMARK-AUDIT.md` lists every touched file so a merge can be resolved deliberately. | | `frontend/package.json` | The `test` script diverges from upstream. Upstream's value is inert, so upstream's version can be discarded on conflict. | +| Punctuation | Every em dash was removed repository wide, including from inherited READMEs, and `scripts/universe/check-text.mjs` keeps them out. Expect one-character conflicts in those files on sync. | +| Branding edits across upstream components | The trademark work touches many upstream templates. `docs/legal/TRADEMARK-AUDIT.md` lists every one, and the branding gate fails the build if a sync reintroduces a mark. | The two upstream spec files under `frontend/src/app/lightning/` import from a path that does not exist in this tree and reference a missing `src/test.ts`. diff --git a/backend/eslint-local-rules/index.js b/backend/eslint-local-rules/index.js index 0a4605dd269..8d494fe5be0 100644 --- a/backend/eslint-local-rules/index.js +++ b/backend/eslint-local-rules/index.js @@ -292,7 +292,7 @@ module.exports = { if (!sym || !Array.isArray(sym.declarations)) return false; for (const decl of sym.declarations) { - // method, function, property with function type — accept any with @asyncSafe + // method, function, property with function type, accept any with @asyncSafe if (tsNodeHasJsDocTag(decl, opt.safeTag)) return true; // for class methods, also check the parent (sometimes the tag is on the signature) if (decl.parent && tsNodeHasJsDocTag(decl.parent, opt.safeTag)) return true; @@ -379,7 +379,7 @@ module.exports = { context.report({ node, messageId: 'unhandled' }); }, - // void someAsyncCall() — only allowed if callee is @asyncSafe + // void someAsyncCall(), only allowed if callee is @asyncSafe UnaryExpression(node) { if (node.operator !== 'void') return; diff --git a/backend/mempool-config.sample.json b/backend/mempool-config.sample.json index c2715153bba..39349201309 100644 --- a/backend/mempool-config.sample.json +++ b/backend/mempool-config.sample.json @@ -5,6 +5,7 @@ "BACKEND": "electrum", "ENABLED": true, "HTTP_PORT": 8999, + "HTTP_HOST": "127.0.0.1", "SPAWN_CLUSTER_PROCS": 0, "API_URL_PREFIX": "/api/v1/", "POLL_RATE_MS": 2000, @@ -128,7 +129,7 @@ "PASSWORD": "" }, "EXTERNAL_DATA_SERVER": { - "MEMPOOL_API": "https://mempool.space/api/v1", + "MEMPOOL_API": "", "MEMPOOL_ONION": "http://mempoolhqx4isw62xs7abwphsq7ldayuidyx2v2oethdhhj6mlo2r6ad.onion/api/v1", "LIQUID_API": "https://liquid.network/api/v1", "LIQUID_ONION": "http://liquidmom47f6s3m53ebfxn47p76a6tlnxib3wp6deux7wuzotdr6cyd.onion/api/v1" @@ -152,7 +153,7 @@ ] }, "MEMPOOL_SERVICES": { - "API": "https://mempool.space/api/v1/services", + "API": "/services", "ACCELERATIONS": false }, "STRATUM": { diff --git a/backend/mempool-config.test.json b/backend/mempool-config.test.json index 2522ca90f3d..4b69da9b0f6 100644 --- a/backend/mempool-config.test.json +++ b/backend/mempool-config.test.json @@ -5,6 +5,7 @@ "BACKEND": "none", "ENABLED": true, "HTTP_PORT": 8998, + "HTTP_HOST": "127.0.0.1", "SPAWN_CLUSTER_PROCS": 0, "API_URL_PREFIX": "/api/v1/", "POLL_RATE_MS": 2000, @@ -128,7 +129,7 @@ "PASSWORD": "" }, "EXTERNAL_DATA_SERVER": { - "MEMPOOL_API": "https://mempool.space/api/v1", + "MEMPOOL_API": "", "MEMPOOL_ONION": "http://mempoolhqx4isw62xs7abwphsq7ldayuidyx2v2oethdhhj6mlo2r6ad.onion/api/v1", "LIQUID_API": "https://liquid.network/api/v1", "LIQUID_ONION": "http://liquidmom47f6s3m53ebfxn47p76a6tlnxib3wp6deux7wuzotdr6cyd.onion/api/v1" @@ -147,7 +148,7 @@ "SERVERS": [] }, "MEMPOOL_SERVICES": { - "API": "https://mempool.space/api/v1/services", + "API": "/services", "ACCELERATIONS": false }, "STRATUM": { @@ -160,4 +161,3 @@ "API_KEY": "" } } - diff --git a/backend/package-lock.json b/backend/package-lock.json index 007e6020e14..7d7a35e1d84 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -12,7 +12,7 @@ "dependencies": { "@mempool/electrum-client": "1.1.9", "@types/node": "^18.15.3", - "axios": "1.13.5", + "axios": "^1.20.0", "bitcoinjs-lib": "~6.1.3", "crypto-js": "~4.2.0", "express": "~4.22.1", @@ -22,7 +22,7 @@ "rust-gbt": "file:./rust-gbt", "socks-proxy-agent": "~7.0.0", "typescript": "~4.9.3", - "ws": "~8.19.0" + "ws": "^8.21.3" }, "devDependencies": { "@types/compression": "^1.7.2", @@ -41,13 +41,6 @@ "ts-node": "^10.9.1" } }, - "../rust/gbt": { - "version": "3.0.1", - "extraneous": true, - "engines": { - "node": ">= 12" - } - }, "node_modules/@aashutoshrathi/word-wrap": { "version": "1.2.6", "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", @@ -58,13 +51,13 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", - "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", + "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.27.1", + "@babel/helper-validator-identifier": "^7.29.7", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" }, @@ -73,9 +66,9 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.5.tgz", - "integrity": "sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.7.tgz", + "integrity": "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==", "dev": true, "license": "MIT", "engines": { @@ -83,21 +76,21 @@ } }, "node_modules/@babel/core": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.5.tgz", - "integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz", + "integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.28.5", - "@babel/helper-compilation-targets": "^7.27.2", - "@babel/helper-module-transforms": "^7.28.3", - "@babel/helpers": "^7.28.4", - "@babel/parser": "^7.28.5", - "@babel/template": "^7.27.2", - "@babel/traverse": "^7.28.5", - "@babel/types": "^7.28.5", + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.7", + "@babel/helper-compilation-targets": "^7.29.7", + "@babel/helper-module-transforms": "^7.29.7", + "@babel/helpers": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/template": "^7.29.7", + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7", "@jridgewell/remapping": "^2.3.5", "convert-source-map": "^2.0.0", "debug": "^4.1.0", @@ -114,14 +107,14 @@ } }, "node_modules/@babel/generator": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.5.tgz", - "integrity": "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==", + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.8.tgz", + "integrity": "sha512-gZbepsdh3WDtgZKWL+vTPh71LSBrm/Y4/QDZBVCcYfmeTEEuoOYwlSy+G1StfJg+/Zy550u/3TATbm7qDbbMtg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/parser": "^7.28.5", - "@babel/types": "^7.28.5", + "@babel/parser": "^7.29.8", + "@babel/types": "^7.29.8", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" @@ -131,14 +124,14 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", - "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz", + "integrity": "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==", "dev": true, "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.27.2", - "@babel/helper-validator-option": "^7.27.1", + "@babel/compat-data": "^7.29.7", + "@babel/helper-validator-option": "^7.29.7", "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" @@ -148,9 +141,9 @@ } }, "node_modules/@babel/helper-globals": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", - "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz", + "integrity": "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==", "dev": true, "license": "MIT", "engines": { @@ -158,29 +151,29 @@ } }, "node_modules/@babel/helper-module-imports": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", - "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz", + "integrity": "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==", "dev": true, "license": "MIT", "dependencies": { - "@babel/traverse": "^7.27.1", - "@babel/types": "^7.27.1" + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz", - "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz", + "integrity": "sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-module-imports": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1", - "@babel/traverse": "^7.28.3" + "@babel/helper-module-imports": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7", + "@babel/traverse": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -200,9 +193,9 @@ } }, "node_modules/@babel/helper-string-parser": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", - "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz", + "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==", "dev": true, "license": "MIT", "engines": { @@ -210,9 +203,9 @@ } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", - "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", + "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", "dev": true, "license": "MIT", "engines": { @@ -220,9 +213,9 @@ } }, "node_modules/@babel/helper-validator-option": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", - "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz", + "integrity": "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==", "dev": true, "license": "MIT", "engines": { @@ -230,27 +223,27 @@ } }, "node_modules/@babel/helpers": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz", - "integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.7.tgz", + "integrity": "sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/template": "^7.27.2", - "@babel/types": "^7.28.4" + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/parser": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz", - "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==", + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.8.tgz", + "integrity": "sha512-E8lTAYNB1KW+FH+VGJuZM1ioAx2E6oVlvQFRrf5P8ZZmsiJXYAD9vTFV7yyEURNzgh1dFqMZuO6tUwcARbqFCA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.28.5" + "@babel/types": "^7.29.8" }, "bin": { "parser": "bin/babel-parser.js" @@ -499,33 +492,33 @@ } }, "node_modules/@babel/template": { - "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", - "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz", + "integrity": "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/parser": "^7.27.2", - "@babel/types": "^7.27.1" + "@babel/code-frame": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.5.tgz", - "integrity": "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==", + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.8.tgz", + "integrity": "sha512-I5z7H3bf/41ktsNVLtpN0wAa336HkqIHQ5BuPLEhTkt1jVSyZpeNKIzTgEWmlxjdg81R0IgUCcaE+Ok3NvrfZg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.28.5", - "@babel/helper-globals": "^7.28.0", - "@babel/parser": "^7.28.5", - "@babel/template": "^7.27.2", - "@babel/types": "^7.28.5", + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.8", + "@babel/helper-globals": "^7.29.7", + "@babel/parser": "^7.29.8", + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.8", "debug": "^4.3.1" }, "engines": { @@ -533,14 +526,14 @@ } }, "node_modules/@babel/types": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz", - "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==", + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.8.tgz", + "integrity": "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.28.5" + "@babel/helper-string-parser": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -2489,13 +2482,15 @@ } }, "node_modules/axios": { - "version": "1.13.5", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.5.tgz", - "integrity": "sha512-cz4ur7Vb0xS4/KUN0tPWe44eqxrIu31me+fbang3ijiNscE129POzipJJA6zniq2C/Z6sJCjMimjS8Lc/GAs8Q==", + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.20.0.tgz", + "integrity": "sha512-r8aOh8j9cGKpgQAqpzrUHnSIc6a59Y3Xf/cv8sy1DrHCkZHzQGEuoq1tARk6qSyDdtQGSDgpb9kFlruzPvrgwg==", + "license": "MIT", "dependencies": { - "follow-redirects": "^1.15.11", - "form-data": "^4.0.5", - "proxy-from-env": "^1.1.0" + "follow-redirects": "^1.16.0", + "form-data": "^4.0.6", + "https-proxy-agent": "^5.0.1", + "proxy-from-env": "^2.1.0" } }, "node_modules/babel-jest": { @@ -2609,13 +2604,16 @@ "integrity": "sha512-uAZ8x6r6S3aUM9rbHGVOIsR15U/ZSc82b3ymnCPsT45Gk1DDvhDPdIgB5MrhirZWt+5K0EEPQH985kNqZgNPFw==" }, "node_modules/baseline-browser-mapping": { - "version": "2.8.28", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.28.tgz", - "integrity": "sha512-gYjt7OIqdM0PcttNYP2aVrr2G0bMALkBaoehD4BuRGjAOtipg0b6wHg1yNL+s5zSnLZZrGHOw4IrND8CD+3oIQ==", + "version": "2.11.19", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.19.tgz", + "integrity": "sha512-Grytf1xOxOEMTGRwx6rLGKkTabd4vMg3VrKdj/7joCmV0qgh4QwMMO6xh34YEXQqirAuUdgQGa5orJQQ+69RBw==", "dev": true, "license": "Apache-2.0", "bin": { - "baseline-browser-mapping": "dist/cli.js" + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" } }, "node_modules/bech32": { @@ -2648,9 +2646,9 @@ } }, "node_modules/body-parser": { - "version": "1.20.4", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.4.tgz", - "integrity": "sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA==", + "version": "1.20.6", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.6.tgz", + "integrity": "sha512-p5tAzS57i5MV9fZFDj9LeIiTZEufbSe2eDozP+ElheSUq1m74CRq1jI4mYNDdVs9vQztXFLuk/Gd6BWTdwRJ5g==", "license": "MIT", "dependencies": { "bytes": "~3.1.2", @@ -2661,7 +2659,7 @@ "http-errors": "~2.0.1", "iconv-lite": "~0.4.24", "on-finished": "~2.4.1", - "qs": "~6.14.0", + "qs": "~6.15.1", "raw-body": "~2.5.3", "type-is": "~1.6.18", "unpipe": "~1.0.0" @@ -2675,6 +2673,7 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", "dependencies": { "ms": "2.0.0" } @@ -2702,7 +2701,8 @@ "node_modules/body-parser/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" }, "node_modules/body-parser/node_modules/statuses": { "version": "2.0.2", @@ -2714,9 +2714,9 @@ } }, "node_modules/brace-expansion": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", - "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", + "version": "1.1.18", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz", + "integrity": "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==", "dev": true, "license": "MIT", "dependencies": { @@ -2738,9 +2738,9 @@ } }, "node_modules/browserslist": { - "version": "4.28.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.0.tgz", - "integrity": "sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ==", + "version": "4.28.8", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.8.tgz", + "integrity": "sha512-V2NpofLblG64mfOtSgDhOJESZEGogzDMBv/q+W6oc4LXWP/q75eOXoOaaOu1EOadB9U4Bwx/e0yzbvwKH8zalA==", "dev": true, "funding": [ { @@ -2758,11 +2758,11 @@ ], "license": "MIT", "dependencies": { - "baseline-browser-mapping": "^2.8.25", - "caniuse-lite": "^1.0.30001754", - "electron-to-chromium": "^1.5.249", - "node-releases": "^2.0.27", - "update-browserslist-db": "^1.1.4" + "baseline-browser-mapping": "^2.11.12", + "caniuse-lite": "^1.0.30001809", + "electron-to-chromium": "^1.5.402", + "node-releases": "^2.0.53", + "update-browserslist-db": "^1.3.0" }, "bin": { "browserslist": "cli.js" @@ -2842,6 +2842,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.2", "get-intrinsic": "^1.3.0" @@ -2873,9 +2874,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001754", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001754.tgz", - "integrity": "sha512-x6OeBXueoAceOmotzx3PO4Zpt4rzpeIFsSr6AAePTZxSkXiYDUmpypEl7e2+8NCd9bD7bXjqyef8CJYPC1jfxg==", + "version": "1.0.30001810", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001810.tgz", + "integrity": "sha512-TITQPUkaz+aVk5GL6NhOdwk1aEaNTSDPsGFWrTuhKGtjTF70jL/Oht2W4c6rXUe5fu7Ie19VIahAXHIIiWWNeg==", "dev": true, "funding": [ { @@ -3036,6 +3037,7 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -3236,9 +3238,9 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "node_modules/electron-to-chromium": { - "version": "1.5.253", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.253.tgz", - "integrity": "sha512-O0tpQ/35rrgdiGQ0/OFWhy1itmd9A6TY9uQzlqj3hKSu/aYpe7UIn5d7CU2N9myH6biZiWF3VMZVuup8pw5U9w==", + "version": "1.5.415", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.415.tgz", + "integrity": "sha512-958V+Kbhtgz+SxXeEVKBjrlKRBIDAYvUJfwhjxMZ5S6ut9jAl7l9ZKBkBrvjyjZE36PabLUo2L8kEeV5O4vgJg==", "dev": true, "license": "ISC" }, @@ -3646,13 +3648,14 @@ } }, "node_modules/express": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.22.1.tgz", - "integrity": "sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==", + "version": "4.22.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.22.2.tgz", + "integrity": "sha512-IuL+Elrou2ZvCFHs18/CIzy2Nzvo25nZ1/D2eIZlz7c+QUayAcYoiM2BthCjs+EBHVpjYjcuLDAiCWgeIX3X1Q==", + "license": "MIT", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "~1.20.3", + "body-parser": "~1.20.5", "content-disposition": "~0.5.4", "content-type": "~1.0.4", "cookie": "~0.7.1", @@ -3671,7 +3674,7 @@ "parseurl": "~1.3.3", "path-to-regexp": "~0.1.12", "proxy-addr": "~2.0.7", - "qs": "~6.14.0", + "qs": "~6.15.1", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", "send": "~0.19.0", @@ -3860,15 +3863,16 @@ "license": "ISC" }, "node_modules/follow-redirects": { - "version": "1.15.11", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", - "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.0.tgz", + "integrity": "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==", "funding": [ { "type": "individual", "url": "https://github.com/sponsors/RubenVerborgh" } ], + "license": "MIT", "engines": { "node": ">=4.0" }, @@ -3909,15 +3913,16 @@ } }, "node_modules/form-data": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", - "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.6.tgz", + "integrity": "sha512-vKatAh4SlVfgbv+YtmhiRjhEMJsYpsG1Y2rMQtR+SVSbytsSD1YGzDIcrAJmdFec88u/+VoGmxnl+80gL1tRCQ==", + "license": "MIT", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", - "hasown": "^2.0.2", - "mime-types": "^2.1.12" + "hasown": "^2.0.4", + "mime-types": "^2.1.35" }, "engines": { "node": ">= 6" @@ -4102,16 +4107,16 @@ } }, "node_modules/glob/node_modules/brace-expansion": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", - "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", + "version": "5.0.9", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.9.tgz", + "integrity": "sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==", "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^4.0.2" }, "engines": { - "node": "18 || 20 || >=22" + "node": "20 || >=22" } }, "node_modules/glob/node_modules/minimatch": { @@ -4231,9 +4236,10 @@ } }, "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", + "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==", + "license": "MIT", "dependencies": { "function-bind": "^1.1.2" }, @@ -4263,6 +4269,19 @@ "node": ">= 0.8" } }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "license": "MIT", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/human-signals": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", @@ -4345,9 +4364,9 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "node_modules/ip-address": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.1.0.tgz", - "integrity": "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.5.0.tgz", + "integrity": "sha512-R5SnVLJmgYYvf2F2ZgwSBnelz5G4q5AxIC277GDfUaNbrZKNANcBC7RHqYYePlszf4kBolVkJauG0ZjHHFh55g==", "license": "MIT", "engines": { "node": ">= 12" @@ -5175,10 +5194,20 @@ "license": "MIT" }, "node_modules/js-yaml": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", - "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.2.tgz", + "integrity": "sha512-SFNOvSJ+Dgf/9An904Yx+CgSlIPCkIpao4qo51lpee25TIRejdH3rhR4EZMGoNx3/TP3O+wzWuiTFl4sqbltzA==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/puzrin" + }, + { + "type": "github", + "url": "https://github.com/sponsors/nodeca" + } + ], "license": "MIT", "dependencies": { "argparse": "^2.0.1" @@ -5387,6 +5416,7 @@ "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -5620,11 +5650,14 @@ "license": "MIT" }, "node_modules/node-releases": { - "version": "2.0.27", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", - "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", + "version": "2.0.53", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.53.tgz", + "integrity": "sha512-D9UOmYG3UH1V+ENW56t5QXBwJw1YEY18ruVeus89Rw+SyIgjPkCO84bRzO3uNIYosJbNwiabWVn48o3uJLjxFQ==", "dev": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": ">=18" + } }, "node_modules/normalize-path": { "version": "3.0.0", @@ -5653,6 +5686,7 @@ "version": "1.13.4", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -6014,9 +6048,13 @@ } }, "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz", + "integrity": "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==", + "license": "MIT", + "engines": { + "node": ">=10" + } }, "node_modules/punycode": { "version": "2.3.0", @@ -6045,11 +6083,13 @@ "license": "MIT" }, "node_modules/qs": { - "version": "6.14.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.2.tgz", - "integrity": "sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q==", + "version": "6.15.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.3.tgz", + "integrity": "sha512-O9gl3zCl5h5blw1KGUzQKhA5oUXSl8rwUIM5o0S3nCXMliSvy5Dzx7/DJcI+SwgICv+IneSZwhBh1oSyEHA71A==", + "license": "BSD-3-Clause", "dependencies": { - "side-channel": "^1.1.0" + "es-define-property": "^1.0.1", + "side-channel": "^1.1.1" }, "engines": { "node": ">=0.6" @@ -6273,6 +6313,7 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } @@ -6372,13 +6413,14 @@ } }, "node_modules/side-channel": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", - "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.1.tgz", + "integrity": "sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==", + "license": "MIT", "dependencies": { "es-errors": "^1.3.0", - "object-inspect": "^1.13.3", - "side-channel-list": "^1.0.0", + "object-inspect": "^1.13.4", + "side-channel-list": "^1.0.1", "side-channel-map": "^1.0.1", "side-channel-weakmap": "^1.0.2" }, @@ -6390,12 +6432,13 @@ } }, "node_modules/side-channel-list": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", - "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz", + "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==", + "license": "MIT", "dependencies": { "es-errors": "^1.3.0", - "object-inspect": "^1.13.3" + "object-inspect": "^1.13.4" }, "engines": { "node": ">= 0.4" @@ -6408,6 +6451,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "license": "MIT", "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", @@ -6425,6 +6469,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "license": "MIT", "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", @@ -6917,6 +6962,7 @@ "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "license": "MIT", "dependencies": { "media-typer": "0.3.0", "mime-types": "~2.1.24" @@ -7000,9 +7046,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.4.tgz", - "integrity": "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.3.1.tgz", + "integrity": "sha512-ZZ61DsRsOnakl74HAmp3oSN4aXUmEWXf+i/yv0h7tIBfICc3VdrFErQKUUKPgu3AMsTUMbcongALEN4l6GSUrQ==", "dev": true, "funding": [ { @@ -7181,9 +7227,10 @@ } }, "node_modules/ws": { - "version": "8.19.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz", - "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==", + "version": "8.21.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.3.tgz", + "integrity": "sha512-201TZ/kPWxoPr/OKWjquZR1SWKXcvxdH+e1xrx89b3YbmzLMFCLfnaG1HFIgWzJOEWZ7MvpK++odZufgYR50Rw==", + "license": "MIT", "engines": { "node": ">=10.0.0" }, @@ -7282,37 +7329,37 @@ "dev": true }, "@babel/code-frame": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", - "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", + "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.27.1", + "@babel/helper-validator-identifier": "^7.29.7", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "@babel/compat-data": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.5.tgz", - "integrity": "sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.7.tgz", + "integrity": "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==", "dev": true }, "@babel/core": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.5.tgz", - "integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.28.5", - "@babel/helper-compilation-targets": "^7.27.2", - "@babel/helper-module-transforms": "^7.28.3", - "@babel/helpers": "^7.28.4", - "@babel/parser": "^7.28.5", - "@babel/template": "^7.27.2", - "@babel/traverse": "^7.28.5", - "@babel/types": "^7.28.5", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz", + "integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.7", + "@babel/helper-compilation-targets": "^7.29.7", + "@babel/helper-module-transforms": "^7.29.7", + "@babel/helpers": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/template": "^7.29.7", + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7", "@jridgewell/remapping": "^2.3.5", "convert-source-map": "^2.0.0", "debug": "^4.1.0", @@ -7322,56 +7369,56 @@ } }, "@babel/generator": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.5.tgz", - "integrity": "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==", + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.8.tgz", + "integrity": "sha512-gZbepsdh3WDtgZKWL+vTPh71LSBrm/Y4/QDZBVCcYfmeTEEuoOYwlSy+G1StfJg+/Zy550u/3TATbm7qDbbMtg==", "dev": true, "requires": { - "@babel/parser": "^7.28.5", - "@babel/types": "^7.28.5", + "@babel/parser": "^7.29.8", + "@babel/types": "^7.29.8", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "@babel/helper-compilation-targets": { - "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", - "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz", + "integrity": "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==", "dev": true, "requires": { - "@babel/compat-data": "^7.27.2", - "@babel/helper-validator-option": "^7.27.1", + "@babel/compat-data": "^7.29.7", + "@babel/helper-validator-option": "^7.29.7", "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" } }, "@babel/helper-globals": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", - "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz", + "integrity": "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==", "dev": true }, "@babel/helper-module-imports": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", - "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz", + "integrity": "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==", "dev": true, "requires": { - "@babel/traverse": "^7.27.1", - "@babel/types": "^7.27.1" + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7" } }, "@babel/helper-module-transforms": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz", - "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz", + "integrity": "sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==", "dev": true, "requires": { - "@babel/helper-module-imports": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1", - "@babel/traverse": "^7.28.3" + "@babel/helper-module-imports": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7", + "@babel/traverse": "^7.29.7" } }, "@babel/helper-plugin-utils": { @@ -7381,40 +7428,40 @@ "dev": true }, "@babel/helper-string-parser": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", - "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz", + "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==", "dev": true }, "@babel/helper-validator-identifier": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", - "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", + "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", "dev": true }, "@babel/helper-validator-option": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", - "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz", + "integrity": "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==", "dev": true }, "@babel/helpers": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz", - "integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.7.tgz", + "integrity": "sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==", "dev": true, "requires": { - "@babel/template": "^7.27.2", - "@babel/types": "^7.28.4" + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.7" } }, "@babel/parser": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz", - "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==", + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.8.tgz", + "integrity": "sha512-E8lTAYNB1KW+FH+VGJuZM1ioAx2E6oVlvQFRrf5P8ZZmsiJXYAD9vTFV7yyEURNzgh1dFqMZuO6tUwcARbqFCA==", "dev": true, "requires": { - "@babel/types": "^7.28.5" + "@babel/types": "^7.29.8" } }, "@babel/plugin-syntax-async-generators": { @@ -7571,39 +7618,39 @@ } }, "@babel/template": { - "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", - "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz", + "integrity": "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==", "dev": true, "requires": { - "@babel/code-frame": "^7.27.1", - "@babel/parser": "^7.27.2", - "@babel/types": "^7.27.1" + "@babel/code-frame": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7" } }, "@babel/traverse": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.5.tgz", - "integrity": "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==", + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.8.tgz", + "integrity": "sha512-I5z7H3bf/41ktsNVLtpN0wAa336HkqIHQ5BuPLEhTkt1jVSyZpeNKIzTgEWmlxjdg81R0IgUCcaE+Ok3NvrfZg==", "dev": true, "requires": { - "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.28.5", - "@babel/helper-globals": "^7.28.0", - "@babel/parser": "^7.28.5", - "@babel/template": "^7.27.2", - "@babel/types": "^7.28.5", + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.8", + "@babel/helper-globals": "^7.29.7", + "@babel/parser": "^7.29.8", + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.8", "debug": "^4.3.1" } }, "@babel/types": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz", - "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==", + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.8.tgz", + "integrity": "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==", "dev": true, "requires": { - "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.28.5" + "@babel/helper-string-parser": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7" } }, "@bcoe/v8-coverage": { @@ -9004,13 +9051,14 @@ "integrity": "sha512-NZKeq9AfyQvEeNlN0zSYAaWrmBffJh3IELMZfRpJVWgrpEbtEpnjvzqBPf+mxoI287JohRDoa+/nsfqqiZmF6g==" }, "axios": { - "version": "1.13.5", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.5.tgz", - "integrity": "sha512-cz4ur7Vb0xS4/KUN0tPWe44eqxrIu31me+fbang3ijiNscE129POzipJJA6zniq2C/Z6sJCjMimjS8Lc/GAs8Q==", + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.20.0.tgz", + "integrity": "sha512-r8aOh8j9cGKpgQAqpzrUHnSIc6a59Y3Xf/cv8sy1DrHCkZHzQGEuoq1tARk6qSyDdtQGSDgpb9kFlruzPvrgwg==", "requires": { - "follow-redirects": "^1.15.11", - "form-data": "^4.0.5", - "proxy-from-env": "^1.1.0" + "follow-redirects": "^1.16.0", + "form-data": "^4.0.6", + "https-proxy-agent": "^5.0.1", + "proxy-from-env": "^2.1.0" } }, "babel-jest": { @@ -9095,9 +9143,9 @@ "integrity": "sha512-uAZ8x6r6S3aUM9rbHGVOIsR15U/ZSc82b3ymnCPsT45Gk1DDvhDPdIgB5MrhirZWt+5K0EEPQH985kNqZgNPFw==" }, "baseline-browser-mapping": { - "version": "2.8.28", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.28.tgz", - "integrity": "sha512-gYjt7OIqdM0PcttNYP2aVrr2G0bMALkBaoehD4BuRGjAOtipg0b6wHg1yNL+s5zSnLZZrGHOw4IrND8CD+3oIQ==", + "version": "2.11.19", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.19.tgz", + "integrity": "sha512-Grytf1xOxOEMTGRwx6rLGKkTabd4vMg3VrKdj/7joCmV0qgh4QwMMO6xh34YEXQqirAuUdgQGa5orJQQ+69RBw==", "dev": true }, "bech32": { @@ -9124,9 +9172,9 @@ } }, "body-parser": { - "version": "1.20.4", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.4.tgz", - "integrity": "sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA==", + "version": "1.20.6", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.6.tgz", + "integrity": "sha512-p5tAzS57i5MV9fZFDj9LeIiTZEufbSe2eDozP+ElheSUq1m74CRq1jI4mYNDdVs9vQztXFLuk/Gd6BWTdwRJ5g==", "requires": { "bytes": "~3.1.2", "content-type": "~1.0.5", @@ -9136,7 +9184,7 @@ "http-errors": "~2.0.1", "iconv-lite": "~0.4.24", "on-finished": "~2.4.1", - "qs": "~6.14.0", + "qs": "~6.15.1", "raw-body": "~2.5.3", "type-is": "~1.6.18", "unpipe": "~1.0.0" @@ -9175,9 +9223,9 @@ } }, "brace-expansion": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", - "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", + "version": "1.1.18", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz", + "integrity": "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==", "dev": true, "requires": { "balanced-match": "^1.0.0", @@ -9194,16 +9242,16 @@ } }, "browserslist": { - "version": "4.28.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.0.tgz", - "integrity": "sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ==", + "version": "4.28.8", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.8.tgz", + "integrity": "sha512-V2NpofLblG64mfOtSgDhOJESZEGogzDMBv/q+W6oc4LXWP/q75eOXoOaaOu1EOadB9U4Bwx/e0yzbvwKH8zalA==", "dev": true, "requires": { - "baseline-browser-mapping": "^2.8.25", - "caniuse-lite": "^1.0.30001754", - "electron-to-chromium": "^1.5.249", - "node-releases": "^2.0.27", - "update-browserslist-db": "^1.1.4" + "baseline-browser-mapping": "^2.11.12", + "caniuse-lite": "^1.0.30001809", + "electron-to-chromium": "^1.5.402", + "node-releases": "^2.0.53", + "update-browserslist-db": "^1.3.0" } }, "bs-logger": { @@ -9283,9 +9331,9 @@ "dev": true }, "caniuse-lite": { - "version": "1.0.30001754", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001754.tgz", - "integrity": "sha512-x6OeBXueoAceOmotzx3PO4Zpt4rzpeIFsSr6AAePTZxSkXiYDUmpypEl7e2+8NCd9bD7bXjqyef8CJYPC1jfxg==", + "version": "1.0.30001810", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001810.tgz", + "integrity": "sha512-TITQPUkaz+aVk5GL6NhOdwk1aEaNTSDPsGFWrTuhKGtjTF70jL/Oht2W4c6rXUe5fu7Ie19VIahAXHIIiWWNeg==", "dev": true }, "chalk": { @@ -9523,9 +9571,9 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "electron-to-chromium": { - "version": "1.5.253", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.253.tgz", - "integrity": "sha512-O0tpQ/35rrgdiGQ0/OFWhy1itmd9A6TY9uQzlqj3hKSu/aYpe7UIn5d7CU2N9myH6biZiWF3VMZVuup8pw5U9w==", + "version": "1.5.415", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.415.tgz", + "integrity": "sha512-958V+Kbhtgz+SxXeEVKBjrlKRBIDAYvUJfwhjxMZ5S6ut9jAl7l9ZKBkBrvjyjZE36PabLUo2L8kEeV5O4vgJg==", "dev": true }, "emittery": { @@ -9816,13 +9864,13 @@ } }, "express": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.22.1.tgz", - "integrity": "sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==", + "version": "4.22.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.22.2.tgz", + "integrity": "sha512-IuL+Elrou2ZvCFHs18/CIzy2Nzvo25nZ1/D2eIZlz7c+QUayAcYoiM2BthCjs+EBHVpjYjcuLDAiCWgeIX3X1Q==", "requires": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "~1.20.3", + "body-parser": "~1.20.5", "content-disposition": "~0.5.4", "content-type": "~1.0.4", "cookie": "~0.7.1", @@ -9841,7 +9889,7 @@ "parseurl": "~1.3.3", "path-to-regexp": "~0.1.12", "proxy-addr": "~2.0.7", - "qs": "~6.14.0", + "qs": "~6.15.1", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", "send": "~0.19.0", @@ -10002,9 +10050,9 @@ "dev": true }, "follow-redirects": { - "version": "1.15.11", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", - "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==" + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.0.tgz", + "integrity": "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==" }, "foreground-child": { "version": "3.3.1", @@ -10025,15 +10073,15 @@ } }, "form-data": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", - "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.6.tgz", + "integrity": "sha512-vKatAh4SlVfgbv+YtmhiRjhEMJsYpsG1Y2rMQtR+SVSbytsSD1YGzDIcrAJmdFec88u/+VoGmxnl+80gL1tRCQ==", "requires": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", - "hasown": "^2.0.2", - "mime-types": "^2.1.12" + "hasown": "^2.0.4", + "mime-types": "^2.1.35" } }, "forwarded": { @@ -10142,9 +10190,9 @@ "dev": true }, "brace-expansion": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", - "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", + "version": "5.0.9", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.9.tgz", + "integrity": "sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==", "dev": true, "requires": { "balanced-match": "^4.0.2" @@ -10234,9 +10282,9 @@ } }, "hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", + "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==", "requires": { "function-bind": "^1.1.2" } @@ -10259,6 +10307,15 @@ "toidentifier": "1.0.1" } }, + "https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "requires": { + "agent-base": "6", + "debug": "4" + } + }, "human-signals": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", @@ -10311,9 +10368,9 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "ip-address": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.1.0.tgz", - "integrity": "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==" + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.5.0.tgz", + "integrity": "sha512-R5SnVLJmgYYvf2F2ZgwSBnelz5G4q5AxIC277GDfUaNbrZKNANcBC7RHqYYePlszf4kBolVkJauG0ZjHHFh55g==" }, "ipaddr.js": { "version": "1.9.1", @@ -10902,9 +10959,9 @@ "dev": true }, "js-yaml": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", - "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.2.tgz", + "integrity": "sha512-SFNOvSJ+Dgf/9An904Yx+CgSlIPCkIpao4qo51lpee25TIRejdH3rhR4EZMGoNx3/TP3O+wzWuiTFl4sqbltzA==", "dev": true, "requires": { "argparse": "^2.0.1" @@ -11210,9 +11267,9 @@ "dev": true }, "node-releases": { - "version": "2.0.27", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", - "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", + "version": "2.0.53", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.53.tgz", + "integrity": "sha512-D9UOmYG3UH1V+ENW56t5QXBwJw1YEY18ruVeus89Rw+SyIgjPkCO84bRzO3uNIYosJbNwiabWVn48o3uJLjxFQ==", "dev": true }, "normalize-path": { @@ -11470,9 +11527,9 @@ } }, "proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz", + "integrity": "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==" }, "punycode": { "version": "2.3.0", @@ -11487,11 +11544,12 @@ "dev": true }, "qs": { - "version": "6.14.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.2.tgz", - "integrity": "sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q==", + "version": "6.15.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.3.tgz", + "integrity": "sha512-O9gl3zCl5h5blw1KGUzQKhA5oUXSl8rwUIM5o0S3nCXMliSvy5Dzx7/DJcI+SwgICv+IneSZwhBh1oSyEHA71A==", "requires": { - "side-channel": "^1.1.0" + "es-define-property": "^1.0.1", + "side-channel": "^1.1.1" } }, "queue-microtask": { @@ -11710,24 +11768,24 @@ "dev": true }, "side-channel": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", - "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.1.tgz", + "integrity": "sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==", "requires": { "es-errors": "^1.3.0", - "object-inspect": "^1.13.3", - "side-channel-list": "^1.0.0", + "object-inspect": "^1.13.4", + "side-channel-list": "^1.0.1", "side-channel-map": "^1.0.1", "side-channel-weakmap": "^1.0.2" } }, "side-channel-list": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", - "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz", + "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==", "requires": { "es-errors": "^1.3.0", - "object-inspect": "^1.13.3" + "object-inspect": "^1.13.4" } }, "side-channel-map": { @@ -12100,9 +12158,9 @@ } }, "update-browserslist-db": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.4.tgz", - "integrity": "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.3.1.tgz", + "integrity": "sha512-ZZ61DsRsOnakl74HAmp3oSN4aXUmEWXf+i/yv0h7tIBfICc3VdrFErQKUUKPgu3AMsTUMbcongALEN4l6GSUrQ==", "dev": true, "requires": { "escalade": "^3.2.0", @@ -12218,9 +12276,9 @@ } }, "ws": { - "version": "8.19.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz", - "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==", + "version": "8.21.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.3.tgz", + "integrity": "sha512-201TZ/kPWxoPr/OKWjquZR1SWKXcvxdH+e1xrx89b3YbmzLMFCLfnaG1HFIgWzJOEWZ7MvpK++odZufgYR50Rw==", "requires": {} }, "y18n": { diff --git a/backend/package.json b/backend/package.json index 44b6158042a..35b9f7e6241 100644 --- a/backend/package.json +++ b/backend/package.json @@ -3,7 +3,7 @@ "version": "3.3.1", "description": "Bitcoin mempool visualizer and blockchain explorer backend", "license": "GNU Affero General Public License v3.0", - "homepage": "https://mempool.space", + "homepage": "https://explorer.bitcoinuniverse.io", "repository": { "type": "git", "url": "git+https://github.com/mempool/mempool" @@ -43,17 +43,17 @@ "dependencies": { "@mempool/electrum-client": "1.1.9", "@types/node": "^18.15.3", - "axios": "1.13.5", + "axios": "^1.20.0", "bitcoinjs-lib": "~6.1.3", "crypto-js": "~4.2.0", "express": "~4.22.1", "maxmind": "~4.3.11", "mysql2": "~3.17.1", - "rust-gbt": "file:./rust-gbt", "redis": "^4.7.0", + "rust-gbt": "file:./rust-gbt", "socks-proxy-agent": "~7.0.0", "typescript": "~4.9.3", - "ws": "~8.19.0" + "ws": "^8.21.3" }, "devDependencies": { "@types/compression": "^1.7.2", diff --git a/backend/src/__fixtures__/mempool-config.template.json b/backend/src/__fixtures__/mempool-config.template.json index 0ca5654a5ab..c169caf6c32 100644 --- a/backend/src/__fixtures__/mempool-config.template.json +++ b/backend/src/__fixtures__/mempool-config.template.json @@ -7,6 +7,7 @@ "BLOCKS_SUMMARIES_INDEXING": true, "GOGGLES_INDEXING": false, "HTTP_PORT": 1, + "HTTP_HOST": "127.0.0.2", "UNIX_SOCKET_PATH": "/mempool/socket/mempool-bitcoin-mainnet", "SPAWN_CLUSTER_PROCS": 2, "API_URL_PREFIX": "__MEMPOOL_API_URL_PREFIX__", diff --git a/backend/src/__tests__/api/common.ts b/backend/src/__tests__/api/common.ts index fb245e15a98..796f1e2f807 100644 --- a/backend/src/__tests__/api/common.ts +++ b/backend/src/__tests__/api/common.ts @@ -24,7 +24,7 @@ describe('Common', () => { }); }); - describe('Mempool Goggles', () => { + describe('Transaction filter flags', () => { test('should detect nonstandard transactions', () => { nonStandardTransactions.forEach((tx) => { expect(Common.isNonStandard(tx)).toEqual(true); diff --git a/backend/src/__tests__/config.test.ts b/backend/src/__tests__/config.test.ts index cf81a5f7f1c..7b7b6b4da10 100644 --- a/backend/src/__tests__/config.test.ts +++ b/backend/src/__tests__/config.test.ts @@ -20,6 +20,7 @@ describe('Mempool Backend Config', () => { BLOCKS_SUMMARIES_INDEXING: false, GOGGLES_INDEXING: false, HTTP_PORT: 8999, + HTTP_HOST: '127.0.0.1', UNIX_SOCKET_PATH: '', SPAWN_CLUSTER_PROCS: 0, API_URL_PREFIX: '/api/v1/', @@ -121,7 +122,7 @@ describe('Mempool Backend Config', () => { }); expect(config.EXTERNAL_DATA_SERVER).toStrictEqual({ - MEMPOOL_API: 'https://mempool.space/api/v1', + MEMPOOL_API: '', MEMPOOL_ONION: 'http://mempoolhqx4isw62xs7abwphsq7ldayuidyx2v2oethdhhj6mlo2r6ad.onion/api/v1', LIQUID_API: 'https://liquid.network/api/v1', LIQUID_ONION: 'http://liquidmom47f6s3m53ebfxn47p76a6tlnxib3wp6deux7wuzotdr6cyd.onion/api/v1' diff --git a/backend/src/api/backend-info.ts b/backend/src/api/backend-info.ts index af22f45b2cb..3d4951bd69e 100644 --- a/backend/src/api/backend-info.ts +++ b/backend/src/api/backend-info.ts @@ -9,6 +9,7 @@ import logger from '../logger'; class BackendInfo { private backendInfo: IBackendInfo; private timer; + private syncTimer; constructor() { // This file is created by ./fetch-version.ts during building @@ -31,6 +32,7 @@ class BackendInfo { backend: config.MEMPOOL.BACKEND, coreVersion: '?', osVersion: `${os.type()} ${os.release()}`, + chainSync: null, }; this.timer = setInterval(async () => { @@ -41,6 +43,13 @@ class BackendInfo { } }, 10 * 60 * 1000); // every 10 minutes void this.$updateCoreVersion(); // starting immediately + + // Sync state changes far more often than the version does, and a stale + // answer here would defeat the point of publishing it at all. + this.syncTimer = setInterval(async () => { + await this.$updateChainSync(); + }, 30 * 1000); + void this.$updateChainSync(); } /** @asyncSafe */ @@ -53,6 +62,28 @@ class BackendInfo { } } + /** + * Reads how far the node has got. Never throws: a node that cannot answer + * leaves the previous reading in place rather than replacing it with a + * fabricated one. + * + * @asyncSafe + */ + private async $updateChainSync(): Promise { + try { + const info = await bitcoinClient.getBlockchainInfo(); + this.backendInfo.chainSync = { + blocks: info.blocks, + headers: info.headers, + initialBlockDownload: !!info.initialblockdownload, + verificationProgress: info.verificationprogress, + checkedAt: new Date().toISOString(), + }; + } catch (e) { + logger.debug(`Could not read chain sync state. Reason: ${(e instanceof Error ? e.message : e)}`); + } + } + public getBackendInfo(): IBackendInfo { return this.backendInfo; } diff --git a/backend/src/api/bitcoin/esplora-api.ts b/backend/src/api/bitcoin/esplora-api.ts index f4b0b400c22..4669de8ff9c 100644 --- a/backend/src/api/bitcoin/esplora-api.ts +++ b/backend/src/api/bitcoin/esplora-api.ts @@ -283,7 +283,9 @@ class FailoverRouter { path: '/en-US/resources/config.js', method: 'GET', headers: { - 'Host': Common.isLiquid() ? 'liquid.network' : 'mempool.space' + // The failover host answers for its own domain; upstream hardcoded + // its hosted domain here, which is not this deployment's. + 'Host': host.publicDomain.replace('https://', '').replace('http://', '') }, timeout: config.ESPLORA.FALLBACK_TIMEOUT, }, (res) => { diff --git a/backend/src/api/common.ts b/backend/src/api/common.ts index 8fcd2b27bbc..98d9161d8fc 100644 --- a/backend/src/api/common.ts +++ b/backend/src/api/common.ts @@ -189,7 +189,7 @@ export class Common { static isDERSig(w: string): boolean { // heuristic to detect probable DER signatures return (w.length >= 18 - && w.startsWith('30') // minimum DER signature length is 8 bytes + sighash flag (see https://mempool.space/testnet/tx/c6c232a36395fa338da458b86ff1327395a9afc28c5d2daa4273e410089fd433) + && w.startsWith('30') // minimum DER signature length is 8 bytes + sighash flag (see testnet transaction c6c232a36395fa338da458b86ff1327395a9afc28c5d2daa4273e410089fd433) && ['01', '02', '03', '81', '82', '83'].includes(w.slice(-2)) // signature must end with a valid sighash flag && (w.length === (2 * parseInt(w.slice(2, 4), 16)) + 6) // second byte encodes the combined length of the R and S components ); diff --git a/backend/src/api/pools-parser.ts b/backend/src/api/pools-parser.ts index 92c8e919dcc..c40d27d7fc7 100644 --- a/backend/src/api/pools-parser.ts +++ b/backend/src/api/pools-parser.ts @@ -87,7 +87,7 @@ class PoolsParser { if (poolDB.name !== pool.name) { // Pool has been renamed const newSlug = pool.name.replace(/[^a-z0-9]/gi, '').toLowerCase(); - logger.warn(`Renaming ${poolDB.name} mining pool to ${pool.name}. Slug has been updated. Maybe you want to make a redirection from 'https://mempool.space/mining/pool/${poolDB.slug}' to 'https://mempool.space/mining/pool/${newSlug}`); + logger.warn(`Renaming ${poolDB.name} mining pool to ${pool.name}. Slug has been updated. Maybe you want to redirect '/mining/pool/${poolDB.slug}' to '/mining/pool/${newSlug}'`); await PoolsRepository.$renameMiningPool(poolDB.id, newSlug, pool.name); clearCache = true; } @@ -195,9 +195,9 @@ class PoolsParser { * @asyncUnsafe */ private async $reindexBlocksForPool(poolId: number): Promise { - let firstKnownBlockPool = 130635; // https://mempool.space/block/0000000000000a067d94ff753eec72830f1205ad3a4c216a08a80c832e551a52 + let firstKnownBlockPool = 130635; // block 0000000000000a067d94ff753eec72830f1205ad3a4c216a08a80c832e551a52 if (config.MEMPOOL.NETWORK === 'testnet') { - firstKnownBlockPool = 21106; // https://mempool.space/testnet/block/0000000070b701a5b6a1b965f6a38e0472e70b2bb31b973e4638dec400877581 + firstKnownBlockPool = 21106; // testnet block 0000000070b701a5b6a1b965f6a38e0472e70b2bb31b973e4638dec400877581 } else if (['signet', 'testnet4', 'regtest'].includes(config.MEMPOOL.NETWORK)) { firstKnownBlockPool = 0; } diff --git a/backend/src/config.ts b/backend/src/config.ts index 9c1762378b7..e0396a1d681 100644 --- a/backend/src/config.ts +++ b/backend/src/config.ts @@ -9,6 +9,7 @@ interface IConfig { NETWORK: 'mainnet' | 'testnet' | 'testnet4' | 'signet' | 'liquid' | 'liquidtestnet' | 'regtest'; BACKEND: 'esplora' | 'electrum' | 'none'; HTTP_PORT: number; + HTTP_HOST: string; UNIX_SOCKET_PATH: string; SPAWN_CLUSTER_PROCS: number; API_URL_PREFIX: string; @@ -180,6 +181,10 @@ const defaults: IConfig = { 'NETWORK': 'mainnet', 'BACKEND': 'none', 'HTTP_PORT': 8999, + // Loopback by default. Upstream binds every interface, which publishes the + // API on whatever address the host happens to have. A deployment that + // wants that must ask for it. + 'HTTP_HOST': '127.0.0.1', 'UNIX_SOCKET_PATH': '', 'SPAWN_CLUSTER_PROCS': 0, 'API_URL_PREFIX': '/api/v1/', @@ -300,7 +305,8 @@ const defaults: IConfig = { 'PASSWORD': '' }, 'EXTERNAL_DATA_SERVER': { - 'MEMPOOL_API': 'https://mempool.space/api/v1', + // Unset by default: this deployment never calls a hosted third-party API. + 'MEMPOOL_API': '', 'MEMPOOL_ONION': 'http://mempoolhqx4isw62xs7abwphsq7ldayuidyx2v2oethdhhj6mlo2r6ad.onion/api/v1', 'LIQUID_API': 'https://liquid.network/api/v1', 'LIQUID_ONION': 'http://liquidmom47f6s3m53ebfxn47p76a6tlnxib3wp6deux7wuzotdr6cyd.onion/api/v1' diff --git a/backend/src/index.ts b/backend/src/index.ts index 45dc16fb413..1428e405b0b 100644 --- a/backend/src/index.ts +++ b/backend/src/index.ts @@ -217,11 +217,11 @@ class Server { void this.$runLightningBackend(); } - this.server.listen(config.MEMPOOL.HTTP_PORT, () => { + this.server.listen(config.MEMPOOL.HTTP_PORT, config.MEMPOOL.HTTP_HOST, () => { if (worker) { logger.info(`Mempool Server worker #${process.pid} started`); } else { - logger.notice(`Mempool Server is running on port ${config.MEMPOOL.HTTP_PORT}`); + logger.notice(`Mempool Server is running on ${config.MEMPOOL.HTTP_HOST}:${config.MEMPOOL.HTTP_PORT}`); } }); diff --git a/backend/src/mempool.interfaces.ts b/backend/src/mempool.interfaces.ts index a0888bb5066..9b07ae0c2d6 100644 --- a/backend/src/mempool.interfaces.ts +++ b/backend/src/mempool.interfaces.ts @@ -507,6 +507,23 @@ export interface IBackendInfo { coreVersion: string; osVersion: string; backend: 'esplora' | 'electrum' | 'none'; + /** + * How far the node this explorer reads has actually got. + * + * An explorer that reads a node still in initial block download would + * otherwise present a months-old tip as the present, which is the one thing + * this product must never do. Null while the state has not been read yet. + */ + chainSync: IChainSyncState | null; +} + +export interface IChainSyncState { + blocks: number; + headers: number; + initialBlockDownload: boolean; + /** Fraction of the chain verified, 0 to 1, as the node reports it. */ + verificationProgress: number; + checkedAt: string; } export interface INetworkInfo { diff --git a/backend/src/repositories/AccelerationRepository.ts b/backend/src/repositories/AccelerationRepository.ts index a45a8062175..6ac5f555503 100644 --- a/backend/src/repositories/AccelerationRepository.ts +++ b/backend/src/repositories/AccelerationRepository.ts @@ -283,7 +283,7 @@ class AccelerationRepository { logger.debug(`Fetching accelerations between block ${lastSyncedHeight} and ${currentHeight}`); - // Fetch accelerations from mempool.space since the last synced block; + // Fetch accelerations from the configured services API since the last synced block; const accelerationsByBlock: {[height: number]: AccelerationHistory[]} = {}; const blockHashes = {}; let done = false; diff --git a/docker/backend/mempool-config.json b/docker/backend/mempool-config.json index ee8e329a64b..49862964604 100644 --- a/docker/backend/mempool-config.json +++ b/docker/backend/mempool-config.json @@ -5,6 +5,7 @@ "ENABLED": __MEMPOOL_ENABLED__, "OFFICIAL": __MEMPOOL_OFFICIAL__, "HTTP_PORT": __MEMPOOL_HTTP_PORT__, + "HTTP_HOST": "__MEMPOOL_HTTP_HOST__", "SPAWN_CLUSTER_PROCS": __MEMPOOL_SPAWN_CLUSTER_PROCS__, "UNIX_SOCKET_PATH": "__MEMPOOL_UNIX_SOCKET_PATH__", "API_URL_PREFIX": "__MEMPOOL_API_URL_PREFIX__", diff --git a/docker/backend/start.sh b/docker/backend/start.sh index ae0bc616f8f..cc554c2130c 100755 --- a/docker/backend/start.sh +++ b/docker/backend/start.sh @@ -6,6 +6,7 @@ __MEMPOOL_BACKEND__=${MEMPOOL_BACKEND:=electrum} __MEMPOOL_ENABLED__=${MEMPOOL_ENABLED:=true} __MEMPOOL_OFFICIAL__=${MEMPOOL_OFFICIAL:=false} __MEMPOOL_HTTP_PORT__=${BACKEND_HTTP_PORT:=8999} +__MEMPOOL_HTTP_HOST__=${MEMPOOL_HTTP_HOST:=0.0.0.0} __MEMPOOL_SPAWN_CLUSTER_PROCS__=${MEMPOOL_SPAWN_CLUSTER_PROCS:=0} __MEMPOOL_UNIX_SOCKET_PATH__=${MEMPOOL_UNIX_SOCKET_PATH:=""} __MEMPOOL_API_URL_PREFIX__=${MEMPOOL_API_URL_PREFIX:=/api/v1/} @@ -170,6 +171,7 @@ sed -i "s!__MEMPOOL_BACKEND__!${__MEMPOOL_BACKEND__}!g" mempool-config.json sed -i "s!__MEMPOOL_ENABLED__!${__MEMPOOL_ENABLED__}!g" mempool-config.json sed -i "s!__MEMPOOL_OFFICIAL__!${__MEMPOOL_OFFICIAL__}!g" mempool-config.json sed -i "s!__MEMPOOL_HTTP_PORT__!${__MEMPOOL_HTTP_PORT__}!g" mempool-config.json +sed -i "s!__MEMPOOL_HTTP_HOST__!${__MEMPOOL_HTTP_HOST__}!g" mempool-config.json sed -i "s!__MEMPOOL_SPAWN_CLUSTER_PROCS__!${__MEMPOOL_SPAWN_CLUSTER_PROCS__}!g" mempool-config.json sed -i "s!__MEMPOOL_UNIX_SOCKET_PATH__!${__MEMPOOL_UNIX_SOCKET_PATH__}!g" mempool-config.json sed -i "s!__MEMPOOL_API_URL_PREFIX__!${__MEMPOOL_API_URL_PREFIX__}!g" mempool-config.json diff --git a/docs/legal/TRADEMARK-AUDIT.md b/docs/legal/TRADEMARK-AUDIT.md index 50318ccfc1b..64730e96c63 100644 --- a/docs/legal/TRADEMARK-AUDIT.md +++ b/docs/legal/TRADEMARK-AUDIT.md @@ -2,7 +2,10 @@ Purpose: ensure the public Universe Explorer deployment contains no Mempool Holdings trademarks, logos, slogans, or presentation implying affiliation. -Status: IN PROGRESS - inventory complete, removal tracked per item below. + +**Status: COMPLETE.** Enforced continuously by +`scripts/universe/check-branding.mjs`, which runs over the source tree and over +the production bundle in CI. A new occurrence fails the build. Upstream's own about page enumerates the marks of Mempool Holdings S.A. de C.V.: The Mempool Open Source Project (r), Mempool Accelerator (r), Mempool @@ -12,55 +15,86 @@ the mempool Logo, Square Logo, block visualization Logo, Blocks Logo, transaction Logo, Blocks 3|2 Logo, research Logo, and the mempool.space Vertical/Horizontal Logos. -## Inventory and disposition +## Disposition -| Item | Where found (fork base v3.3.1) | Disposition | -| --- | --- | --- | -| mempool logos (PNG/JPEG/SVG) | `frontend/src/resources/mempool-logo-bigger.png`, `mempool-space-logo-*.png`, `mempool-blocks-*-logo.jpeg`, `mempool-space-preview.png`, `previews/mempool-space-preview.jpg` | REMOVE; replace with original Universe logo treatment and social cards | -| In-app SVG logo components | `frontend/src/app/components/svg-images/svg-images.component.html` (mempool logo paths) | REPLACE with Universe marks | -| "Mempool Goggles" name | `block-filters.component.{ts,html}`, dashboards, transaction-details, about | REPLACE feature name with "Universe Lens"; strings must not ship in bundles | -| "Be your own explorer" slogan | `about.component.html` | REMOVE (about page replaced by Universe source/about page) | -| "Explore the full Bitcoin ecosystem" slogan | `search-form.component.html` placeholder, about | REPLACE with original Universe copy | -| Mempool Accelerator branding + UI | ~91 files under acceleration components/services | Feature remains disabled (no `MEMPOOL_SERVICES` configured); public routes/nav entries removed; branded strings removed from shipped bundles where reachable | -| Mempool Enterprise references | about page, services code | REMOVE from public surface | -| Trademark policy page | `frontend/src/app/components/trademark-policy/` | REMOVE route/page (policy text is Mempool Holdings'); fork keeps no claim to those marks | -| Sponsor graphics / profile images | about page sponsor sections, `frontend/src/resources/profile/*` | REMOVE from public deployment | -| mempool.space service links | chat/onion/enterprise links across components | REMOVE or replace with Universe equivalents | -| Liquid Network branding | liquid logos/components | Liquid views not exposed in Universe deployment (BASE_MODULE=mempool); assets retained in source for upstream mergeability, unreachable publicly | -| Package names/titles ("mempool-frontend", "Mempool" titles) | package.json, index HTML titles, manifests | REPLACE user-visible titles with Universe Explorer; internal package names may remain for merge hygiene | - -## Pass 1 status (2026-08-26) - -Completed in commit 94ebc0c6: header/footer/tracker/preview logos replaced -with the Universe wordmark, titles and metadata rebranded, search placeholder -and slogans replaced, visible Goggles strings renamed to Universe Lens, -/about and /trademark-policy routes removed, upstream service links removed -from the footer, social images repointed. Production bundle greps clean for -upstream marks in all reachable chunks. - -Documented residuals still open: - -| Item | Where | Plan | +| Item | Where it was | What was done | | --- | --- | --- | -| Slogans/Goggles strings in unreachable lazy chunks | about module (chunk emitted via Liquid master page), trademark-policy module, accelerator-dashboard | Unreachable at runtime on BASE_MODULE=mempool with removed routes and disabled services; excluded from Liquid build or stripped before GO | -| rel=canonical link element pointing at the upstream domain | frontend/src/index.mempool.html (feeds SeoService.baseDomain) | Replace with the production Universe domain at deployment configuration time | -| Address error state suggesting the upstream site as fallback viewer | address.component.html | Replace copy with Universe-only guidance | -| Upstream social links (GitHub/X/nostr/YouTube) | global-footer | Replace with Universe accounts or remove | -| Sponsor index variants (index.mempool.bitb/meta/onbtc/river/strategy/xxi.html) | frontend/src | Unused by generate-config; delete in a cleanup commit | -| Localized slogan strings | src/locale/*.xlf | Only shipped for non-English locales; regenerate translations from rebranded sources before enabling locales | +| Upstream logos (PNG, JPEG, SVG) | `frontend/src/resources/`, preview images | Replaced with the Universe wordmark and logo | +| In-app SVG logo components | `svg-images.component.html` | Replaced with Universe marks; the remaining accelerator glyph title is now a plain word | +| "Mempool Goggles" name | block filters, dashboards, transaction details | Feature renamed to Universe Lens; every identifier (`activeGoggles$`, `goggleCycle`, `goggleIndex`) renamed so the mark does not survive minification | +| "Be your own explorer" slogan | about page | About page deleted | +| "Explore the full Bitcoin ecosystem" slogan | search placeholder, about, Liquid index | Replaced with original Universe copy | +| Accelerator branding and checkout UI | ~91 files | Public routes and nav removed; `accelerate-checkout` deleted; the transaction and tracker templates no longer embed it; remaining acceleration display components carry no upstream mark | +| Enterprise references and upsells | about page, API docs, services code | Removed. `EnterpriseService.exclusiveHostName` is empty, so no hostname is treated as an enterprise subdomain, and the upstream redirect on an unknown subdomain is gone | +| Hosted analytics | `EnterpriseService.insertMatomo` | Now a documented no-op. No tracker is loaded on any hostname | +| Trademark policy page | `components/trademark-policy/` | Deleted, along with its Liquid route | +| About page and sponsor graphics | `components/about/` | Deleted, along with its Liquid route | +| Upstream service links | footer, docs, transaction details | Removed | +| Upstream social accounts | global footer | Removed. The version line now links to the Universe fork commit | +| Terms of service and privacy policy | upstream legal text | Rewritten as Universe documents describing this deployment | +| Sponsor index variants | `index.mempool.{bitb,meta,onbtc,river,strategy,xxi}.html` | Deleted; unused by `generate-config` | +| Upstream node fleet scripts | `scripts/get_backend_hash.sh`, `scripts/get_block_tip_height.sh` | Deleted | +| Lightning node group page | `frontend/src/app/lightning/group/` | Deleted with its routes; it existed to advertise upstream's own nodes | +| Upstream domains in defaults | `state.service.ts`, `seo.service.ts`, `config.ts`, proxy configs, sample configs, package homepages | Point at this deployment, or are unset | +| Upstream CDN for build assets | `frontend/sync-assets.js` | The hosted mirror rewrite is removed, and the production build skips asset synchronization entirely | +| Liquid branding | Liquid components and index | Liquid views are not exposed (`BASE_MODULE=mempool`); the Liquid index metadata is rebranded and the peg links resolve locally | +| Package names and titles | `package.json`, index HTML, manifests | User-visible titles are Universe Explorer; internal package names remain for merge hygiene | + +## Allowlisted references, and why + +The gate permits an upstream reference only in these paths: + +| Path | Reason | +| --- | --- | +| `COPYING.md`, `LICENSE` | Licence text, preserved verbatim | +| `UPSTREAM.md`, `upstream-base.json` | Fork provenance record | +| `CONTRIBUTING.md`, `contributors/` | Inherited contribution guide and contributor records | +| `docs/legal/` | This file and the AGPL compliance record | +| `docs/research/` | Competitor research that names the competitor | +| `docs/architecture/`, `docs/operations/UPSTREAM-SYNC.md` | Records which upstream subsystems are modified and how to sync | +| `README.md` | Fork attribution required by the licence | +| `backend/README.md`, `frontend/README.md`, `production/`, `docker/`, `rust/` | Inherited developer and operator notes | +| `frontend/src/locale/` | Upstream translation catalogues; not built by this deployment | +| `frontend/cypress/`, `.github/workflows/` | Inherited end-to-end suite, recorded fixtures, and upstream CI definitions | +| `scripts/universe/check-branding.mjs`, `check-origins.mjs` | The gates list the marks and hosts they ban | +| `audits/` | Dated audit records | + +Two attribution sentences are permitted anywhere, including inside a minified +bundle, because publishing them is the point of them: + +- the API docs statement that this is an independent instance of the + AGPL-licensed upstream codebase, not affiliated with or endorsed by the + upstream site; +- the source page statement that Universe Explorer is free software built on + the upstream project, with the corresponding source published. + +## Localization + +The 33 upstream translation catalogues under `frontend/src/locale/` still carry +upstream copy, including its marks. They are **not built**: the production +script `npm run build:universe` omits `--localize`, so only the English build +ships and no catalogue reaches a bundle. They are retained so a future +translation pass starts from the upstream structure rather than from nothing. +Re-enabling locales requires regenerating them from the rebranded sources, and +the branding gate must be pointed at the localized output before that ships. ## Rules applied - No confusingly similar logos: Universe iconography is designed independently. - The familiar explorer layout and mechanics of the AGPL codebase are retained; that is licensed functionality, not trade dress owned by upstream marketing. -- Upstream LICENSE/COPYING and copyright notices are PRESERVED (see - AGPL-COMPLIANCE.md) - only trademark usage is removed. -- The upstream synchronization procedure re-checks this table after every sync. +- Upstream LICENSE and COPYING notices are PRESERVED (see AGPL-COMPLIANCE.md). + Only trademark usage is removed. +- The upstream synchronization procedure re-runs the gate after every sync. + +## Verification, 26 August 2026 -## Release gate +``` +node scripts/universe/check-branding.mjs # source tree +node scripts/universe/check-branding.mjs frontend/dist # production bundle +node scripts/universe/check-origins.mjs +node scripts/universe/check-origins.mjs frontend/dist +node scripts/universe/check-text.mjs +``` -Do not declare GO until every REMOVE/REPLACE row above is verified against the -built production bundle (grep of `dist/` output for: "mempool.space", -"Goggles", "Be your own explorer", "Explore the full Bitcoin ecosystem", -"Accelerator", "Mempool Enterprise", plus visual review of all public routes). +All five passed against the release build. diff --git a/docs/operations/DEPLOYMENT.md b/docs/operations/DEPLOYMENT.md index c74f4a15389..0e44ac759ae 100644 --- a/docs/operations/DEPLOYMENT.md +++ b/docs/operations/DEPLOYMENT.md @@ -1,74 +1,119 @@ # Deployment -Universe Explorer runs as three processes behind one public HTTPS origin. +Universe Explorer runs as three processes on one host, reached through one +public HTTPS origin. -## Components +## Topology -| Component | What it is | Listens | -| --- | --- | --- | -| Explorer backend | The forked Mempool backend (Node, `backend/dist/index.js`) | loopback, `MEMPOOL.HTTP_PORT` | -| Protocol overlay | `backend-apis` standalone read-only service (`dist/universe-explorer-main.js`) | loopback, `UNIVERSE_EXPLORER_PORT` | -| Static frontend | Angular production build (`frontend/dist/mempool/browser`) | served by the gateway | +``` +explorer.bitcoinuniverse.io public origin, TLS terminated at the gateway host + -> nginx proxies the whole origin to one upstream + -> universe-explorer-tunnel forward-only SSH tunnel, 127.0.0.1:8385 + -> universe-indexer-01:8099 universe-explorer-gateway + /api/v1/universe/* -> universe-explorer-overlay 127.0.0.1:3400 + /api/* -> universe-explorer-backend 127.0.0.1:8996 + everything else -> the built frontend, SPA fallback +``` -The gateway (nginx) terminates TLS on 443 and routes: +No indexer port, RPC port, or database port is exposed publicly, and the +browser never learns an indexer origin. The tunnel key on the gateway host is +restricted to port forwarding and to that single destination port. -- `/api/v1/universe/*` and the `universe:*` WebSocket namespace to the overlay -- everything else under `/api/` to the explorer backend -- all other paths to the static frontend with SPA fallback +## Components + +| Unit | What it is | Listens | +| --- | --- | --- | +| `universe-explorer-backend.service` | the forked explorer backend, `backend/dist/index.js` | 127.0.0.1:8996 | +| `universe-explorer-overlay.service` | the `backend-apis` read-only protocol overlay, `dist/universe-explorer-main.js` | 127.0.0.1:3400 | +| `universe-explorer-gateway.service` | `scripts/universe/gateway.mjs`, static files plus routing | 127.0.0.1:8099 | -No native RPC port, indexer port, or database port is ever exposed publicly. +All three run as the `universe-explorer` system user. The backend additionally +holds the `bitcoin` supplementary group so it can read the Core cookie, and +nothing else. ## Data authorities -The explorer backend reads only Universe-owned infrastructure: +The backend reads only Universe-owned infrastructure: + +- Bitcoin Core on 127.0.0.1:8332, authenticated by cookie +- Fulcrum on 127.0.0.1:50001 for address and UTXO queries +- no third-party API, at runtime or at build time -- Bitcoin Core v31 through a bounded RPC pool (`universe-explorer-rpc-pool`), - never directly, so no single consumer can exhaust Core's connections -- Fulcrum (Electrum backend) for address and UTXO queries -- MariaDB for the explorer's own derived data (upstream migrations require - MariaDB syntax; MySQL 8.4 rejects them) -- A local static mirror for mining-pool metadata, so no runtime call leaves - Universe infrastructure +`DATABASE.ENABLED` is `false`. The database only powers historical indexing, +mining statistics, and audit features; the live explorer, the protocol overlay, +and every route this product leads with work without it. Running without it +keeps the explorer off the memory budget of a host that is also indexing. +`AUTOMATIC_POOLS_UPDATE` is `false` so no pool metadata is fetched from a third +party; mining pool logos fall back to the bundled default. The overlay reads only Universe protocol authorities, configured through -`UNIVERSE_EXPLORER_SOURCES_JSON` with bearer tokens supplied by separate -environment variables. Credentials never appear in the JSON, in responses, or -in logs. +`UNIVERSE_EXPLORER_SOURCES_JSON` in `/etc/universe-explorer/overlay.env`, with +bearer tokens supplied by separate named variables. Credentials never appear in +the JSON, in responses, or in logs. -## Development instance (universe-indexer-01) +## Configuration -Services, all bound to loopback: +`/etc/universe-explorer/`, owned by root, group `universe-explorer`, mode 0640: -``` -universe-explorer-rpc-pool.service bounded Bitcoin RPC pool -universe-explorer-static.service mining pool metadata mirror -universe-explorer-backend.service forked Mempool backend -universe-explorer-overlay.service protocol overlay -universe-explorer-mariadb (docker) explorer database +| File | Holds | +| --- | --- | +| `backend.json` | explorer backend configuration | +| `overlay.env` | overlay port and the protocol source registry | +| `gateway.env` | gateway ports and the static root | +| `fulcrum.conf` | the Electrum index this deployment reads | + +## Build + +Build on the runner fleet, not on the indexer host: + +```bash +cd frontend && npm ci && npm run build:universe +cd backend && npm ci && npm run build ``` -Configuration and secrets live in `/etc/universe-explorer/`, mode 0600. -Release checkouts live under `/opt/universe-explorer/`. +`build:universe` deliberately omits `--localize` and asset synchronization. Only +the English build ships, and nothing is downloaded from a third party. ## Release procedure -1. Build and test on the certified runner fleet (`.github/workflows/universe-ci.yml`). -2. Deploy the new release beside the current one; never overwrite a live release - directory in place. -3. Run the explorer backend against the new release on its own port. -4. Verify: tip height matches Core, mempool count is non-zero, fee estimates - resolve, a known block and transaction render, and the overlay reports its - sources with agreeing checkpoints. -5. Switch the gateway upstream to the new port; keep the previous release - running through the stability window so rollback is a single upstream flip. -6. Remove the superseded release only after the window closes. +1. Run the full check set on the runner fleet + (`.github/workflows/universe-ci.yml`), including the branding, origin, and + text gates against both the source tree and `frontend/dist`. +2. Install the new release beside the running one under + `/opt/universe-explorer/releases/mempool-/`. Never overwrite a live + release directory in place. +3. Point `/opt/universe-explorer/current` at the new release with an atomic + symlink swap. +4. Restart the three explorer units. The gateway comes back within a second, + so the public origin sees at most a brief connection reset rather than a + sustained outage. +5. Verify: `/__gateway/health` on the gateway, tip height against Core, + a known block and transaction render, `/api/v1/universe/status` reports its + sources, and the `/source` page shows the deployed commit. +6. Keep the previous release directory until the stability window closes. + +## Rollback + +Point the symlink back and restart: + +```bash +ln -sfn /opt/universe-explorer/releases/mempool- /opt/universe-explorer/current.new +mv -Tf /opt/universe-explorer/current.new /opt/universe-explorer/current +systemctl restart universe-explorer-backend universe-explorer-overlay universe-explorer-gateway +``` + +Nothing else changes: configuration lives outside the release directory, and no +migration runs, so a rollback is exactly the same operation in reverse. + +## Rules -Never restart a protocol indexer to make a deployment convenient, never stop -Bitcoin Core, and never interrupt an in-flight build. +Never restart a protocol indexer to make a deployment convenient. Never stop +Bitcoin Core. Never interrupt an ord index rebuild. `universe-mempool.service` +on the same host is a different product and is not part of this stack. ## Release identity -Every deployment exposes its identity: the explorer backend reports -`gitCommit` on `/api/v1/backend-info`, and the public `/source` page renders -the Universe release SHA, the pinned upstream base, the license, and the -source repository link. A build whose SHA is not published must not ship. +Every deployment publishes what it is running: the backend reports `gitCommit` +on `/api/v1/backend-info`, and the public `/source` page renders the release +SHA, the pinned upstream base, the licence, and the source repository link. A +build whose SHA is not published must not ship. diff --git a/docs/product/EXPERIENCE-BRIEF.md b/docs/product/EXPERIENCE-BRIEF.md new file mode 100644 index 00000000000..91646e290c5 --- /dev/null +++ b/docs/product/EXPERIENCE-BRIEF.md @@ -0,0 +1,84 @@ +# Universe Explorer experience brief + +Written 26 August 2026 to direct implementation. Every statement here is meant +to settle a build decision, not to describe an aspiration. + +## The promise + +**See what a Bitcoin transaction actually does, with the proof attached.** + +Everything else follows from that sentence. If a screen cannot show what it +proves, it does not ship. + +## Who it is for + +| Group | Highest-value job | What they do here | +| --- | --- | --- | +| Protocol holders and traders | "What is on this output, right now" | Open an output, an address, or an asset and read exactly what the authority proves. | +| Builders on Bitcoin protocols | "Did my transaction do what I intended" | Read a transaction, see the action the authority reported, and follow it to the outputs it landed on. | +| Fee-sensitive Bitcoin users | "When does this confirm and what does it cost" | The upstream mempool machinery, unchanged and still excellent. | +| Analysts and researchers | "What is happening across protocols right now" | The pulse page, with a published denominator so the number can be checked. | +| Operators self-hosting | "Can I run this and trust it" | One documented stack, first-party data only, source published on the site. | + +## The emotional outcomes to design for + +1. **Oriented in seconds.** Live data above the fold, one dominant search field, + no marketing hero. +2. **In control.** Every state is addressable and shareable. Nothing important + hides behind a modal. +3. **Confident the data is real.** Each claim names its authority and the block + it was proven at. +4. **Curious.** One page always suggests the next honest hop: transaction to + output, output to asset, asset to protocol, protocol to live activity. +5. **Early.** The pulse shows protocol transactions while they are still pending. +6. **Able to explain it.** Plain-language first, technical detail underneath. + +## What competitors cannot easily copy + +1. **A mempool-grade explorer that also decodes protocol assets.** The strongest + mempool explorer refuses metaprotocol interpretation as a matter of policy. + The strongest protocol explorers are thin on the mempool. Both positions are + deliberate, so neither moves quickly. +2. **First-party authorities.** The protocol data comes from indexers Bitcoin + Universe runs. Hosted protocol data keeps disappearing from this market; + infrastructure that is owned does not. +3. **Evidence as a product surface, not a footnote.** Proven, partly proven, + outside coverage, pending, and unavailable are five distinct answers with + five distinct treatments. Competitors show a value or an empty cell. +4. **Outputs as first-class pages.** Everyone else treats an output as a table + row inside a transaction. +5. **Self-hostable and readable.** Full source, AGPL, no tracker, no account. + +## Why people come back + +Real utility, not compulsion. + +- The pulse changes every block, and it is the only place to see verified + protocol activity before confirmation. +- Saved pages and recent history make the second visit faster than the first. +- Pinned protocols shape the views the visitor actually cares about. +- Deep links mean a colleague's link lands exactly where it should. + +Explicitly rejected: fabricated scarcity, engineered urgency, notification +spam, streaks, gamified counters, and any metric that cannot be recomputed from +published numbers. Urgency in this product is allowed only when the chain +supplies it: a pending transaction, a live mint approaching its cap, a first +sighting, an unusual verified event. + +## Boundaries + +- **Read only.** The one write path is the transaction broadcast that already + exists upstream. +- **No inference.** Ownership, transfers, trades, buyers, and sellers are never + asserted from transaction shape. If the authority did not say it, the page + does not say it. +- **No third-party data.** Not as a fallback, not behind a flag. +- **No profile.** Personalization is local storage, and one button erases it. +- **No advertising or paid placement.** Rankings cannot be bought. +- **Scope stays an explorer.** Not a wallet, not a market, not a custodian. + +## The one-sentence position + +Universe Explorer is the only self-hostable, mempool-grade Bitcoin explorer that +shows exactly which outputs carry which protocol assets, with first-party +evidence and a stated block for every claim. diff --git a/docs/research/competitive-landscape.md b/docs/research/competitive-landscape.md index 2a482584b2b..0ce1da7e062 100644 --- a/docs/research/competitive-landscape.md +++ b/docs/research/competitive-landscape.md @@ -1,6 +1,6 @@ # Competitive Landscape: Bitcoin Protocol-Aware Explorers -**Draft — August 2026.** Research for "Universe Explorer": a self-hosted, protocol-aware +**Draft, August 2026.** Research for "Universe Explorer": a self-hosted, protocol-aware fork of mempool.space that shows exact asset flows across transaction inputs/outputs, backed by authoritative indexer evidence (never heuristics). @@ -15,7 +15,7 @@ Verdict legend: **ADOPT** = adopt the principle · **IMPROVE** = do it, but bett **What it is.** The de-facto reference Bitcoin explorer, centered on the mempool rather than the chain: live fee market, projected (audited) blocks, mining dashboards, and a -Lightning explorer. Actively developed — v3.0 (Accelerator/Goggles integration, +Lightning explorer. Actively developed, v3.0 (Accelerator/Goggles integration, full-RBF timelines), v3.2 (April 2025: UTXO bubble chart, Stratum job visualizations, address-poisoning warnings, runestone tags, package broadcast, PSBT previews), v3.3 (Taproot script-tree visualization, sighash icons/highlighting, stale-block @@ -25,7 +25,7 @@ merkle proofs on non-Esplora backends). **Protocol support.** Deliberately minimal. It tags transactions that contain inscription envelopes or runestones (Mempool Goggles filters, runestone tags) but the maintainers have publicly stated they will not integrate `ord` or any metaprotocol -indexer — it displays what is in the mempool/blockchain, nothing interpreted. No +indexer, it displays what is in the mempool/blockchain, nothing interpreted. No BRC-20 balances, no Runes decoding beyond tagging, no Ordinals content rendering. **Signature features.** @@ -33,7 +33,7 @@ BRC-20 balances, no Runes decoding beyond tagging, no Ordinals content rendering - Projected blocks + block audit (expected vs. actual block composition; detects prioritized/excluded txs). - Full-RBF replacement timelines (tree of replacements with timestamps and fee deltas). - CPFP/effective-fee computation and package relationships. -- Accelerator (paid out-of-band acceleration via partner pools) — off-chain commercial service. +- Accelerator (paid out-of-band acceleration via partner pools), off-chain commercial service. - Mining dashboards: pool dominance, hashrate, difficulty adjustment, Stratum job monitoring, DATUM/coinbase tags. - Address pages with UTXO endpoint, taproot script tree rendering, PSBT/raw-tx preview tool, address-poisoning detection. - Self-hostable (Umbrel/Start9/Docker); first-class REST + WebSocket APIs; Liquid + Testnet4 + regtest support. @@ -41,7 +41,7 @@ BRC-20 balances, no Runes decoding beyond tagging, no Ordinals content rendering **Strengths.** Best-in-class mempool UX and visual language; strong self-hosting story; excellent mobile/responsive design; healthy release cadence; trusted brand. -**Weaknesses.** Protocol-blind by ideology — a Runes/Ordinals/Alkanes user cannot see +**Weaknesses.** Protocol-blind by ideology, a Runes/Ordinals/Alkanes user cannot see what assets a transaction actually moves; asset "tags" are recognition, not accounting; Accelerator/enterprise services are centralized; Angular frontend is heavy to fork and track upstream. @@ -50,13 +50,13 @@ track upstream. |---|---|---| | Mempool goggles / live block-grid viz | **ADOPT** | The core visual metaphor is proven; extend filters to protocol-aware categories (inscription reveal, rune mint, alkane call) driven by indexer evidence. | | Projected blocks + block audit | **ADOPT** | Audit-style "expected vs. actual" thinking matches the evidence-first ethos; keep as-is from the fork base. | -| Full-RBF replacement timelines | **IMPROVE** | Keep the timeline, but add what replacement means for pending asset transfers (e.g. a replaced rune mint) — no one shows that today. | +| Full-RBF replacement timelines | **IMPROVE** | Keep the timeline, but add what replacement means for pending asset transfers (e.g. a replaced rune mint), no one shows that today. | | Runestone/inscription *tagging without decoding* | **IMPROVE** | Tagging is heuristic recognition; Universe must resolve tags to authoritative indexer state (asset IDs, amounts, edicts) per input/output. | | Accelerator (paid out-of-band) | **REJECT** | Commercial, centralized, irrelevant to a self-hosted evidence-focused explorer. | | Mining/Stratum dashboards | **OOS** | Valuable but orthogonal to asset-flow goals; inherit from fork base without investment. | | Lightning explorer | **OOS** | Different domain; keep disabled to reduce operational surface. | | REST/WebSocket API + self-host packaging | **ADOPT** | Table stakes; extend the same API style with asset-flow endpoints. | -| UTXO bubble chart / address UTXO endpoint | **IMPROVE** | Extend UTXO views to show attached assets (inscriptions, rune balances, stamps) per outpoint — the natural home for outpoint-level evidence. | +| UTXO bubble chart / address UTXO endpoint | **IMPROVE** | Extend UTXO views to show attached assets (inscriptions, rune balances, stamps) per outpoint, the natural home for outpoint-level evidence. | | Address-poisoning warnings, PSBT preview | **ADOPT** | Cheap safety wins already in the fork base; keep. | --- @@ -67,7 +67,7 @@ track upstream. **What it is.** An "all-in-one" explorer for Bitcoin and Fractal Bitcoin covering addresses, transactions, blocks, and assets across UniSat's indexer stack. In 2025–26 -it expanded to Alkanes and "brc2.0" alongside Ordinals, BRC-20, and Runes — currently +it expanded to Alkanes and "brc2.0" alongside Ordinals, BRC-20, and Runes, currently the broadest protocol coverage of any mainstream explorer, reflecting UniSat's position as an Alkanes ecosystem partner. @@ -114,7 +114,7 @@ server integration for AI agents. - Per-address views split by asset class (inscriptions / runes / BRC-20 / rare sats). - API: BRC-20 balances, address activity checks, tx-level info, rare-sat lookup, inscription transfer history per address. - Collections browsing with metadata. -- MCP server exposing the API to LLM tooling — an early "explorer as agent data source" move. +- MCP server exposing the API to LLM tooling, an early "explorer as agent data source" move. **Strengths.** Simple, fast, readable UX; API-first mindset; inscription *transfer history* (not just current location) is closer to flow-tracking than most. @@ -133,7 +133,7 @@ accounting; depends on third-party indexer infrastructure. --- -## 4. Ord.io — DEFUNCT +## 4. Ord.io, DEFUNCT **URL:** was https://ord.io · **Shut down June 1, 2026** (with its trading app Zap), citing financial unsustainability after ~3 years and 1M+ users. @@ -146,8 +146,7 @@ real-time Runes mint tracking. **Strengths (historical).** Best content-first browsing UX; made inscriptions legible to non-technical users; real-time mint feeds. -**Weaknesses / lesson.** Venture-funded consumer explorer with no durable revenue — -the shutdown is the cautionary tale for explorer sustainability. Social features +**Weaknesses / lesson.** Venture-funded consumer explorer with no durable revenue, the shutdown is the cautionary tale for explorer sustainability. Social features (votes, profiles) did not save it. | Feature | Verdict | Reasoning | @@ -169,7 +168,7 @@ its REST API surface became a de-facto standard (mempool.space implements a compatible API). **Protocol support.** None beyond base Bitcoin/Liquid. Liquid side: confidential -transactions, peg-in/out, multi-asset (issued assets) — notable because Liquid asset +transactions, peg-in/out, multi-asset (issued assets), notable because Liquid asset display is *consensus-level* asset accounting, shown per output. **Signature features.** @@ -181,14 +180,14 @@ display is *consensus-level* asset accounting, shown per output. **Strengths.** Privacy posture (Tor, no trackers, works without JS); the outpoint-level navigation model; battle-tested self-host path; API standardization. -**Weaknesses.** Static feel — no live mempool visualization, no RBF timelines, no +**Weaknesses.** Static feel, no live mempool visualization, no RBF timelines, no projected blocks; zero metaprotocol awareness on Bitcoin; development has slowed relative to mempool.space; heavy disk requirements for full index. | Feature | Verdict | Reasoning | |---|---|---| | Outpoint-level navigation (prev-out ↔ spend links) | **ADOPT** | The structural skeleton that asset-flow evidence hangs on; make every outpoint a first-class page with asset annotations. | -| Liquid-style per-output asset display | **ADOPT** | Exactly the right *presentation* for assets on outputs — Universe applies it to metaprotocol assets with indexer evidence instead of consensus data. | +| Liquid-style per-output asset display | **ADOPT** | Exactly the right *presentation* for assets on outputs, Universe applies it to metaprotocol assets with indexer evidence instead of consensus data. | | Tor / no-tracking / noscript operation | **ADOPT** | Privacy-preserving defaults are core to a self-hosted explorer's value. | | API-standard compatibility (Esplora API) | **ADOPT** | Keeping Esplora-compatible endpoints (via the mempool fork base) preserves ecosystem tooling. | | Multi-language UI (17 locales) | **OOS** | Nice-to-have; inherit whatever the fork base provides, don't invest early. | @@ -209,7 +208,7 @@ sweeps them up with a satisfying animation. Self-hostable (Umbrel app). **Signature features.** Value-scaled live tx squares; block-formation animation; block composition view; "screensaver" mode. -**Strengths.** Emotional/legibility win — makes network activity *felt*; tiny, +**Strengths.** Emotional/legibility win, makes network activity *felt*; tiny, self-hostable, elegant; open source. **Weaknesses.** Not an explorer (no search, addresses, or history); one-trick; @@ -218,7 +217,7 @@ maintenance is quiet since its author moved to mempool.space. | Feature | Verdict | Reasoning | |---|---|---| | Ambient real-time block-formation animation | **OOS** | Delightful but decorative; Universe's live view already comes from the mempool fork base. | -| Value/size-scaled visual encoding of txs | **ADOPT** | The principle — visual channels encoding real tx properties — should extend to protocol events (e.g. color = asset action, verified by indexer). | +| Value/size-scaled visual encoding of txs | **ADOPT** | The principle, visual channels encoding real tx properties, should extend to protocol events (e.g. color = asset action, verified by indexer). | | Minimal self-host footprint | **ADOPT** | Keep Universe deployable on modest hardware where possible; heavy indexers should be optional modules. | --- @@ -242,7 +241,7 @@ client-side; not practically self-hostable end-to-end (backend pieces incomplete |---|---|---| | Gamified fee-market metaphor | **REJECT** | Charming but at odds with an evidence-first professional tool; mempool goggles communicate the same facts precisely. | | Multi-chain visualization | **OOS** | Universe is Bitcoin-only by design. | -| Making fee dynamics legible to newcomers | **IMPROVE** | The *goal* is right — serve it with accurate projected-block and fee-band UI, not cartoons. | +| Making fee dynamics legible to newcomers | **IMPROVE** | The *goal* is right, serve it with accurate projected-block and fee-band UI, not cartoons. | --- @@ -274,7 +273,7 @@ privacy-o-meter is explicitly heuristic; multi-chain breadth is noise for Bitcoi |---|---|---| | SQL-like filterable data API | **IMPROVE** | Powerful principle; Universe can expose rich filtered queries over *indexer-evidenced* asset events rather than raw columns only. | | Privacy-o-meter (heuristic tx scoring) | **REJECT** | Heuristic scoring is precisely the "never heuristics" anti-pattern; if Universe flags anything, it must be provable properties. | -| Anonymous portfolio / xPub statements | **IMPROVE** | Portfolio views are wanted, but on a self-hosted instance they become private by construction — add asset-aware balances. | +| Anonymous portfolio / xPub statements | **IMPROVE** | Portfolio views are wanted, but on a self-hosted instance they become private by construction, add asset-aware balances. | | Database dumps for researchers | **ADOPT** | Exportable, reproducible datasets align with evidence-first values; publish indexer snapshots with block-height provenance. | | 40+ chain coverage | **REJECT** | Horizontal breadth is the opposite of Universe's vertical protocol depth. | @@ -286,7 +285,7 @@ privacy-o-meter is explicitly heuristic; multi-chain breadth is noise for Bitcoi **What it is.** The largest exchange-operated protocol-aware Bitcoin explorer: inscription lists, BRC-20 token tracker (deploy/mint/transfer states, holders), -Ordinals transaction lists, Runes market data, Atomicals support — all fused with +Ordinals transaction lists, Runes market data, Atomicals support, all fused with OKX's wallet and inscription marketplace. **Protocol support.** Ordinals/inscriptions, BRC-20, Runes, Atomicals (via wallet @@ -314,7 +313,7 @@ strategy (cf. Magic Eden's exit). --- -## 10. Magic Eden Ordinals Explorer — DEFUNCT (as explorer) +## 10. Magic Eden Ordinals Explorer, DEFUNCT (as explorer) **URL:** was magiceden.io / magiceden.us Ordinals + Runes sections · **Feb 27, 2026: announced shutdown** of Bitcoin Ordinals, Runes, and EVM NFT marketplaces (and its multi-chain wallet) to refocus on Solana and a gambling product. @@ -326,8 +325,7 @@ sat listings, wallet portfolio views, Runes swap UI. **Strengths (historical).** Collection-level metadata, market context (floors, volume) that pure explorers lack. -**Weaknesses / lesson.** Marketplace economics could not sustain the infrastructure — -80% of costs for 20% of revenue. Its exit (weeks before Ord.io's) leaves a data +**Weaknesses / lesson.** Marketplace economics could not sustain the infrastructure, 80% of costs for 20% of revenue. Its exit (weeks before Ord.io's) leaves a data vacuum: collection metadata and market context lost a canonical home in 2026. | Feature | Verdict | Reasoning | @@ -358,7 +356,7 @@ and account funnels; API less loved than Esplora-compatible ones; innovation has | Feature | Verdict | Reasoning | |---|---|---| -| Beginner-simple search & address pages | **ADOPT** | Progressive disclosure — simple by default, deep on demand — is worth preserving in a power tool. | +| Beginner-simple search & address pages | **ADOPT** | Progressive disclosure, simple by default, deep on demand, is worth preserving in a power tool. | | Price/market data on explorer pages | **OOS** | Fiat context is not evidence; keep optional at most. | | Account/wallet funnel around explorer | **REJECT** | Same neutrality argument as OKX/Magic Eden. | @@ -366,14 +364,14 @@ and account funnels; API less loved than Esplora-compatible ones; innovation has ## 12. Notable emerging / adjacent explorers (2025–2026) -### Ordpool (ordpool.space) — the direct precedent +### Ordpool (ordpool.space), the direct precedent Open-source fork of mempool.space that decodes **Inscriptions, Runes (incl. Alkanes), -BRC-20, SRC-20 Stamps, CAT-21, Atomicals, Labitbu, and OpenTimestamps** — including +BRC-20, SRC-20 Stamps, CAT-21, Atomicals, Labitbu, and OpenTimestamps**, including *while transactions are still in the mempool*. Built on `ordpool-parser`, a zero-dependency TypeScript parser applied to raw transactions. - **Validation:** proves the "protocol-aware mempool.space fork" concept Universe is pursuing, and that mempool-time metaprotocol decoding is feasible. -- **Key limitation:** parsing raw envelopes client/edge-side is *recognition*, not authoritative state — a decoded runestone doesn't tell you whether the mint was valid, within cap, or how balances resolve. That gap (parser output vs. indexer truth) is exactly Universe's differentiator. +- **Key limitation:** parsing raw envelopes client/edge-side is *recognition*, not authoritative state, a decoded runestone doesn't tell you whether the mint was valid, within cap, or how balances resolve. That gap (parser output vs. indexer truth) is exactly Universe's differentiator. | Feature | Verdict | Reasoning | |---|---|---| @@ -389,9 +387,9 @@ analytics, user-built dashboards, and a developer API. Closed source, hosted. ### Stamps ecosystem: Stampchain.io & OpenStamp (openstamp.io) Stampchain publishes an open-source Bitcoin Stamps indexer + explorer + API (SRC-20, stamp NFTs, SRC-101); OpenStamp adds marketplace/launchpad around the same assets. -- Stamps data lives in multisig/bare-data outputs — a fundamentally different encoding from ordinals envelopes, so per-output asset attribution is *natural* for stamps. **ADOPT** open-indexer integration if/when Stamps support is prioritized. +- Stamps data lives in multisig/bare-data outputs, a fundamentally different encoding from ordinals envelopes, so per-output asset attribution is *natural* for stamps. **ADOPT** open-indexer integration if/when Stamps support is prioritized. -### Hiro Ordinals Explorer & API — deprecated +### Hiro Ordinals Explorer & API, deprecated Hiro's Ordinals API and explorer (once ~150M requests/month) were **deprecated March 9, 2026**, with users pointed to Xverse's Ordinals API and Hiro's Bitcoin Indexer repo. Another major hosted-Ordinals-data exit in 2026, reinforcing the self-hosting thesis. @@ -411,12 +409,12 @@ Sibling to UniScan with Runes "hot map" of recent mints and marketplace integrat metaprotocol interpretation; UniScan/OKX/Ordiscan show asset involvement and balances but not outpoint-level flow with evidence; Ordpool decodes envelopes without validity resolution. The only production precedent for per-output asset display is Esplora's - *Liquid* view — consensus assets, not metaprotocols. + *Liquid* view, consensus assets, not metaprotocols. 3. **Fork base is right.** mempool.space contributes the live mempool UX, RBF/CPFP machinery, audit mindset, API standards, and self-host packaging; Ordpool proves the fork approach; Esplora contributes the outpoint-navigation and privacy-default principles. 4. **Differentiator to protect:** every asset claim traceable to an authoritative indexer (ord, runes indexer, alkanes metashrew, stamps indexer) at a stated block - height — decoded-but-unvalidated mempool data must be visibly distinguished from + height, decoded-but-unvalidated mempool data must be visibly distinguished from validated state. Nothing shipped today makes that distinction. diff --git a/docs/research/emerging-trends.md b/docs/research/emerging-trends.md new file mode 100644 index 00000000000..ccf51e6e2a7 --- /dev/null +++ b/docs/research/emerging-trends.md @@ -0,0 +1,68 @@ +# Emerging trends brief + +Compiled 26 August 2026. Sources and access dates are in `source-ledger.md`. + +## 1. Data carriage stopped being policy-limited + +Bitcoin Core v30, released 10 October 2025, raised the default +`-datacarriersize` from 83 bytes to 100,000, which removes any practical limit +on OP_RETURN because a transaction hits the 100,000 vbyte ceiling first. The +planned deprecation of the `datacarrier` options was reverted before release, so +operators can still filter. Bitcoin Knots keeps stricter defaults, and a +meaningful share of operators run it for that reason. + +**What it means for an explorer.** Whether a data-carrying transaction relays now +depends on which software its peers run, not on consensus. A pending transaction +can be perfectly valid and still fail to propagate across part of the network. +No explorer currently shows that distinction. + +**Position taken.** Protocols that carry instructions in data outputs are +described that way on their pages, so the reader understands where the meaning +comes from. Instrumenting relay-policy divergence is recorded as the next area +of work rather than claimed today. + +## 2. Hosted protocol data keeps being withdrawn + +The pattern of 2026: an explorer or API that many products depended on is +retired, and everyone downstream scrambles. It happened to Ordinals data more +than once this year. + +**Position taken.** Every protocol figure comes from an indexer Bitcoin Universe +operates. The registry states which protocols have a running first-party +authority and which do not, so coverage is never overstated. + +## 3. Protocol families keep multiplying, and none of them wins + +Alkanes brought WebAssembly contracts to Bitcoin outputs via an open indexer; +Runes remains the dominant fungible standard; Stamps, Atomicals, TAP, DMT, and +CAT-20 each hold a niche. The population of standards is growing faster than any +one explorer's coverage. + +**Position taken.** The registry is a first-class contract with an explicit +release status per protocol, so adding coverage is a data and adapter change +rather than a redesign, and absent coverage is visible rather than silent. + +## 4. Agent-facing data access is becoming a category + +Hosted blockchain data providers now ship agent interfaces alongside their REST +APIs. Bitcoin-specific coverage in those products is thin. + +**Position taken.** Out of scope for this release. A stable, versioned, +same-origin public API is the prerequisite and it exists; an agent interface on +top of it is a later, additive step. + +## 5. Speed and the absence of tracking are being sold as features + +Explorers now advertise no third-party trackers and onion availability as +headline attributes rather than footnotes. + +**Position taken.** Both are enforced by build gates rather than claimed in +copy, and the privacy page states exactly what the browser stores. + +## 6. Explorers are still built for people who already know the answer + +Across the whole competitor set, no product writes a sentence explaining what a +transaction did. They present fields and leave interpretation to the reader. + +**Position taken.** Plain language first on every transaction, with the complete +technical detail directly underneath. diff --git a/docs/research/indexer-inventory.md b/docs/research/indexer-inventory.md index f6c1e87a01f..85721f03f79 100644 --- a/docs/research/indexer-inventory.md +++ b/docs/research/indexer-inventory.md @@ -5,7 +5,7 @@ Paths inside each section are relative to that repo's root unless prefixed with ## Headline cross-cutting findings -1. **`/v1/explorer/*` does not exist anywhere.** Zero hits for `v1/explorer` routes in any indexer, in backend-apis, or in wallet. The only string matches are backend-apis' *outbound* proxy to openstamp/stampchain (`src/external/external.controller.ts:280-284`, paths `/api/v1/explorer/src20/all` and `/api/v1/explorer/src20/holdersByTick`) — third-party URLs, not a served contract. +1. **`/v1/explorer/*` does not exist anywhere.** Zero hits for `v1/explorer` routes in any indexer, in backend-apis, or in wallet. The only string matches are backend-apis' *outbound* proxy to openstamp/stampchain (`src/external/external.controller.ts:280-284`, paths `/api/v1/explorer/src20/all` and `/api/v1/explorer/src20/holdersByTick`), third-party URLs, not a served contract. 2. **The de-facto standardized contract is the Marketplace v1 authority surface**, not an explorer contract. Recurring routes across most Bitcoin indexers: - `GET /live`, `GET /ready` (200/503), `GET /status` or `GET /token-explorer/status` - `GET /v1/checkpoint` (only index-ordinals, index-bitmap, index-names) @@ -14,7 +14,7 @@ Paths inside each section are relative to that repo's root unless prefixed with - `GET /v1/marketplace/protocols/:protocolId/position-source/ready` + `.../position-source/outpoints/:outpoint?heightAtomic=&blockHash=` (stamps, op20, arc20, drops-and-opdrop, runes) - Browse: `GET /v1/marketplace/protocols/:protocolId/{assets|listings|offers|collections|activity}` - Shared schema id (string literal, duplicated per repo): `universe-marketplace-protocol-position-v1`, plus `universe-marketplace-composite-inventory-v1`. -3. **Shared contracts package exists but only backend-apis + wallet consume it**: `@bitcoinuniverse/ecosystem-contracts` v1.1.1 at `D:\universe\backend-apis\backend-apis\packages\ecosystem-contracts` (vendored into wallet as `wallet/vendor/bitcoinuniverse-ecosystem-contracts-1.1.1.tgz`). **No indexer imports it** — indexers duplicate schema ids as string constants and copy-paste the 26-entry `MARKETPLACE_PROTOCOL_IDS` roster (`ordinals, tap, dmt, unat, bitmap, names, dust20, stamps, src20, brc20, runes, runes_native, mezcal, alkanes, op_return, op_names, op_inscriptions, op_drop, drops, tap_doge, drc20, doginals, arc20, rare_sats, cat20, ordex`). +3. **Shared contracts package exists but only backend-apis + wallet consume it**: `@bitcoinuniverse/ecosystem-contracts` v1.1.1 at `D:\universe\backend-apis\backend-apis\packages\ecosystem-contracts` (vendored into wallet as `wallet/vendor/bitcoinuniverse-ecosystem-contracts-1.1.1.tgz`). **No indexer imports it**, indexers duplicate schema ids as string constants and copy-paste the 26-entry `MARKETPLACE_PROTOCOL_IDS` roster (`ordinals, tap, dmt, unat, bitmap, names, dust20, stamps, src20, brc20, runes, runes_native, mezcal, alkanes, op_return, op_names, op_inscriptions, op_drop, drops, tap_doge, drc20, doginals, arc20, rare_sats, cat20, ordex`). 4. **`runes_native` ("Runes (Native)") is a first-class protocol id** across the ecosystem, and its actual adapter implementation lives in **index-runes** (dual authority: `runes` provider-family + `runes_native` protocol-native). Full reference list in the runes_native section at the bottom. 5. **Port collisions in defaults**: 3043 (index-stamps vs index-atomicals ARC20 sidecar), 3044 (index-alkanes vs index-dmt), 3042 (index-runes vs index-cat20), 3012 (index-tap vs index-witness-circles), 3220 (index-names vs index-bitmap), 3000 (index-chainbloom vs backend-apis vs bitcoin-indexer API), 3101 (index-block20; also 3001 index-opdrop vs drops-and-opdrop containers). Ops env files sometimes override (e.g. atomicals-nfts ops uses 3014, opinscriptions ops uses 3016). 6. **No indexer runs under PM2.** PM2 is only used by backend-apis (`ecosystem.config.cjs`, app name `universe`). Indexers run via bare node, Docker/compose, or systemd units. @@ -22,84 +22,84 @@ Paths inside each section are relative to that repo's root unless prefixed with --- -## index-ordinals — `D:\universe\index-ordinals\index-ordinals` +## index-ordinals, `D:\universe\index-ordinals\index-ordinals` 1. **Stack/run**: TypeScript ESM, Node 24.19.0, compiled to `dist/`; `npm start` -> `node ./dist/main.js`. Dockerfile (EXPOSE 3218, non-root). systemd units under `ops/netcup/`, PowerShell ops under `ops/powervps/`. No PM2. Default port **3218** (`.env.example`). 2. **Protocols**: Ordinals inscriptions + rare sats (`sat:`), fail-closed mainnet-only authority backed by local `ord` + Bitcoin Core. Also hosts the **Marketplace v1 composite collateral inventory** that aggregates position sources from every other metaprotocol (config `INDEX_ORDINALS_POSITION_SOURCES_JSON`). 3. **Routes** (`src/server.ts`, manual dispatch): `GET /live`, `/ready`, `/status`, `/v1/checkpoint`; `GET /v1/assets`, `/v1/assets/:assetId`, `/inscriptions/:page`, `/content/:inscriptionId`, `/content-status/:inscriptionId`; `GET /v1/marketplace/inventory/ready`, `GET /v1/marketplace/inventory/outpoints/:outpoint` (composite 29-protocol inventory); marketplace browse/execution under `/v1/marketplace/protocols/{ordinals|rare_sats}/...` incl. `internal/readiness`, `internal/actions` (POST); settlement: `GET /v1/marketplace/settlements/transactions/:txid`, `GET /v1/marketplace/settlements/protocol-positions/transactions/:txid`; `POST /bitcoin` (Core RPC passthrough). No block-height route, no address route. 4. **Explorer contract**: none. Nearest analogues: `/ready`, `/status`, `/v1/checkpoint`, `/v1/marketplace/inventory/outpoints/:outpoint`. -5. **DB**: SQLite via built-in `node:sqlite` (`src/store.ts`), `INDEX_ORDINALS_DATABASE_PATH`. Per-outpoint data: yes — `asset_observation.outpoint` plus marketplace tables in `src/marketplace-migrations.ts` (`marketplace_listing.source_outpoint`, `marketplace_offer.source_outpoint`, spend fences, settlement observations). +5. **DB**: SQLite via built-in `node:sqlite` (`src/store.ts`), `INDEX_ORDINALS_DATABASE_PATH`. Per-outpoint data: yes, `asset_observation.outpoint` plus marketplace tables in `src/marketplace-migrations.ts` (`marketplace_listing.source_outpoint`, `marketplace_offer.source_outpoint`, spend fences, settlement observations). 6. **Auth**: three-tier bearer (`INDEX_ORDINALS_BEARER_TOKEN` read; `X-Marketplace-Execution-Authorization` execution bearer; separate rare-sats execution bearer) + HMAC request signing for internal actions (`INDEX_ORDINALS_MARKETPLACE_HMAC_SECRET`). `/live`, `/ready` unauthenticated. 7. **runes_native**: consumed protocol id (not implemented here). `src/marketplace-inventory-types.ts:13,46`; `src/position-source-client.ts:224-225` maps `runes_native` -> prefix `/v1/marketplace/runes-native/position-source`; `README.md:173`. 8. **Shared contracts**: no package import (deps only bitcoinjs-lib + tiny-secp256k1). Local schemas: `src/marketplace-inventory-types.ts`, `src/settlement.ts`, `src/protocol-position-settlement.ts`; position-source client in `src/position-source-client.ts`. -## index-runes — `D:\universe\index-runes\index-runes` +## index-runes, `D:\universe\index-runes\index-runes` 1. **Stack/run**: plain JS ESM `.mjs`, Node 24.19.0, no build. `npm start` -> `node --env-file-if-exists=.env src/main.mjs`. No Docker, no PM2. Port **3042** (`RUNES_PORT`). 2. **Protocols**: Runes (Hiro Runes API-backed journal + normalized token-explorer feed). Two Marketplace authorities: provider-family **`runes`** and protocol-native **`runes_native`**. 3. **Routes** (`src/server.mjs`): `GET /live`, `/ready`, `/token-explorer/status`, `/token-explorer/runes` (bearer). Dual-prefix marketplace (`/v1/marketplace/runes` -> `runes`, `/v1/marketplace/runes-native` -> `runes_native`): `/ready`, `/status`, `/position-source/ready`, `/position-source/outpoints/:outpoint?heightAtomic=&blockHash=`, `/outpoints/:outpoint`, `/assets`, `/positions?runeId=&owner=`, `/assets/:runeId/accounts/:account`, `/positions/:assetId[/history]`, `POST /settlements/verify`, `POST /offers` (always rejected). Also `GET /v1/marketplace/protocols/runes_native/internal/readiness` and `.../runes_native/{assets|listings|offers|collections|activity}`. Admin: `POST /indexer/hiro/poll`, `POST /indexer/marketplace/observe`. No block/tx routes; mempool: none (coverage declared partial). 4. **Explorer contract**: none. -5. **DB**: SQLite (`node:sqlite`, `src/database.mjs`). Per-outpoint positions: **yes** — `migrations/003_marketplace_authority.sql`: `marketplace_outputs (outpoint PK)`, `marketplace_positions (PK(outpoint, ref))`, replay tables, `marketplace_output_observations`. +5. **DB**: SQLite (`node:sqlite`, `src/database.mjs`). Per-outpoint positions: **yes**, `migrations/003_marketplace_authority.sql`: `marketplace_outputs (outpoint PK)`, `marketplace_positions (PK(outpoint, ref))`, replay tables, `marketplace_output_observations`. 6. **Auth**: bearer `RUNES_SOURCE_BEARER_TOKEN` (feed), per-authority bearers `RUNES_MARKETPLACE_RUNES_BEARER_TOKEN` / `RUNES_MARKETPLACE_RUNES_NATIVE_BEARER_TOKEN`, execution bearer via `x-marketplace-execution-authorization`, admin header `X-Indexer-Admin-Token` (`RUNES_ADMIN_TOKEN`), HMAC cursors. 7. **runes_native**: **implemented here as a separate adapter/authority.** `src/main.mjs:27` instantiates `RunesMarketplaceAuthority(store, config, 'runes_native')`; `src/marketplace/authority.mjs` (schemas `universe-runes-native-marketplace-authority-v1`, `universe-runes-native-marketplace-position-source-v1`; asset id form `:@:`); `src/marketplace/identities.mjs:64`; `src/config.mjs:142-191` (`RUNES_MARKETPLACE_RUNES_NATIVE_*`, requires distinct authority IDs); docs `docs/MARKETPLACE_V1_AUTHORITY.md` §`runes_native` (route prefix `/v1/marketplace/runes-native`; `/v1/marketplace/runes_native` intentionally NOT a route). 8. **Shared contracts**: none imported (zero deps). Schema ids are local constants in `src/marketplace/authority.mjs`. -## index-stamps — `D:\universe\index-stamps\index-stamps` +## index-stamps, `D:\universe\index-stamps\index-stamps` 1. **Stack/run**: JS ESM `.mjs`, Node 24.19.0, no Docker/PM2. `npm start` -> `node src/main.mjs`. Port **3043** (collides with index-atomicals ARC20 sidecar default). 2. **Protocols**: Bitcoin Stamps, SRC-20, SRC-101 (three sources in one process; Stampchain v2 upstream; marketplace also reads Counterparty Core + Bitcoin Core). 3. **Routes** (`src/server.mjs`): `GET /live`, `/status`, `/ready[?protocol=]`; `GET /token-explorer/{stamps|src20|src101}` (per-protocol bearer); `GET /v1/marketplace/protocols/{stamps|src20}/ready`, `.../position-source/ready`, `.../position-source/outpoints/:outpoint?heightAtomic=&blockHash=`; `GET .../stamps/assets/:assetId`, `.../src20/assets/:assetId/accounts/:account`; orders: `POST/GET /v1/marketplace/protocols/stamps/orders[...]`; offers/src20 execution always rejected. Admin `POST /indexer/stampchain/poll` etc. No block/tx routes; mempool: none (partial coverage per protocol). 4. **Explorer contract**: none. -5. **DB**: SQLite (`node:sqlite`). Per-outpoint positions: **no persisted table** — stamps/src20 use account-ledger ownership; outpoint lookups return complete-empty position sets or resolve live via Counterparty/Core (`src/marketplace/authority.mjs`). +5. **DB**: SQLite (`node:sqlite`). Per-outpoint positions: **no persisted table**, stamps/src20 use account-ledger ownership; outpoint lookups return complete-empty position sets or resolve live via Counterparty/Core (`src/marketplace/authority.mjs`). 6. **Auth**: bearer per protocol (`STAMPS|SRC20|SRC101_SOURCE_BEARER_TOKEN`) + `INDEXER_ADMIN_TOKEN` (also Bearer), HMAC cursor secrets per protocol. 7. **runes_native**: none. 8. **Shared contracts**: none; emits `universe-marketplace-protocol-position-v1` as literal; source id `index-stamps-{protocol}-account-ledger-position-source-v1` (`src/marketplace/authority.mjs:104`). -## index-atomicals — `D:\universe\index-atomicals\index-atomicals` +## index-atomicals, `D:\universe\index-atomicals\index-atomicals` 1. **Stack/run**: **Python** (atomicals-electrumx fork) + vendored `bitcointx` + AVM consensus lib. Runs via `run.sh` / systemd (`ops/linux/universe-atomicals-electrumx.service`, `universe-atomicals-token-explorer.service`) and Windows Task Scheduler (`ops/windows/`). ElectrumX services `tcp://0.0.0.0:50010`, `ws://:50020`, `rpc://:8000` (HTTP proxy at `/proxy`); ARC-20 token-explorer sidecar (`electrumx/token_explorer/`) on **3043**. 2. **Protocols**: Atomicals (full chain index, LevelDB) + ARC-20 sidecar; AVM readiness canaries. 3. **Routes** (sidecar, `electrumx/token_explorer/server.py` + `marketplace/service.py`): `GET /live`, `/ready`, `/token-explorer/status`, `/token-explorer/arc20` (bearer); adapter base `/v1/marketplace/protocols/arc20/`: `internal/readiness`, `position-source/ready`, `position-source/outpoints/:outpoint`, browse, `listings/:uuid`, `POST internal/actions`; application base `/api/marketplace/v1/protocols/arc20/`: status/readiness/listings/orders/offers/reservations/settlements + auth challenges + prepare/finalize/broadcast/reconcile POSTs. ElectrumX core speaks Electrum JSON-RPC (has full mempool handling internally: `electrumx/server/mempool.py`); sidecar mempool used only as rejection signal (`testmempoolaccept`). 4. **Explorer contract**: none. -5. **DB**: LevelDB (ElectrumX core) + SQLite sidecar (`ARC20_DATABASE_PATH`, `electrumx/token_explorer/store.py`, migrations 001-004). No persisted per-outpoint position table — resolved live against the ElectrumX proxy. +5. **DB**: LevelDB (ElectrumX core) + SQLite sidecar (`ARC20_DATABASE_PATH`, `electrumx/token_explorer/store.py`, migrations 001-004). No persisted per-outpoint position table, resolved live against the ElectrumX proxy. 6. **Auth**: sidecar bearer `ARC20_SOURCE_BEARER_TOKEN`, admin header `X-Indexer-Admin-Token`, marketplace signed auth challenges/sessions + nonces + idempotency keys; ElectrumX has cost-based rate limiting. 7. **runes_native**: none. 8. **Shared contracts**: none; local schemas under `electrumx/token_explorer/`; docs `docs/arc20-token-explorer.rst`, `docs/arc20-marketplace-v1.rst`. -## index-atomicals-nfts-and-realms — `D:\universe\index-atomicals-nfts-and-realms\index-atomicals-nfts-and-realms` +## index-atomicals-nfts-and-realms, `D:\universe\index-atomicals-nfts-and-realms\index-atomicals-nfts-and-realms` 1. **Stack/run**: JS ESM `.mjs`, Node 24.19.0. Docker (EXPOSE **3003**, healthcheck `/live`) + systemd units in `ops/linux/` (ops env uses port 3014). No PM2. -2. **Protocols**: Atomicals NFTs, Realms, Subrealms — materialized SQLite projection over an Atomicals ElectrumX HTTP proxy (generation/refresh model). Replaces former `index-atomicals-nfts` and `index-atomicals-realms` services. +2. **Protocols**: Atomicals NFTs, Realms, Subrealms, materialized SQLite projection over an Atomicals ElectrumX HTTP proxy (generation/refresh model). Replaces former `index-atomicals-nfts` and `index-atomicals-realms` services. 3. **Routes** (`src/server.mjs`): `GET /live`, `/version`, `/health`, `/ready`, `/metrics`, `/token-explorer/status`, `/token-explorer/{atomicals|realms}` (bearer); status: `GET /v1/atomicals/index/status` (+ `-nfts`/`-realms` aliases), `/v1/atomicals/index/events`; admin POST refresh/rollback. Assets: `GET /v1/{atomicals|atomicals-nfts|atomicals-realms}/assets` (filters `q,address,ownerScript,realm,parent,txid,utxo,block,type,kind,cursor,limit`), `/assets/:atomicalId[/history|/metadata|/holders]`, media route. Realms: `resolve`, `hierarchy`, `subrealms`. **Chain-shaped queries**: `GET /v1/atomicals/transactions/:txid`, `GET /v1/atomicals/blocks/:height`, `GET /v1/atomicals/utxos/:txid/:vout`. No mempool at all. -4. **Explorer contract**: none, but closest structural match (block/tx/utxo routes exist; no checkpoint route — `generationId` header instead; no `addresses/:address/positions`). +4. **Explorer contract**: none, but closest structural match (block/tx/utxo routes exist; no checkpoint route, `generationId` header instead; no `addresses/:address/positions`). 5. **DB**: SQLite (`node:sqlite`, schema in code `src/database.mjs`; FTS5). No dedicated outpoint position table (projection queried by utxo/txid/block snapshots). 6. **Auth**: read surface unauthenticated; bearer only on `/token-explorer/{atomicals|realms}`; admin token for refresh/rollback; HMAC cursors. 7. **runes_native**: none. 8. **Shared contracts**: none. `PROTOCOL-PROVENANCE.json` records provenance locally. -## index-brc20 — `D:\universe\index-brc20\index-brc20` +## index-brc20, `D:\universe\index-brc20\index-brc20` 1. **Stack/run**: JS ESM `.mjs`, Node 24.19.0, zero runtime deps. Dockerfile (EXPOSE **3041**, healthcheck `/live`). `npm start` -> `src/main.mjs`. No PM2. 2. **Protocols**: BRC-20 (canonical decoded ops pushed by external decoder `BRC20_CANONICAL_DECODER_SOURCE_ID`; optional UniSat metadata supplement, default-off). 3. **Routes** (`src/server.mjs`): `GET /live`, `/ready`, `/token-explorer/status`, `/token-explorer/brc20` (bearer); `GET /v1/marketplace/positions/ready`, `GET /v1/marketplace/positions/outpoints/:outpoint` (line 50); `GET /v1/marketplace/authority/status`, `/authority/assets`, `/authority/assets/:assetId/accounts/:account`, `/authority/transferables[...]`; `POST /v1/marketplace/authority/settlements/verify`, `POST .../offers`; ingest `POST /indexer/operations`, `POST /indexer/unisat/poll`. No block/tx/mempool routes. 4. **Explorer contract**: none. -5. **DB**: SQLite (`node:sqlite`). Per-outpoint: partial — `marketplace_transferables` keyed by `location_txid`/`location_vout` (`migrations/003_marketplace_authority.sql:36,63`); balances account-keyed. +5. **DB**: SQLite (`node:sqlite`). Per-outpoint: partial, `marketplace_transferables` keyed by `location_txid`/`location_vout` (`migrations/003_marketplace_authority.sql:36,63`); balances account-keyed. 6. **Auth**: bearer `BRC20_SOURCE_BEARER_TOKEN` (feed) + `BRC20_MARKETPLACE_BEARER_TOKEN` (authority) + admin header `x-indexer-admin-token`; HMAC cursors. -7. **runes_native**: **absent** — the only Marketplace-authority indexer missing it from its protocol-id list (divergence risk vs the 26-id roster). +7. **runes_native**: **absent**, the only Marketplace-authority indexer missing it from its protocol-id list (divergence risk vs the 26-id roster). 8. **Shared contracts**: none; emits `universe-marketplace-protocol-position-v1` literal. -## index-alkanes — `D:\universe\index-alkanes\index-alkanes` +## index-alkanes, `D:\universe\index-alkanes\index-alkanes` 1. **Stack/run**: JS ESM `.mjs`, Node 24.19.0, dep `pg`. `npm start` -> `src/main.mjs`. No Docker/PM2. Port **3044** (collides with index-dmt). -2. **Protocols**: Alkanes — reads the PostgreSQL trace projection of `kungfuflex/alkanes-rs` (`TraceBalanceUtxo`), verifies against Bitcoin Core; ESPO RPC for height/metadata. +2. **Protocols**: Alkanes, reads the PostgreSQL trace projection of `kungfuflex/alkanes-rs` (`TraceBalanceUtxo`), verifies against Bitcoin Core; ESPO RPC for height/metadata. 3. **Routes** (`src/server.mjs`): `GET /live`, `/ready`, `/token-explorer/status`, `/token-explorer/alkanes`; `GET /v1/marketplace/positions/ready`, `GET /v1/marketplace/positions/outpoints/:outpoint`; `/v1/marketplace/protocols/alkanes/`: `internal/readiness`, browse; `/v1/marketplace/alkanes/`: `ready`, `positions/ready`, `status`, `positions[...]`, `outpoints/:outpoint`, `assets/:assetId`, `POST offers`; admin polls. No block/tx/address/mempool routes. 4. **Explorer contract**: none. -5. **DB**: SQLite local store; Postgres is upstream-only. Per-outpoint: **yes** — `migrations/003_marketplace_authority.sql`: `marketplace_outpoints (outpoint PK)`, `marketplace_positions (PK(outpoint, token_id))`, plus `alkane_utxos` in 001. +5. **DB**: SQLite local store; Postgres is upstream-only. Per-outpoint: **yes**, `migrations/003_marketplace_authority.sql`: `marketplace_outpoints (outpoint PK)`, `marketplace_positions (PK(outpoint, token_id))`, plus `alkane_utxos` in 001. 6. **Auth**: bearer (source + marketplace + execution header + admin header); marketplace enable is fail-closed with pinned revisions (`ALKANES_MARKETPLACE_PROTOCOL_REVISION`, `PRODUCER_REVISION`). -7. **runes_native**: consumed id — `src/marketplace/inventory.mjs:8` (frozen protocol list) and `:191` (`protocolId === 'runes' || protocolId === 'runes_native'` coverage counting). +7. **runes_native**: consumed id, `src/marketplace/inventory.mjs:8` (frozen protocol list) and `:191` (`protocolId === 'runes' || protocolId === 'runes_native'` coverage counting). 8. **Shared contracts**: none; source id `index-alkanes-canonical-replay-position-source-v1`. -## index-tap — `D:\universe\index-tap\index-tap` +## index-tap, `D:\universe\index-tap\index-tap` 1. **Stack/run**: TypeScript ESM -> `dist/`; `npm start` -> `node dist/main.js`. Dockerfile (EXPOSE 3012). Port **3012** (collides with index-witness-circles). No PM2. Note: committed `node_modules/` + `dist/`. 2. **Protocols**: TAP (Bitcoin mainnet), sourced from the authenticated Universe ord-tap writer (pinned ord-1.0.5 / commit b8f6ea35...). DMT rows are consumed but delegated to index-dmt. @@ -107,32 +107,32 @@ Paths inside each section are relative to that repo's root unless prefixed with 4. **Explorer contract**: none. 5. **DB**: SQLite (`src/database.ts`). Positions computed live from Ord output + Core txOut (`src/marketplace-authority.ts:524-668`), not persisted; marketplace execution tables created at runtime (`src/marketplace-execution-migrations.ts`: `marketplace_listing.source_outpoint`, `marketplace_offer.source_outpoint`, spend fences). 6. **Auth**: bearer `TOKEN_EXPLORER_BEARER_TOKEN` for authorized GETs, execution header `x-marketplace-execution-authorization`, HMAC cursors. -7. **runes_native**: consumed id — `src/marketplace-authority.ts:61` (protocol-id list). +7. **runes_native**: consumed id, `src/marketplace-authority.ts:61` (protocol-id list). 8. **Shared contracts**: none; literals `universe-marketplace-protocol-position-v1` / `universe-marketplace-composite-inventory-v1`. Marketplace v1 talks to inventory origin `MARKETPLACE_V1_INVENTORY_ORIGIN` (index-ordinals composite, default :3219). -## index-dmt — `D:\universe\index-dmt\index-dmt` +## index-dmt, `D:\universe\index-dmt\index-dmt` 1. **Stack/run**: JS ESM `.mjs`, Node 24.19.0; deps bitcoinjs-lib, socket.io-client. `npm start` -> `src/main.mjs`. No Docker/PM2. Port **3044** (collides with index-alkanes). 2. **Protocols**: DMT (Digital Matter Theory), production input = ord-tap writer + Bitcoin Core; legacy Blockpad/Trac rollback mode. 3. **Routes** (`src/server.mjs`): `GET /live`, `/status`, `/ready`; `GET /dmt/collections`, `/dmt/collections/:collectionId/items`; `GET /v1/marketplace/ready`, `/v1/marketplace/positions/ready`, `/v1/marketplace/positions/outpoints/:outpoint`; `/v1/marketplace/protocols/dmt/`: `internal/readiness`, `POST internal/actions`, browse, `listings/:id`, `reservations/:id`; `GET /v1/marketplace/assets/:assetId`; `GET /token-explorer/dmt`; admin `POST /indexer/dmt/poll`. No block/tx/address routes; mempool: unavailable from canonical providers (partial). 4. **Explorer contract**: none. 5. **DB**: SQLite; `migrations/003_marketplace_authority.sql` carries `outpoint` column on evidence table (partial per-outpoint). -6. **Auth**: bearer only — source, marketplace authority, execution (`x-marketplace-execution-authorization`), admin bearers all distinct. -7. **runes_native**: consumed id — `src/marketplace-authority.mjs:33`; README.md:219 lists "native Runes" as a distinct required protocolCoverage row from the external composite inventory. +6. **Auth**: bearer only, source, marketplace authority, execution (`x-marketplace-execution-authorization`), admin bearers all distinct. +7. **runes_native**: consumed id, `src/marketplace-authority.mjs:33`; README.md:219 lists "native Runes" as a distinct required protocolCoverage row from the external composite inventory. 8. **Shared contracts**: none; literals only. Talks to `ORDINALS_AUTHORITY_BASE_URL` (:3045 in env example) and `DMT_MARKETPLACE_COLLATERAL_INVENTORY_BASE_URL` (:3046). -## index-dust20 — `D:\universe\index-dust20\index-dust20` +## index-dust20, `D:\universe\index-dust20\index-dust20` 1. **Stack/run**: JS ESM `.mjs`, zero deps, Node 24.19.0. `npm start` -> `src/main.mjs`. No Docker/PM2. Port **3102**. 2. **Protocols**: DUST-20 (inscribed deploy/mint; UTXO-flow transfers reconstructed via ordinal FIFO sat tracking). Upstreams: shared Ord 0.29 (`DUST20_ORD_ORIGIN` :8380) + Bitcoin Core verbosity-3. 3. **Routes** (`src/server.mjs`): `GET /live`, `/ready`, `/token-explorer/status`, `/token-explorer/dust20`; `/v1/marketplace/protocols/dust20/`: `internal/actions` (POST), `internal/execution-readiness`, `internal/readiness`, browse; `GET /v1/marketplace/positions/ready`, `/v1/marketplace/positions/outpoints/:outpoint`; `GET /v1/marketplace/authority/ready`, `/v1/marketplace/authority/assets/:assetId`; legacy unauthenticated `GET /dust20/indexer`, `/dust20/checkTicker`, `/dust20/detail/ticker`, `/dust20/indexer/tick`; admin polls. No block/tx/address/mempool routes. 4. **Explorer contract**: none. -5. **DB**: SQLite. Per-outpoint: **yes** — `dust20_allocations` (+ `idx_dust20_allocations_unspent_outpoint`, `spent_by_txid`), `dust20_transition_outputs` with outpoint index. +5. **DB**: SQLite. Per-outpoint: **yes**, `dust20_allocations` (+ `idx_dust20_allocations_unspent_outpoint`, `spent_by_txid`), `dust20_transition_outputs` with outpoint index. 6. **Auth**: bearer source/authority/execution + admin header; legacy `/dust20/*` routes unauthenticated. -7. **runes_native**: consumed id — `src/marketplace-composite-inventory.mjs:66`. +7. **runes_native**: consumed id, `src/marketplace-composite-inventory.mjs:66`. 8. **Shared contracts**: none; literals incl. `universe-dust20-marketplace-authority-v1`. -## index-op20 — `D:\universe\index-op20\index-op20` +## index-op20, `D:\universe\index-op20\index-op20` 1. **Stack/run**: JS ESM `.mjs`; deps bitcoinjs-lib + mysql2. Dockerfile (EXPOSE **3045**, healthcheck `/live`). `npm start` -> `src/main.mjs`. No PM2. 2. **Protocols**: OP-20 (protocol id `op_return`) + separate **OP Names** (`op_names`, gated off by default). Sources: canonical OP-20 MySQL (`tap_wallets` schema, repeatable-read RO snapshots), Bitcoin Core, Esplora outspends (mempool.space API), Bitcoin Universe V4 API oracle. @@ -143,9 +143,9 @@ Paths inside each section are relative to that repo's root unless prefixed with 7. **runes_native**: none. 8. **Shared contracts**: none; sources `index-op20-account-ledger-position-source-v1`, `index-op20-op-names-utxo-position-source-v1`. -## index-opinscriptions — `D:\universe\index-opinscriptions\index-opinscriptions` +## index-opinscriptions, `D:\universe\index-opinscriptions\index-opinscriptions` -1. **Stack/run**: TypeScript; NestJS deps but runtime is raw `node:http` (`dist/indexer/main.js`; no NestFactory call — the Nest module `src/op-inscriptions/` is a legacy compatibility surface, unmounted). Dockerfile (EXPOSE 3000 9091 9092) + systemd `ops/systemd/universe-op-inscriptions-indexer.service` (+ mempool/verifier SSH tunnels). Three listeners: probe **9091** (`/live /ready /metrics`), canonical read API **3000** (ops env 3016), marketplace authority **9092**. No PM2. +1. **Stack/run**: TypeScript; NestJS deps but runtime is raw `node:http` (`dist/indexer/main.js`; no NestFactory call, the Nest module `src/op-inscriptions/` is a legacy compatibility surface, unmounted). Dockerfile (EXPOSE 3000 9091 9092) + systemd `ops/systemd/universe-op-inscriptions-indexer.service` (+ mempool/verifier SSH tunnels). Three listeners: probe **9091** (`/live /ready /metrics`), canonical read API **3000** (ops env 3016), marketplace authority **9092**. No PM2. 2. **Protocols**: OP Inscriptions (`op_inscriptions`), canonical OP_RETURN inscription indexer extracted from universe-backend; dual-provider verification (mempool API + independent verifier / private Core checkpoint authority). 3. **Routes**: probe: `GET /live`, `/ready`, `/metrics`. Read API (`src/indexer/canonical-read.server.ts`, GET/HEAD, no auth): `GET /live`, `/ready` (alias `/api/op-inscriptions/health`), `GET /api/op-inscriptions/inscriptions[ /random]` (+ underscore aliases). Marketplace (`src/marketplace/marketplace-http.server.ts`, bearer): `GET /v1/marketplace/positions/ready`, `GET /v1/marketplace/authority/status`, `GET /v1/marketplace/authority/assets[/:assetId[/history]]`, `GET /v1/marketplace/positions/outpoints/:txid::vout` (line 537), `POST /v1/marketplace/authority/settlements/verify`, `POST .../actions/observe` & `.../offers` (fail 409 by design). Mempool: source-level only (`src/indexer/mempool-chain.source.ts`), no HTTP route. @@ -155,106 +155,106 @@ Paths inside each section are relative to that repo's root unless prefixed with 7. **runes_native**: none. 8. **Shared contracts**: none; local constants `OP_INSCRIPTIONS_MARKETPLACE_POSITION_SCHEMA` etc. in `src/common/constants.ts`. -## index-drops-and-opdrop — `D:\universe\index-drops-and-opdrop\index-drops-and-opdrop` +## index-drops-and-opdrop, `D:\universe\index-drops-and-opdrop\index-drops-and-opdrop` 1. **Stack/run**: TypeScript + NestJS 11 + TypeORM. Dockerfile (EXPOSE 3001) + `compose.yml` (host bind `${DROPS_OPDROP_BIND_PORT:-3015}:3001`, MySQL 8.4 + Redis) + systemd `ops/linux/universe-drops-opdrop.service`. Roles: `SERVICE_ROLE=all|api|scanner` (advisory-lock single writer). CLI `drops` + library exports (`./drops`, `./drops/client`, `./drops/protocol`, `./drops/pacts`). No PM2. **The canonical route list is committed at `api-list.txt` (110 routes).** 2. **Protocols**: op-drop (BIP-110 `$DROP` fungible tokens + trading desk) and Drops (inscription/artifact indexer + `/drops` HTML gallery) over one confirmed-chain scan. -3. **Routes** (see `api-list.txt`): health `GET /live|/health|/ready|/version|/metrics` (+ `/op-drop/*` aliases), `GET /drops/health`, `/drops/status`; op-drop data: tokens, `balances/:address`, transfers, events, `provisional` (+ `POST provisional/track` — pending/mempool lifecycle `mempool -> M of N -> finalized`), `indexer/status|scan|replay`; trading `POST /op-drop/trading/listings[...]` with authorization payloads; token-explorer feeds `GET /{op-drop|drops}/token-explorer[ /status]` (bearer); Marketplace v1 mounted under BOTH `op-drop/marketplace/v1` and `drops/marketplace/v1` (ready, status, assets, positions[...], `chain/prevouts/:txid/:vout`, listings/offers/intents/actions/history); **generic position source**: `GET /v1/marketplace/protocols/:protocolId/position-source/ready` and `.../position-source/outpoints/:outpoint?heightAtomic=&blockHash=` (`src/marketplace/marketplace-v1-authority.controller.ts:724,738`), protocols `op_drop` and `drops`; custody admin `/drops-and-opdrop/drops/custody/admin/*`; `GET /openapi.json`, `/docs`. +3. **Routes** (see `api-list.txt`): health `GET /live|/health|/ready|/version|/metrics` (+ `/op-drop/*` aliases), `GET /drops/health`, `/drops/status`; op-drop data: tokens, `balances/:address`, transfers, events, `provisional` (+ `POST provisional/track`, pending/mempool lifecycle `mempool -> M of N -> finalized`), `indexer/status|scan|replay`; trading `POST /op-drop/trading/listings[...]` with authorization payloads; token-explorer feeds `GET /{op-drop|drops}/token-explorer[ /status]` (bearer); Marketplace v1 mounted under BOTH `op-drop/marketplace/v1` and `drops/marketplace/v1` (ready, status, assets, positions[...], `chain/prevouts/:txid/:vout`, listings/offers/intents/actions/history); **generic position source**: `GET /v1/marketplace/protocols/:protocolId/position-source/ready` and `.../position-source/outpoints/:outpoint?heightAtomic=&blockHash=` (`src/marketplace/marketplace-v1-authority.controller.ts:724,738`), protocols `op_drop` and `drops`; custody admin `/drops-and-opdrop/drops/custody/admin/*`; `GET /openapi.json`, `/docs`. 4. **Explorer contract**: none (`/token-explorer/*` is a feed contract, different shape). -5. **DB**: MySQL 8.4 (TypeORM); Redis for rate limiting. Per-outpoint: **yes** — `marketplace_v1_tracked_positions` (idx protocol,txid,vout), `drops_marketplace_listings` (unique outpoint), spend fences, outpoint-keyed custody tables; op-drop transfers unique on `(network, anchorTxid, anchorVout)`. +5. **DB**: MySQL 8.4 (TypeORM); Redis for rate limiting. Per-outpoint: **yes**, `marketplace_v1_tracked_positions` (idx protocol,txid,vout), `drops_marketplace_listings` (unique outpoint), spend fences, outpoint-keyed custody tables; op-drop transfers unique on `(network, anchorTxid, anchorVout)`. 6. **Auth**: per-protocol bearer tokens (`OP_DROP_MARKETPLACE_V1_BEARER_TOKEN`, `DROPS_MARKETPLACE_V1_BEARER_TOKEN` + execution + inventory bearers), token-explorer bearer, service token `DROPS_OPDROP_INDEXER_SERVICE_TOKEN` (trusted-backend bucket), admin/ingest tokens, BIP322 signatures for trading writes, Redis rate limiting. -7. **runes_native**: consumed id — `src/drops/drops-output-inventory.client.ts:26` in the 26-id `COMPLETE_MARKETPLACE_PROTOCOL_IDS` allowlist for the index-ordinals composite output-inventory client. +7. **runes_native**: consumed id, `src/drops/drops-output-inventory.client.ts:26` in the 26-id `COMPLETE_MARKETPLACE_PROTOCOL_IDS` allowlist for the index-ordinals composite output-inventory client. 8. **Shared contracts**: none imported; local `src/marketplace/marketplace-v1.route.ts`, contract specs `src/marketplace/marketplace-v1.contract.spec.ts`. -## index-unat — `D:\universe\index-unat\index-unat` +## index-unat, `D:\universe\index-unat\index-unat` 1. **Stack/run**: JS ESM `.mjs`; deps @noble/curves, bitcoinjs-lib, mysql2, re2-wasm, unicode-segmenter. Dockerfile (EXPOSE **3217**). `npm start` -> `src/main.mjs`; canonical seed via `scripts/seed-canonical.mjs`. No PM2. 2. **Protocols**: UNAT (fail-closed Marketplace v1 authority + position source; canonical MySQL seed -> incremental Ord/Core replay -> dynamic position proof; TAP writer mirror attestation). 3. **Routes** (`src/server.mjs`): `GET /live`, `/status`, `/ready` (public); `GET /unat/collections[...]` (marketplace bearer); `POST /indexer/unat/poll`, `GET /v1/internal/replay/status` (admin); `GET /v1/marketplace/ready`; `GET /v1/marketplace/protocols/unat/internal/readiness` (dual bearer), browse, `listings/:id`, `reservations/:id`, `POST internal/actions`; `GET /v1/marketplace/positions/ready`, `GET /v1/marketplace/positions/outpoints/:outpoint?heightAtomic=&blockHash=`; `GET /v1/marketplace/assets/:assetId`. No block/tx/address/mempool routes. 4. **Explorer contract**: none ("explorer" absent from repo). -5. **DB**: SQLite x2 (canonical + marketplace execution journal); MySQL only as one-shot RO seed source. Per-outpoint: yes — `unat_tick_claims.current_outpoint`, `marketplace_evidence.outpoint` (`migrations/001_initial.sql:146,257`). -6. **Auth**: bearers — `UNAT_MARKETPLACE_BEARER_TOKEN`, execution via `X-Marketplace-Execution-Authorization`, `UNAT_ADMIN_BEARER_TOKEN`; outbound bearers for ordinals authority/collateral inventory/TAP writer export. -7. **runes_native**: consumed id — `src/clients.mjs:12` (26-id list for composite/collateral inventory client validation). +5. **DB**: SQLite x2 (canonical + marketplace execution journal); MySQL only as one-shot RO seed source. Per-outpoint: yes, `unat_tick_claims.current_outpoint`, `marketplace_evidence.outpoint` (`migrations/001_initial.sql:146,257`). +6. **Auth**: bearers, `UNAT_MARKETPLACE_BEARER_TOKEN`, execution via `X-Marketplace-Execution-Authorization`, `UNAT_ADMIN_BEARER_TOKEN`; outbound bearers for ordinals authority/collateral inventory/TAP writer export. +7. **runes_native**: consumed id, `src/clients.mjs:12` (26-id list for composite/collateral inventory client validation). 8. **Shared contracts**: none; source ids like `index-unat-complete-position-source-v1` (`src/authority.mjs:247`). -## index-bitmap — `D:\universe\index-bitmap\index-bitmap` +## index-bitmap, `D:\universe\index-bitmap\index-bitmap` 1. **Stack/run**: JS ESM `.mjs`, leanest repo (no Docker, no .env.example, no ops). `npm start` -> `node ./src/main.mjs`. Port **3220** (`BITMAP_PORT` default; collides with index-names). No PM2. 2. **Protocols**: Bitmap districts (`{height}.bitmap`, activation 767430, OPI-pinned rules; parcels rejected). Evidence: Ord + Bitcoin Core + index-ordinals composite inventory. 3. **Routes** (`src/server.mjs`): `GET /live`, `/ready` (unauthenticated); bearer: `GET /v1/checkpoint`, `/v1/indexer/progress`, `/v1/marketplace/assets/:inscriptionId`, `/v1/marketplace/positions/ready`, `/v1/marketplace/positions/outpoints/:outpoint?heightAtomic=&blockHash=`, `/v1/marketplace/protocols/bitmap/` browse + `internal/readiness` + `POST internal/actions` (dual bearer). Rate limited (`BITMAP_RATE_LIMIT_PER_MINUTE`). No block/tx/address/mempool routes. 4. **Explorer contract**: none. -5. **DB**: SQLite x2 (canonical `migrations/001_bitmap_authority.sql`: `bitmap_blocks/candidates/claims/authority_state`; marketplace execution journal). No persisted outpoint column — positions computed live (Ord satpoint + Core gettxout + composite inventory). +5. **DB**: SQLite x2 (canonical `migrations/001_bitmap_authority.sql`: `bitmap_blocks/candidates/claims/authority_state`; marketplace execution journal). No persisted outpoint column, positions computed live (Ord satpoint + Core gettxout + composite inventory). 6. **Auth**: bearer `BITMAP_AUTHORITY_BEARER_TOKEN` on all `/v1/*`; execution bearer header; outbound `BITMAP_ORDINALS_COMPOSITE_BEARER_TOKEN`. -7. **runes_native**: consumed id — `src/authority.mjs:33` (26-id list; context: `POSITION_SCHEMA='universe-marketplace-protocol-position-v1'`, `COMPOSITE_INVENTORY_SOURCE='index-ordinals-composite-inventory-v1'`). +7. **runes_native**: consumed id, `src/authority.mjs:33` (26-id list; context: `POSITION_SCHEMA='universe-marketplace-protocol-position-v1'`, `COMPOSITE_INVENTORY_SOURCE='index-ordinals-composite-inventory-v1'`). 8. **Shared contracts**: none; inline constants `src/authority.mjs:15-20`. -## index-names — `D:\universe\index-names\index-names` +## index-names, `D:\universe\index-names\index-names` 1. **Stack/run**: JS ESM `.mjs`; deps bitcoinjs-lib, json5, tiny-secp256k1. `npm start` -> `node ./src/main.mjs`. No Docker/PM2/.env.example. Port **3220** default (`NAMES_PORT`; collides with index-bitmap). -2. **Protocols**: Sats Names System (SNS) — Ordinals-based `names` protocol (OPI-pinned first-write rules), fail-closed authority (`NAMES_MARKETPLACE_V1_AUTHORITY_ENABLED`). +2. **Protocols**: Sats Names System (SNS), Ordinals-based `names` protocol (OPI-pinned first-write rules), fail-closed authority (`NAMES_MARKETPLACE_V1_AUTHORITY_ENABLED`). 3. **Routes** (`src/server.mjs`): `GET /live` (open); bearer: `GET /ready`, `/v1/indexer/progress`, `/v1/checkpoint`, `/v1/marketplace/positions/ready`, `/v1/marketplace/positions/outpoints/:outpoint?heightAtomic=&blockHash=`, `/v1/marketplace/assets/:inscriptionId`; execution mode adds `/v1/marketplace/protocols/names/` internal readiness/actions + browse + listings/reservations. No block/tx/address/mempool routes. 4. **Explorer contract**: none. -5. **DB**: SQLite (`node:sqlite`), `migrations/001_names_authority.sql` (`names_blocks/candidates/claims/namespace_claims/authority_state`); no outpoint column — positions resolved live vs ord + Core; separate marketplace DB path. +5. **DB**: SQLite (`node:sqlite`), `migrations/001_names_authority.sql` (`names_blocks/candidates/claims/namespace_claims/authority_state`); no outpoint column, positions resolved live vs ord + Core; separate marketplace DB path. 6. **Auth**: bearer `NAMES_AUTHORITY_BEARER_TOKEN` + execution bearer header; rate limiting. -7. **runes_native**: consumed id — `src/authority.mjs:24` (26-id `MARKETPLACE_PROTOCOL_IDS`); test mirror `test/fixtures.mjs:20`. +7. **runes_native**: consumed id, `src/authority.mjs:24` (26-id `MARKETPLACE_PROTOCOL_IDS`); test mirror `test/fixtures.mjs:20`. 8. **Shared contracts**: none; schema id literals `universe-marketplace-protocol-position-v1`, `index-names-position-inventory-v1` (`src/authority.mjs:19-20`). -## index-block20 — `D:\universe\index-block20\index-block20` +## index-block20, `D:\universe\index-block20\index-block20` 1. **Stack/run**: JS ESM `.mjs`; dep `pg` (legacy Hiro adapter only). `npm start` -> `src/main.mjs`; separate `npm run start:rpc-proxy` (`src/bitcoin-rpc-proxy.mjs`, default 8333 -> upstream 8332). No Docker/PM2. Port **3101**. 2. **Protocols**: BLOCK-20 (Ordinals-inscription token protocol; ord adapter at :8380 + Bitcoin Core; mutually-exclusive legacy Hiro Postgres adapter). 3. **Routes** (`src/server.mjs`): `GET /live`, `/ready`, `/token-explorer/status` (open); `GET /token-explorer/block20` (bearer); legacy `GET /block20/indexer` (open); admin `POST /indexer/operations`, `/indexer/{source|hiro|ord}/poll`. **No marketplace/position-source surface at all.** No block/tx/outpoint/address/mempool routes. 4. **Explorer contract**: none. -5. **DB**: SQLite; tables incl. `block20_transfer_intents`, `block20_ord_locations` (inscription-id keyed). **No outpoint column anywhere** — no per-outpoint positions. +5. **DB**: SQLite; tables incl. `block20_transfer_intents`, `block20_ord_locations` (inscription-id keyed). **No outpoint column anywhere**, no per-outpoint positions. 6. **Auth**: bearer `BLOCK20_SOURCE_BEARER_TOKEN` (feed only) + admin header `X-Indexer-Admin-Token`; HMAC cursors. 7. **runes_native**: none. 8. **Shared contracts**: none; `scripts/check-inscribe-contract.mjs` validates its own feed shape. -## index-mezcal — `D:\universe\index-mezcal\index-mezcal` +## index-mezcal, `D:\universe\index-mezcal\index-mezcal` 1. **Stack/run**: TypeScript ESM -> `dist/`; deps @cmdcode/tapscript, pg. Dockerfile (EXPOSE **3014**, healthcheck `/live`). `npm start` -> `node dist/main.js`. No PM2. 2. **Protocols**: Mezcal (native token protocol). Mirrors canonical bitapeslabs Mezcal Postgres (pinned schema `bitapeslabs-mezcal-postgres-v1`, revision-pinned) + Bitcoin Core verification. 3. **Routes** (`src/server.ts`): `GET /live`, `/ready` (open); `GET /status`, `/token-explorer/mezcal` (bearer); `GET /v1/marketplace/positions/ready`, `/v1/marketplace/positions/outpoints/:outpoint?heightAtomic=&blockHash=` (marketplace bearer, schema `universe-marketplace-protocol-position-v1`); `/v1/marketplace/protocols/mezcal/`: `internal/readiness`, browse; `/v1/marketplace/mezcal/`: `ready`, `status`, `assets`, `positions?tokenId=&owner=`; all write verbs recognized and rejected as unsupported. No block/tx/address/mempool routes. 4. **Explorer contract**: none. -5. **DB**: SQLite local (pg is upstream-only). Per-outpoint: **yes** — `migrations/004_marketplace_v1_authority.sql`: `marketplace_positions (UNIQUE(outpoint, token_id))`, snapshot positions, append-only observations (update/delete triggers ABORT), checkpoint tables scoped `mezcal-utxo-positions`. +5. **DB**: SQLite local (pg is upstream-only). Per-outpoint: **yes**, `migrations/004_marketplace_v1_authority.sql`: `marketplace_positions (UNIQUE(outpoint, token_id))`, snapshot positions, append-only observations (update/delete triggers ABORT), checkpoint tables scoped `mezcal-utxo-positions`. 6. **Auth**: bearer x3 (`TOKEN_EXPLORER_BEARER_TOKEN`, `MEZCAL_MARKETPLACE_BEARER_TOKEN`, execution bearer header); fail-closed enable flag. -7. **runes_native**: **strong reference** — `contracts/universe-marketplace-native-token-v1.json:4` `"protocolIds": ["runes_native", "mezcal", "alkanes"]` (first-class shared native-token contract: consumerClass `MezcalMarketplaceV1AssetResolver`, 16 `protocolOutpointFields`), duplicated in `scripts/check-marketplace-contract.mjs:34` and enforced by `npm run verify`. +7. **runes_native**: **strong reference**, `contracts/universe-marketplace-native-token-v1.json:4` `"protocolIds": ["runes_native", "mezcal", "alkanes"]` (first-class shared native-token contract: consumerClass `MezcalMarketplaceV1AssetResolver`, 16 `protocolOutpointFields`), duplicated in `scripts/check-marketplace-contract.mjs:34` and enforced by `npm run verify`. 8. **Shared contracts**: vendored local JSON contract (above) + literals; source `index-mezcal-canonical-utxo-position-source-v1` (`src/marketplace.ts:375`). -## index-chainbloom — `D:\universe\index-chainbloom\index-chainbloom` +## index-chainbloom, `D:\universe\index-chainbloom\index-chainbloom` 1. **Stack/run**: TypeScript + NestJS 11 + TypeORM + Socket.IO + ZeroMQ + prom-client. Dockerfile (EXPOSE 3000) + hardened `docker-compose.yml` (pinned mysql:8.4, config-check + migrate one-shots). Port **3000** loopback (`CHAINBLOOM_BIND_*`). Swagger `/docs`, `/docs-json`; generated client in `generated/`. No PM2 (systemd wrapper mentioned in docs/operations.md). backend-apis expects it at `CHAINBLOOM_INDEXER_URL=http://127.0.0.1:3011`. 2. **Protocols**: ChainBloom CBLM v1 (fixed-root UTXO relay; worlds/lanes/events), direct Bitcoin Core RPC + ZMQ, provisional mempool ingest, single-leader lease. 3. **Routes**: `GET /health`, `/ready`, `/metrics`; `/v1/chainbloom/`: `status`, `worlds[...]` (events/graph/lanes), `lanes`, **`lanes/by-outpoint/:txid/:vout`**, `lanes/:worldId/:laneNo`, `scripts/:scriptHash/holdings`, **`address/:address/holdings`**, `events`, **`events/:txid`**, `graph`, `render/:worldId[/svg]`, `fees`, `search`, `stats`, **`mempool`**; admin POST `sync|verify|repair|reindex`; WS namespace `/chainbloom` (block/event/mempool/replacement/reorg). No block-by-height route. 4. **Explorer contract**: none (richest explorer-shaped surface, but under `/v1/chainbloom/*`). -5. **DB**: **MySQL 8.4** (TypeORM migrations in `src/database/migrations/`). Per-outpoint: yes — `lanes.current_carrier_txid/vout` UNIQUE, `transaction_inputs/outputs`, `mempool_inputs.outpoint`. +5. **DB**: **MySQL 8.4** (TypeORM migrations in `src/database/migrations/`). Per-outpoint: yes, `lanes.current_carrier_txid/vout` UNIQUE, `transaction_inputs/outputs`, `mempool_inputs.outpoint`. 6. **Auth**: public reads unauthenticated (rate limits + CORS allowlist + Helmet); admin via `X-Api-Key` or `Authorization: Bearer` vs `ADMIN_API_KEYS` (503 fail-closed if unset). 7. **runes_native**: none. 8. **Shared contracts**: none; local `src/api/status-contract.ts`; `SOURCE-PROVENANCE.json` + pinned `CHAINBLOOM_SOURCE_REVISION`. Protocol parser behind `src/protocol/index.ts` awaiting future `@bitcoin-universe/chainbloom` package. -## index-patina — `D:\universe\index-patina\index-patina` +## index-patina, `D:\universe\index-patina\index-patina` 1. **Stack/run**: TypeScript ESM; CLI bin `index-patina` (`serve`/`sync`). Dockerfile + compose (EXPOSE **4180**; optional regtest Core service). Deps: better-sqlite3 + vendored `@bitcoinuniverse/patina` 1.1.0 tarball (SHA-pinned via `SOURCE-PROVENANCE.json`, `scripts/verify-vendor.mjs`). Mainnet fail-closed (`PATINA_MAINNET_AUTHORIZED` + 2-approver deployment record). backend-apis expects `PATINA_INDEXER_URL=http://127.0.0.1:3013` (differs from repo default 4180). 2. **Protocols**: PATINA (Bitcoin artifact/carrier protocol; commit-reveal, rings, epochs/census, ALIVE/RELIC lifecycle). Core RPC (txindex=1) incl. mempool overlay. 3. **Routes** (`src/api.ts`, base `/patina`): `GET /patina/status`, `/window`, `/artifacts[?status=&address=]`, `/artifacts/:id[/card]`, **`/addresses/:address/holdings`**, **`/carriers/:txid/:vout`** (outpoint), `/census/current`, `/census/:epoch`, `/museum`, `/leaderboard`, `/shatter`, `/invalid-events`, `/stats`, **`/mempool`**, **`POST /patina/safety/outpoints`** (batch, <=500); `GET /health`, `/ready`, `/metrics` (bare + prefixed); `/openapi.json`. No block-by-height or tx-by-txid routes. 4. **Explorer contract**: none (closest in shape; prefix `/patina`, forms differ). -5. **DB**: SQLite via **better-sqlite3** (only repo not on `node:sqlite`); code-defined schema `src/migrations.ts`. Per-outpoint: **yes** — `carriers (PK(txid,vout))` + `carrier_artifacts (PK(carrier_txid,carrier_vout,artifact_id))`; `checkpoints`, `block_undo`, mempool tables. +5. **DB**: SQLite via **better-sqlite3** (only repo not on `node:sqlite`); code-defined schema `src/migrations.ts`. Per-outpoint: **yes**, `carriers (PK(txid,vout))` + `carrier_artifacts (PK(carrier_txid,carrier_vout,artifact_id))`; `checkpoints`, `block_undo`, mempool tables. 6. **Auth**: **none** (fully public read API; rate limiting 120/min, loopback bind, optional single CORS origin). 7. **runes_native**: none. -8. **Shared contracts**: imports vendored `@bitcoinuniverse/patina` (protocol spec package — not an ecosystem contracts package; no position-source/checkpoint/settlement schemas). +8. **Shared contracts**: imports vendored `@bitcoinuniverse/patina` (protocol spec package, not an ecosystem contracts package; no position-source/checkpoint/settlement schemas). -## index-witness-circles — `D:\universe\index-witness-circles\index-witness-circles` +## index-witness-circles, `D:\universe\index-witness-circles\index-witness-circles` 1. **Stack/run**: TypeScript + NestJS 11 + TypeORM + Socket.IO. Dockerfile (EXPOSE **3012**) + docker-compose (mysql:8.4 + migrate one-shot). Port 3012 (collides with index-tap default). Swagger `/docs`. No PM2. backend-apis: `WITNESS_INDEXER_URL=http://127.0.0.1:3012`. 2. **Protocols**: Witness Circles `WITC` (42-byte OP_RETURN PUSH40 marker; CIRCLE only). Bitcoin Core RPC + ZMQ; provisional mempool state. 3. **Routes**: `GET /health`, `/ready`, `/metrics`; `/v1/witness/`: `status`, `circles[/:txid]`, **`transactions/:txid`**, `lineages[...]`, **`shards/:txid/:vout`** (outpoint), **`POST safety/outpoints`**, **`addresses/:address/holdings`**, `addresses/:address/activity`, **`mempool[/:txid]`**, `graph`, `invalid-events`, `search`, `trending`, `stats`, `fees`, `POST validate`; admin POST `sync|verify|verify-core|repair|reindex[-range]`; WS gateway. No block-by-height route. 4. **Explorer contract**: none. -5. **DB**: MySQL 8 (entities `src/database/entities.ts`); per-outpoint: `wc_shards PK(txid, vout)` (no fungible amounts — protocol has no token model). +5. **DB**: MySQL 8 (entities `src/database/entities.ts`); per-outpoint: `wc_shards PK(txid, vout)` (no fungible amounts, protocol has no token model). 6. **Auth**: public reads unauthenticated (throttler + CORS); admin bearer (`ADMIN_API_KEYS`, digest + timingSafeEqual). 7. **runes_native**: none. 8. **Shared contracts**: none. -## index-tandem — `D:\universe\index-tandem\index-tandem` +## index-tandem, `D:\universe\index-tandem\index-tandem` 1. **Stack/run**: TypeScript ESM + NestJS 11 + TypeORM; Biome/Vitest; docs site under `site/`. Dockerfile (EXPOSE **3021**) + compose.yaml. Vendored `@bitcoinuniverse/tandem` 0.1.0 tarball. backend-apis: `TANDEM_INDEXER_URL=http://127.0.0.1:3021` (commented out by default). No PM2. 2. **Protocols**: Tandem pipeline A (2-of-2 shared 20,000-sat Bitcoin object; chapters/key rotations); cross-checked against external pipeline B (`PIPELINE_B_BASE_URL`) with signed agreement tuples; mainnet gated by `TANDEM_VERIFIED_MAINNET_ENABLED`. @@ -265,9 +265,9 @@ Paths inside each section are relative to that repo's root unless prefixed with 7. **runes_native**: none. 8. **Shared contracts**: none (vendored protocol tarball only). -## index-cat20 — `D:\universe\index-cat20\index-cat20` +## index-cat20, `D:\universe\index-cat20\index-cat20` -1. **Stack/run**: JS ESM `.mjs`; dep `pg`. Dockerfile (EXPOSE **3042** — collides with index-runes; healthcheck `/live`). `npm start` -> `src/main.mjs`. No PM2. +1. **Stack/run**: JS ESM `.mjs`; dep `pg`. Dockerfile (EXPOSE **3042**, collides with index-runes; healthcheck `/live`). `npm start` -> `src/main.mjs`. No PM2. 2. **Protocols**: CAT-20 on **Fractal Bitcoin** (`fractal-mainnet`); polls the canonical `CATProtocol/cat-token-box` tracker Postgres. 3. **Routes** (`src/server.mjs`): `GET /live`, `/ready`, `/token-explorer/status` (open); `GET /token-explorer/cat20` (bearer); `/v1/marketplace/protocols/cat20/`: `internal/readiness` (dual bearer), browse `{assets|listings|offers|collections|activity}` (fractal-testnet only via `CAT20_MARKETPLACE_BROWSE_ENABLED`); admin `POST /indexer/operations`, `/indexer/cat-tracker/poll`. **No position-source/outpoint routes.** No block/tx/address/mempool routes. 4. **Explorer contract**: none. @@ -276,32 +276,32 @@ Paths inside each section are relative to that repo's root unless prefixed with 7. **runes_native**: none. 8. **Shared contracts**: none. -## index-doge-tap — `D:\universe\index-doge-tap\index-doge-tap` +## index-doge-tap, `D:\universe\index-doge-tap\index-doge-tap` 1. **Stack/run**: TypeScript ESM -> dist; deps trac-tap-reader 0.13.49-beta (Hypercore/Hyperbee) + tiny-secp256k1; `dependencies:prepare` (esbuild rebuild + patch-package) required before start. Dockerfile (EXPOSE **3013**). Optional TLS. No PM2. -2. **Protocols**: Dogecoin TAP (`doge-tap`, `dogecoin-mainnet`, pinned channel/reader identity). Feature-flagged Dogecoin Marketplace v1 subsystem (DRC-20/Doginals/TAP-Doge authority builders) — all off in `.env.example`. +2. **Protocols**: Dogecoin TAP (`doge-tap`, `dogecoin-mainnet`, pinned channel/reader identity). Feature-flagged Dogecoin Marketplace v1 subsystem (DRC-20/Doginals/TAP-Doge authority builders), all off in `.env.example`. 3. **Routes** (`src/server.ts`): `GET /live`, `/ready` (open); `GET /status`, `/token-explorer/doge-tap` (bearer); `GET /reader/:method[...]` (legacy gateway, IP-allowlisted, off by default); `GET /v1/marketplace/checkpoint?protocol=&network=dogecoin-mainnet`; marketplace public `/marketplace/v1/...` (listings/assets/offers/intents/settlements/auth challenges) and internal `/v1/marketplace/protocols/:protocol/internal/{actions,funding,wallet,readiness,reservations}`. No block/tx/outpoint/address/mempool routes. 4. **Explorer contract**: none. -5. **DB**: SQLite (`node:sqlite`), migrations 001-007 incl. marketplace tables; balances address-keyed — no per-outpoint positions (outpoints only inside marketplace funding tables). +5. **DB**: SQLite (`node:sqlite`), migrations 001-007 incl. marketplace tables; balances address-keyed, no per-outpoint positions (outpoints only inside marketplace funding tables). 6. **Auth**: bearer `TOKEN_EXPLORER_BEARER_TOKEN` (timingSafeEqual); reader-gateway IP allowlist + TLS; marketplace internal bearer + HMAC-signed headers with replay window (`src/marketplace/internal-auth.ts`); HMAC cursors. 7. **runes_native**: none. 8. **Shared contracts**: none. -## index-zcash-metaprotocols — `D:\universe\index-zcash-metaprotocols\index-zcash-metaprotocols` +## index-zcash-metaprotocols, `D:\universe\index-zcash-metaprotocols\index-zcash-metaprotocols` 1. **Stack/run**: JS ESM `.mjs` + Rust workspace (`rust/zrunes-codec`). systemd deployment (`ops/universe-index-zcash-metaprotocols.service`); Zebra runs as container. Single HTTP server, port **8790**. No Docker for the indexer itself, no PM2. 2. **Protocols**: Zcash metaprotocols over Zebra JSON-RPC: Zerdinals (legacy families + Universe v1), ZRunes (raw journal + projection), legacy token journals (zrc20/zrc721), collections, transparent ownership; one scan, many projections. 3. **Routes**: health `GET /live`, `/ready`, `/status` (`src/health/server.mjs`); API under `/zcash-metaprotocols/` (`src/api/server.mjs`): `status`, `inscriptions[...]`, **`addresses/:address/{inscriptions|zrunes|utxos}`**, **`blocks/:height`**, **`transactions/:txid`**, `zrunes[...]` (holders/activity), `collections[...]`, `activity`, `search`, **`POST outpoints/assets`** (batch <=64 outpoints), `POST transactions/broadcast`. Exposed through Universe gateway allowlist (backend-apis `/zcash_indexer/*` proxy). No mempool route (confirmed-only). Every response carries `schemaVersion` (`zcash-metaprotocols-api-v1`), `network`, `checkpoint`. 4. **Explorer contract**: none, but the closest structural match (ready/status+checkpoint/blocks/transactions/outpoints batch; differences: batch POST outpoints, no `/summary`, address positions split per protocol). -5. **DB**: **MySQL 8.4** (`mysql2/promise`, migrations 0001-0003). Per-outpoint positions: **yes** — `zrune_balances PK(outpoint, zrune_id)`, `zrune_spent_balances`, `zrune_commitments (outpoint PK)`, `inscription_outpoints (outpoint PK)`. -6. **Auth**: none in-process — delegated to Universe gateway allowlist (gateway currently forwards GET/HEAD only; the two POST routes need gateway allowances). +5. **DB**: **MySQL 8.4** (`mysql2/promise`, migrations 0001-0003). Per-outpoint positions: **yes**, `zrune_balances PK(outpoint, zrune_id)`, `zrune_spent_balances`, `zrune_commitments (outpoint PK)`, `inscription_outpoints (outpoint PK)`. +6. **Auth**: none in-process, delegated to Universe gateway allowlist (gateway currently forwards GET/HEAD only; the two POST routes need gateway allowances). 7. **runes_native**: none (protocol is "ZRunes", never labelled native runes). 8. **Shared contracts**: none; API shape pinned by consumer repos by convention (noted in `src/api/server.mjs` header). -## bitcoin-indexer — `D:\universe\bitcoin-indexer\bitcoin-indexer` +## bitcoin-indexer, `D:\universe\bitcoin-indexer\bitcoin-indexer` 1. **Stack/run**: Rust cargo workspace (fork of Hiro `bitcoin-indexer` v3.0.0; components bitcoind/postgres/cli/config/ordinals/ord/runes) + two Fastify TypeScript REST APIs (`api/ordinals`, `api/runes`). Runs via `bitcoin-indexer {ordinals|runes} service start --config-path `; Docker images in `dockerfiles/`. API default `API_PORT=3000`; runes admin RPC 3001; Postgres 5432. No PM2, no .env.example (TOML config). -2. **Protocols**: Ordinals inscriptions, BRC-20 (ordinals meta-protocol), Runes (stock Hiro components — NOT the Universe `runes_native` adapter). +2. **Protocols**: Ordinals inscriptions, BRC-20 (ordinals meta-protocol), Runes (stock Hiro components, NOT the Universe `runes_native` adapter). 3. **Routes**: Ordinals API under `/ordinals/v1` (+ `/ordinals`): `/` status, `inscriptions[...]` (transfers/content), `sats/:ordinal[...]`, `stats/inscriptions`, `brc-20/{tokens,balances/:address,activity...}`. Runes API under `/runes/v1` (+ `/runes`): `/` status, `etchings[...]` (activity/holders), **`addresses/:address/{balances,activity}`**, **`transactions/:tx_id/activity`**, **`blocks/:block/activity`**. No dedicated /ready or /health (status route hardcodes `status:'ready'`), no checkpoint, **no outpoint route**, no mempool. 4. **Explorer contract**: none. 5. **DB**: PostgreSQL (migrations for ordinals/brc20/runes). Runes ledger has `(tx_id, output)` index (event ledger, not a current-position table); ordinals `locations`/`current_locations` are satpoint-oriented. @@ -309,22 +309,22 @@ Paths inside each section are relative to that repo's root unless prefixed with 7. **runes_native**: zero matches. 8. **Shared contracts**: none. Actively maintained (main promoted 2026-08-22). -## index-drops — `D:\universe\index-drops\index-drops` (LIKELY SUPERSEDED) +## index-drops, `D:\universe\index-drops\index-drops` (LIKELY SUPERSEDED) 1. **Stack/run**: Node TS ESM, raw `node:http`; Node **24.18.1**/npm 10.9.8 (older pin). CLI `drops`; `serve --port 3939` (default **3939**). No Docker/PM2/.env.example. 2. **Protocols**: Drops (base-layer Taproot OP_DROP artifact protocol, BIP341-verified; recognizes `bip110-op-drop` carrier; reference-only Pacts profile). 256-byte body cap. 3. **Routes** (`src/http.ts`, GET-only): `/live`, `/ready` (real readiness), `/health` (deprecated alias), `/openapi.json`, `/docs`, `/drops/status` (source/indexed/finalized cursors), `/drops[?limit=&marker=&planHash=]`, `/drops/:id[/content]`, `/pacts`, `/pacts/capabilities`, `/pacts/:pactId`. No block/tx/outpoint/address/mempool routes. 4. **Explorer contract**: none. -5. **DB**: none — atomic checksummed schema-v2 JSON snapshots on disk (`src/store.ts`); explicitly not production-scale. No outpoint positions (records keyed `drops:::d`). +5. **DB**: none, atomic checksummed schema-v2 JSON snapshots on disk (`src/store.ts`); explicitly not production-scale. No outpoint positions (records keyed `drops:::d`). 6. **Auth**: none (GET-only; outbound Core basic auth only). 7. **runes_native**: zero matches. 8. **Shared contracts**: none. -- **Supersession**: likely superseded by index-drops-and-opdrop (last commit 2026-08-02; the combined repo absorbed the `drops` CLI/toolkit/Pacts surface; remote org differs — `bitcoinuniverse/index-drops` vs `bitcoinuniverseio/*`; imported via git-archive snapshot per `SOURCE-PROVENANCE.json`). No in-repo DEPRECATED marker. +- **Supersession**: likely superseded by index-drops-and-opdrop (last commit 2026-08-02; the combined repo absorbed the `drops` CLI/toolkit/Pacts surface; remote org differs, `bitcoinuniverse/index-drops` vs `bitcoinuniverseio/*`; imported via git-archive snapshot per `SOURCE-PROVENANCE.json`). No in-repo DEPRECATED marker. -## index-opdrop — `D:\universe\index-opdrop\index-opdrop` (SUPERSEDED) +## index-opdrop, `D:\universe\index-opdrop\index-opdrop` (SUPERSEDED) 1. **Stack/run**: NestJS 11 + TypeORM; Node 24.18.1/npm 10.9.8. Dockerfile (EXPOSE 3001) + compose (host `${OP_DROP_BIND_PORT:-3015}:3001`, MySQL 8.4 + Redis). Branch `develop`, never promoted; last substantive commit 2026-08-16. -2. **Protocols**: op-drop (BIP-110 $DROP) + Drops over one scan — the direct predecessor of index-drops-and-opdrop. +2. **Protocols**: op-drop (BIP-110 $DROP) + Drops over one scan, the direct predecessor of index-drops-and-opdrop. 3. **Routes**: same shape as drops-and-opdrop minus Marketplace v1: `/live|/health|/ready|/version|/metrics` (+ `/op-drop/*` aliases), op-drop tokens/balances/:address/transfers/events/provisional[track]/indexer status|scan|replay, trading listings + authorization, `/drops/*` data + HTML viewer, `/token-explorer/{op-drop,drops,status}` (bearer), `/openapi.json`, `/docs`. 4. **Explorer contract**: none (`/token-explorer/*` feed only). 5. **DB**: MySQL 8.4; per-outpoint yes (op_drop_transfers UNIQUE (network, anchorTxid, anchorVout); drops custody outpoint tables; balances address-keyed). @@ -335,38 +335,38 @@ Paths inside each section are relative to that repo's root unless prefixed with --- -## backend-apis — `D:\universe\backend-apis\backend-apis` +## backend-apis, `D:\universe\backend-apis\backend-apis` -1. **Stack/run**: NestJS 11 + TypeORM + mysql2, Node 24.19.0. **PM2** app `universe` (`ecosystem.config.cjs`, fork mode, single instance — owns in-process indexer/polling work), `npm run pm2:deploy`. Port **3000** loopback, Apache ingress; systemd socket activation supported. Swagger `/api/docs`. +1. **Stack/run**: NestJS 11 + TypeORM + mysql2, Node 24.19.0. **PM2** app `universe` (`ecosystem.config.cjs`, fork mode, single instance, owns in-process indexer/polling work), `npm run pm2:deploy`. Port **3000** loopback, Apache ingress; systemd socket activation supported. Swagger `/api/docs`. 2. **Aggregation**: yes, HTTP-only (never direct DB reads of indexer stores): - Transparent reverse proxies: `/zcash_indexer/*`, `/stamp_indexer/*`, `/unat_indexer/*`, `/dust20_indexer/*`, op-inscriptions routes (`src/{zcash-indexer,stamp-indexer,unat-indexer,dust20-indexer,op-inscriptions}/`; base URLs in `src/common/constants.ts`). - Typed indexer clients: chainbloom (:3011), witness (:3012), patina (:3013), drops-opdrop (:3015 + service token), tandem (:3021, commented), mempool provider (:8381), bitmap-render (:3004). - - Marketplace v1 authority clients under `src/marketplace-v1/adapters/`: `ordinals/index-ordinals-authority.client.ts` (`MARKETPLACE_V1_INDEX_ORDINALS_ORIGIN` + bearer), `account-position/index-op20-authority.client.ts`, `account-position/index-stamps-authority.client.ts`, `ordinal-family/index-ordinal-family-authority.client.ts`. **No index-runes/index-brc20 clients** — runes/brc20 data comes from third-party providers (UniSat, Magic Eden, Satflow, etc.) via `src/external/` and `src/unisat/`. + - Marketplace v1 authority clients under `src/marketplace-v1/adapters/`: `ordinals/index-ordinals-authority.client.ts` (`MARKETPLACE_V1_INDEX_ORDINALS_ORIGIN` + bearer), `account-position/index-op20-authority.client.ts`, `account-position/index-stamps-authority.client.ts`, `ordinal-family/index-ordinal-family-authority.client.ts`. **No index-runes/index-brc20 clients**, runes/brc20 data comes from third-party providers (UniSat, Magic Eden, Satflow, etc.) via `src/external/` and `src/unisat/`. - Indexer health gate: `src/indexer-health/` (route `/indexer-health`), consumes `MARKETPLACE_PROTOCOL_REGISTRY` from ecosystem-contracts and blocks marketplace mutations when per-protocol indexer freshness fails. 3. **Route namespaces**: no global prefix; ~60 modules. Notable mounts: `api/marketplace/v1/protocols/:protocolId[...]`, `api/marketplace/v1/runtime`, `api/{patina,witness,tandem,chainbloom,frontier-suite,arc20,cat20,rare-sats,ordex,doge-tap,doginals,whole-products,collectible-check}`, `api/op-drop/trading`, `universe-media/v1`, `ordinals`, `ordinals-collections`, `mempool`, `unisat`, `satflow`, `stampdex`, `ecosystem`, `portfolio`, `indexer-health`, `{zcash,stamp,unat,dust20}_indexer`, `wallet-auth`, `auth/chat`, `bip110`, `atomicals-nfts-and-realms`, plus bare controllers declaring `alkanes`, `op20`, `runes`, `brc20`, `mezcal`, `dmt`, `drc20`, `blockdrop`, `unat` etc. per-route. -4. **Protocol registry**: `packages/ecosystem-contracts/lib/protocols.js` — `PROTOCOL_CAPABILITIES` (38 ids incl. `runes_native` with displayName "Runes (Native)", aliases `runes-native|native-runes|runes-(native)`), `PROTOCOL_ALIASES`, `MARKETPLACE_PROTOCOL_REGISTRY` (29 ids), `normalizeProtocolId`. Entry shape: displayName, aliases, ownershipModel (utxo|balance|hybrid), per-surface actions (main/wallet/inscribe/stampdex), marketplace, decimals, addressRoles. +4. **Protocol registry**: `packages/ecosystem-contracts/lib/protocols.js`, `PROTOCOL_CAPABILITIES` (38 ids incl. `runes_native` with displayName "Runes (Native)", aliases `runes-native|native-runes|runes-(native)`), `PROTOCOL_ALIASES`, `MARKETPLACE_PROTOCOL_REGISTRY` (29 ids), `normalizeProtocolId`. Entry shape: displayName, aliases, ownershipModel (utxo|balance|hybrid), per-surface actions (main/wallet/inscribe/stampdex), marketplace, decimals, addressRoles. 5. **Explorer/overlay modules**: none. No `overlay` matches. `explorer` matches are incidental (outbound stampchain proxy `/api/v1/explorer/src20/*` in `src/external/external.controller.ts`; frontier-suite feature flag; block-explorer prose). 6. **`/v1/explorer/*` routes**: none served. Only `/v1` mounts: `api/marketplace/v1/*`, `universe-media/v1`, `rare-sats` `v1/health`. -7. **runes_native**: pervasive — ecosystem-contracts registry (protocols.js:120, 691), `src/marketplace-v1/marketplace-protocol-adapter.ts:19`, native-token adapter `src/marketplace-v1/adapters/native-token/native-token-marketplace-v1.adapter.ts:73-75` (`RunesNativeMarketplaceV1Adapter`), asset resolver `native-token-asset-resolver.ts:15,35,595` (agreement `unisat-runes-and-esplora-output-agreement-v1`), coverage contract, trade service verified actions, migrations `20260810_create_runes_marketplace_tables.sql`, `20260802_native_token_trade_integrity.sql`, `20260803_marketplace_v1_persistence*.sql` (protocol enum lists). -8. **Shared contracts**: authoring home of `@bitcoinuniverse/ecosystem-contracts` v1.1.1 (`packages/ecosystem-contracts`; subpath exports core/protocols/deep-links/session/events/lifecycle/utxo/marketplace/marketplace-v1/health/metadata/client/schemas). JSON schemas: asset-metadata.v1, classified-utxo.v1, deep-link-intent.v1, ecosystem-event.v1, lifecycle-snapshot.v1, marketplace-order.v1, marketplace-resolver-utxo.v1, wallet-session.v1. **No position-source/checkpoint/settlement-evidence schema in the package** — settlement evidence contract is a code constant `marketplace-v1-settlement-evidence:v1` in `src/marketplace-v1/settlement/marketplace-v1-settlement-recovery-worker.ts:46-47`. +7. **runes_native**: pervasive, ecosystem-contracts registry (protocols.js:120, 691), `src/marketplace-v1/marketplace-protocol-adapter.ts:19`, native-token adapter `src/marketplace-v1/adapters/native-token/native-token-marketplace-v1.adapter.ts:73-75` (`RunesNativeMarketplaceV1Adapter`), asset resolver `native-token-asset-resolver.ts:15,35,595` (agreement `unisat-runes-and-esplora-output-agreement-v1`), coverage contract, trade service verified actions, migrations `20260810_create_runes_marketplace_tables.sql`, `20260802_native_token_trade_integrity.sql`, `20260803_marketplace_v1_persistence*.sql` (protocol enum lists). +8. **Shared contracts**: authoring home of `@bitcoinuniverse/ecosystem-contracts` v1.1.1 (`packages/ecosystem-contracts`; subpath exports core/protocols/deep-links/session/events/lifecycle/utxo/marketplace/marketplace-v1/health/metadata/client/schemas). JSON schemas: asset-metadata.v1, classified-utxo.v1, deep-link-intent.v1, ecosystem-event.v1, lifecycle-snapshot.v1, marketplace-order.v1, marketplace-resolver-utxo.v1, wallet-session.v1. **No position-source/checkpoint/settlement-evidence schema in the package**, settlement evidence contract is a code constant `marketplace-v1-settlement-evidence:v1` in `src/marketplace-v1/settlement/marketplace-v1-settlement-recovery-worker.ts:46-47`. 9. **DB**: MySQL/MariaDB only (TypeORM + raw mysql2 pool); SQL migrations in `migrations/`. -10. **Auth**: per-surface — node-gateway policy middleware (public vs trusted-operator, CIDRs), `PRIVATE_BITCOIN_BEARER_TOKEN`, admin cookie sessions + CSRF, wallet signature challenges (`/wallet-auth/challenge`), Firebase chat tokens, ingest guards, per-protocol marketplace read/execution tokens + HMAC secrets. +10. **Auth**: per-surface, node-gateway policy middleware (public vs trusted-operator, CIDRs), `PRIVATE_BITCOIN_BEARER_TOKEN`, admin cookie sessions + CSRF, wallet signature challenges (`/wallet-auth/challenge`), Firebase chat tokens, ingest guards, per-protocol marketplace read/execution tokens + HMAC secrets. -## wallet — `D:\universe\wallet\wallet` +## wallet, `D:\universe\wallet\wallet` -- **Protocol registry (primary): `backend/shared/protocol-registry.ts`** (668 lines) — "the single release authority for protocol identifiers and operations." 40 entries built via `blocked()`/`readOnly()`/`disabled()` factories; fields: `id`, `aliases`, `network(s)`, `implementedOperations`, `intendedOperations`, `operations` (evidence-backed), `status` (PRODUCTION VERIFIED | VERIFIED READ ONLY | INTENTIONALLY DISABLED | BLOCKED), `evidence`, `uiActions?`, `paymentOnly?`. `BASE_PROTOCOL_REGISTRY` at line ~260; exported `PROTOCOL_REGISTRY` (line ~504) upgraded by `UNIVERSE_PROTOCOL_AUTHORIZATION` env snapshot. No displayName field — display names come from ecosystem-contracts. +- **Protocol registry (primary): `backend/shared/protocol-registry.ts`** (668 lines), "the single release authority for protocol identifiers and operations." 40 entries built via `blocked()`/`readOnly()`/`disabled()` factories; fields: `id`, `aliases`, `network(s)`, `implementedOperations`, `intendedOperations`, `operations` (evidence-backed), `status` (PRODUCTION VERIFIED | VERIFIED READ ONLY | INTENTIONALLY DISABLED | BLOCKED), `evidence`, `uiActions?`, `paymentOnly?`. `BASE_PROTOCOL_REGISTRY` at line ~260; exported `PROTOCOL_REGISTRY` (line ~504) upgraded by `UNIVERSE_PROTOCOL_AUTHORIZATION` env snapshot. No displayName field, display names come from ecosystem-contracts. - Ids: bitcoin, ordinals, brc-20, runes (paymentOnly), alkanes (paymentOnly), tap, src-20, stamps, src-101, dust-20, unat, bitmap, block-20, op_return, op-20, op_names, op_inscriptions, mezcal, drops, op-drop, chainbloom, patina, witness-circles, dogecoin, doginals, drc-20, atomicals, arc-20, cat-20, cat-721, dmt, blockdrop, doge-tap, brc-110, fractal, babylon, bip-110, dogecoin-marketplace, zerdinals, zrunes. (Hyphenated id style; `protocolLookupKey` normalization reconciles with backend's underscore-free ids.) Mirrored in `docs/PROTOCOL-RELEASE-MATRIX.json` / `.md`. -- **Secondary registries**: `backend/shared/protocol-dependencies.json` (schemaVersion 2 — service dependency map: endpoints, healthPaths, per-service protocol lists, lag/finality/reorg policies; e.g. universe-bitcoin-api `https://api.bitcoinuniverse.io` `/health` covering 31 protocols); consumers `frontend/ui/utils/protocol-utils.ts`, `protocol-capabilities.ts`. +- **Secondary registries**: `backend/shared/protocol-dependencies.json` (schemaVersion 2, service dependency map: endpoints, healthPaths, per-service protocol lists, lag/finality/reorg policies; e.g. universe-bitcoin-api `https://api.bitcoinuniverse.io` `/health` covering 31 protocols); consumers `frontend/ui/utils/protocol-utils.ts`, `protocol-capabilities.ts`. - **Shared contracts**: consumes `@bitcoinuniverse/ecosystem-contracts` v1.1.1 as vendored tarball `vendor/bitcoinuniverse-ecosystem-contracts-1.1.1.tgz` (`frontend/package.json:86`; verified by `frontend/scripts/verify-ecosystem-contracts.mjs`). - **runes_native**: not in wallet sources; only transitively via the vendored ecosystem-contracts (appears in built bundles `frontend/chrome-extension-dev/background.js`, `frontend/dist/chrome/background.js`). Wallet's own registry has a single `runes` entry (paymentOnly, BLOCKED) with no native variant. --- -## runes_native / "Native Runes" — complete reference map +## runes_native / "Native Runes", complete reference map | Repo | Role | Files | |---|---|---| -| **index-runes** | **Implementation** — second `RunesMarketplaceAuthority` instance for protocol `runes_native`; routes `/v1/marketplace/runes-native/*` + `/v1/marketplace/protocols/runes_native/*` | `src/main.mjs:27`, `src/marketplace/authority.mjs` (schemas, dual-instance guard), `src/marketplace/identities.mjs:64`, `src/config.mjs:142-191`, `src/server.mjs:44,59,272`, `.env.example:31-32`, `docs/MARKETPLACE_V1_AUTHORITY.md`, `README.md:97,108` | +| **index-runes** | **Implementation**, second `RunesMarketplaceAuthority` instance for protocol `runes_native`; routes `/v1/marketplace/runes-native/*` + `/v1/marketplace/protocols/runes_native/*` | `src/main.mjs:27`, `src/marketplace/authority.mjs` (schemas, dual-instance guard), `src/marketplace/identities.mjs:64`, `src/config.mjs:142-191`, `src/server.mjs:44,59,272`, `.env.example:31-32`, `docs/MARKETPLACE_V1_AUTHORITY.md`, `README.md:97,108` | | backend-apis | Registry + marketplace adapter (`RunesNativeMarketplaceV1Adapter`), trade flows, DB enums | `packages/ecosystem-contracts/lib/protocols.js:120,691`; `src/marketplace-v1/adapters/native-token/*`; `src/marketplace-v1/marketplace-protocol-adapter.ts:19`; `src/trade/trade.service.ts` (multiple); migrations `20260810_create_runes_marketplace_tables.sql`, `20260802_native_token_trade_integrity.sql`, `20260803_marketplace_v1_persistence*.sql` | | index-ordinals | Consumer (composite inventory position-source client; maps to `/v1/marketplace/runes-native/position-source` prefix) | `src/marketplace-inventory-types.ts:13,46`, `src/position-source-client.ts:224-225`, `README.md:173` | | index-mezcal | Shared native-token contract sibling | `contracts/universe-marketplace-native-token-v1.json:4`, `scripts/check-marketplace-contract.mjs:34` | @@ -379,7 +379,7 @@ Paths inside each section are relative to that repo's root unless prefixed with | index-bitmap | Protocol-id enum | `src/authority.mjs:33` | | index-drops-and-opdrop | Protocol-id enum (composite inventory client) | `src/drops/drops-output-inventory.client.ts:26` | | wallet | Transitive only (vendored ecosystem-contracts; built bundles) | `vendor/bitcoinuniverse-ecosystem-contracts-1.1.1.tgz`; `frontend/dist/chrome/background.js` | -| Absent from | index-brc20 (only Marketplace-authority repo missing it — divergence), index-stamps, index-atomicals(+nfts), index-op20, index-opinscriptions, index-block20, index-cat20, index-doge-tap, index-zcash-metaprotocols, index-chainbloom, index-patina, index-witness-circles, index-tandem, bitcoin-indexer, index-drops, index-opdrop | — | +| Absent from | index-brc20 (only Marketplace-authority repo missing it, divergence), index-stamps, index-atomicals(+nfts), index-op20, index-opinscriptions, index-block20, index-cat20, index-doge-tap, index-zcash-metaprotocols, index-chainbloom, index-patina, index-witness-circles, index-tandem, bitcoin-indexer, index-drops, index-opdrop |, | --- @@ -387,31 +387,31 @@ Paths inside each section are relative to that repo's root unless prefixed with | repo | stack | port (default) | explorer contract? | outpoint queries? | mempool support? | auth | |---|---|---|---|---|---|---| -| index-ordinals | Node TS, node:http | 3218 | no (/ready /status /v1/checkpoint) | yes — /v1/marketplace/inventory/outpoints/:o | preflight only (testmempoolaccept) | bearer x3 + HMAC | -| index-runes | Node .mjs | 3042 | no | yes — {runes,runes-native}/[position-source/]outpoints/:o | no (partial) | bearer + admin header | +| index-ordinals | Node TS, node:http | 3218 | no (/ready /status /v1/checkpoint) | yes, /v1/marketplace/inventory/outpoints/:o | preflight only (testmempoolaccept) | bearer x3 + HMAC | +| index-runes | Node .mjs | 3042 | no | yes, {runes,runes-native}/[position-source/]outpoints/:o | no (partial) | bearer + admin header | | index-stamps | Node .mjs | 3043 | no | route yes; account-ledger (empty positions) | no (partial) | bearer per protocol | -| index-atomicals | Python ElectrumX + sidecar | 50010/50020/8000 + 3043 | no | yes — arc20 position-source/outpoints/:o | rejection signal only | bearer + admin header | -| index-atomicals-nfts-and-realms | Node .mjs | 3003 (ops 3014) | no (closest: blocks/tx/utxos routes) | yes — /v1/atomicals/utxos/:txid/:vout | none | mostly open; bearer feeds | -| index-brc20 | Node .mjs | 3041 | no | yes — /v1/marketplace/positions/outpoints/:o | no | bearer x2 + admin header | -| index-alkanes | Node .mjs | 3044 | no | yes — positions/outpoints/:o (persisted) | no (partial) | bearer x3 + admin | -| index-tap | Node TS | 3012 | no | yes — positions/outpoints/:o (computed live) | no | bearer + exec header | -| index-dmt | Node .mjs | 3044 (clash) | no | yes — positions/outpoints/:o | no | bearer x4 | -| index-dust20 | Node .mjs | 3102 | no | yes — positions/outpoints/:o (persisted allocations) | no | bearer x3 + admin; legacy routes open | -| index-op20 | Node .mjs | 3045 | no | yes — {op_return,op_names}/position-source/outpoints/:o | no | bearer x3 + exec header | -| index-opinscriptions | Node TS (raw http; Nest unused) | 3000/9091/9092 | no | yes — positions/outpoints/:txid::vout | source-level only | marketplace bearer; read API open | -| index-drops-and-opdrop | NestJS + TypeORM | 3001 (host 3015) | no | yes — protocols/:pid/position-source/outpoints/:o | partial (op-drop provisional tracker; Drops confirmed-only) | bearers + service token + BIP322 | -| index-unat | Node .mjs | 3217 | no | yes — positions/outpoints/:o | no | bearer x3 | -| index-bitmap | Node .mjs | 3220 | no (/v1/checkpoint yes) | yes — positions/outpoints/:o (computed live) | no | bearer + exec header | -| index-names | Node .mjs | 3220 (clash) | no (/v1/checkpoint yes) | yes — positions/outpoints/:o (computed live) | no | bearer + exec header | +| index-atomicals | Python ElectrumX + sidecar | 50010/50020/8000 + 3043 | no | yes, arc20 position-source/outpoints/:o | rejection signal only | bearer + admin header | +| index-atomicals-nfts-and-realms | Node .mjs | 3003 (ops 3014) | no (closest: blocks/tx/utxos routes) | yes, /v1/atomicals/utxos/:txid/:vout | none | mostly open; bearer feeds | +| index-brc20 | Node .mjs | 3041 | no | yes, /v1/marketplace/positions/outpoints/:o | no | bearer x2 + admin header | +| index-alkanes | Node .mjs | 3044 | no | yes, positions/outpoints/:o (persisted) | no (partial) | bearer x3 + admin | +| index-tap | Node TS | 3012 | no | yes, positions/outpoints/:o (computed live) | no | bearer + exec header | +| index-dmt | Node .mjs | 3044 (clash) | no | yes, positions/outpoints/:o | no | bearer x4 | +| index-dust20 | Node .mjs | 3102 | no | yes, positions/outpoints/:o (persisted allocations) | no | bearer x3 + admin; legacy routes open | +| index-op20 | Node .mjs | 3045 | no | yes, {op_return,op_names}/position-source/outpoints/:o | no | bearer x3 + exec header | +| index-opinscriptions | Node TS (raw http; Nest unused) | 3000/9091/9092 | no | yes, positions/outpoints/:txid::vout | source-level only | marketplace bearer; read API open | +| index-drops-and-opdrop | NestJS + TypeORM | 3001 (host 3015) | no | yes, protocols/:pid/position-source/outpoints/:o | partial (op-drop provisional tracker; Drops confirmed-only) | bearers + service token + BIP322 | +| index-unat | Node .mjs | 3217 | no | yes, positions/outpoints/:o | no | bearer x3 | +| index-bitmap | Node .mjs | 3220 | no (/v1/checkpoint yes) | yes, positions/outpoints/:o (computed live) | no | bearer + exec header | +| index-names | Node .mjs | 3220 (clash) | no (/v1/checkpoint yes) | yes, positions/outpoints/:o (computed live) | no | bearer + exec header | | index-block20 | Node .mjs | 3101 | no | no | no | bearer feed + admin header | -| index-mezcal | Node TS | 3014 | no | yes — positions/outpoints/:o (persisted) | no | bearer x3 | -| index-chainbloom | NestJS + MySQL | 3000 (backend expects 3011) | no | yes — lanes/by-outpoint/:txid/:vout | **yes** (/mempool + WS) | public reads; admin API key | -| index-patina | Node TS CLI | 4180 (backend expects 3013) | no | yes — carriers/:txid/:vout + POST safety/outpoints | **yes** (/mempool) | **none** (rate limit only) | -| index-witness-circles | NestJS + MySQL | 3012 (clash) | no | yes — shards/:txid/:vout + POST safety/outpoints | **yes** (/mempool[/txid]) | public reads; admin bearer | -| index-tandem | NestJS + MySQL | 3021 | no | yes — carriers/:txid/:vout | **yes** (verified/mempool) | **none** | +| index-mezcal | Node TS | 3014 | no | yes, positions/outpoints/:o (persisted) | no | bearer x3 | +| index-chainbloom | NestJS + MySQL | 3000 (backend expects 3011) | no | yes, lanes/by-outpoint/:txid/:vout | **yes** (/mempool + WS) | public reads; admin API key | +| index-patina | Node TS CLI | 4180 (backend expects 3013) | no | yes, carriers/:txid/:vout + POST safety/outpoints | **yes** (/mempool) | **none** (rate limit only) | +| index-witness-circles | NestJS + MySQL | 3012 (clash) | no | yes, shards/:txid/:vout + POST safety/outpoints | **yes** (/mempool[/txid]) | public reads; admin bearer | +| index-tandem | NestJS + MySQL | 3021 | no | yes, carriers/:txid/:vout | **yes** (verified/mempool) | **none** | | index-cat20 | Node .mjs | 3042 (clash) | no | no | no | bearer + admin header | | index-doge-tap | Node TS | 3013 | no | no | no | bearer + IP allowlist + HMAC internal | -| index-zcash-metaprotocols | Node .mjs + Rust | 8790 | no (closest match) | yes — POST /outpoints/assets (batch) | no | none (gateway-fronted) | +| index-zcash-metaprotocols | Node .mjs + Rust | 8790 | no (closest match) | yes, POST /outpoints/assets (batch) | no | none (gateway-fronted) | | bitcoin-indexer | Rust + Fastify TS | 3000 (API) | no | no | no | none | | index-drops (superseded) | Node TS | 3939 | no | no | no | none (GET-only) | | index-opdrop (superseded) | NestJS + MySQL | 3001/3015 | no | no (custody tables only) | partial (provisional) | service token + bearer + admin | diff --git a/docs/research/market-lessons.md b/docs/research/market-lessons.md new file mode 100644 index 00000000000..9ab64dcfe7b --- /dev/null +++ b/docs/research/market-lessons.md @@ -0,0 +1,118 @@ +# Market lessons that changed the build + +Research pass completed 26 August 2026. This file exists so research is +accountable: each lesson names the decision it produced, and each rejected idea +names the reason. + +Companion documents: `competitive-landscape.md` (per-product analysis), +`competitive-landscape.json` (machine-readable matrix), +`source-ledger.md` (claim to source traceability), +`emerging-trends.md` (what changed in the market this year), +`docs/product/EXPERIENCE-BRIEF.md` (the position these lessons produced). + +## Lessons that produced code + +### 1. The strongest mempool explorer will not decode metaprotocols + +Upstream tags inscription envelopes and runestones but refuses to integrate an +asset indexer, as a stated policy. That is a durable gap, not a backlog item. + +**Built:** the asset flow section on every transaction page, resolving tags into +authority-proven positions per input and output. + +### 2. Every asset-centric explorer in this market is closed and hosted + +UniScan, Ordiscan, GeniiData, Best in Slot, and the exchange explorers are all +closed source and none is self-hostable. A user cannot verify their indexer, and +2026 showed what happens when a hosted protocol data source is withdrawn. + +**Built:** first-party authorities only, plus a public `/source` page that names +the exact running commit, so the trust claim is checkable rather than asserted. + +### 3. Asset pages are judged on mint progress, supply, and holders + +Every serious protocol explorer leads its asset page with those figures. + +**Built:** the rune page shows mints against the cap as a floored percentage, +premine, burned, divisibility-scaled supply, and the mint window, all read from +the authority. Where terms carry no cap, the page says there is no progress to +report rather than drawing a meaningless bar. + +### 4. Rare-sat and UTXO inspection is a real, underserved job + +Ordiscan's rare-sat and UTXO tooling exists because holders need to know which +specific output carries a specific thing. + +**Built:** `/outpoint/:txid/:vout` as a first-class page, `/sat/:number` with the +rule that produces the rarity, and outpoint links from every position row. + +### 5. Live visualization drives return visits + +TxStreet, Bitfeed, and the upstream projected-block view all show that watching +the mempool is itself the product for a large audience. + +**Built:** the pulse page. It is not decorative: it publishes the number of +transactions checked alongside every protocol count, so the visualization is +also a measurement. + +### 6. Watchlists and alerts are a product category that harvests privacy + +Third-party trackers log the addresses their users watch. + +**Built:** saved pages, recent history, and pinned protocols in local storage, +with a single button that erases all of it and a privacy page that says so. +No account, no server-side list. + +### 7. Speed and the absence of trackers are marketable positions + +3xpl competes on exactly those two claims. + +**Built:** no analytics of any kind (the upstream hosted tracker path is a +documented no-op), no remote fonts, no third-party requests at runtime or at +build time, and an automated gate that fails the build if one appears. + +### 8. Bitcoin Core v30 removed the effective OP_RETURN limit + +Released 10 October 2025, `-datacarriersize` defaults to 100,000 bytes, so +data-carrying transactions are no longer filtered by a default Core mempool +while Knots operators keep filtering them. + +**Built:** protocols whose instructions live in data outputs are described in +those terms on the protocol pages, so a reader understands that relay policy, +not consensus, decides whether such a transaction propagates. Recorded in +`emerging-trends.md` as the next area to instrument. + +### 9. Nobody explains what a transaction did in plain language + +Every explorer in the set presents fields. None writes a sentence. + +**Built:** the plain-language summary at the top of the asset flow section, +generated only from actions the authority reported, and worded so it never +implies a trade. + +## Ideas deliberately rejected + +| Pattern | Seen in | Why not | +| --- | --- | --- | +| Paid transaction acceleration | upstream | A centralized commercial service that has no place in a self-hosted, read-only explorer. Removed from this fork entirely. | +| Explorer as a marketplace funnel | UniSat, OKX, Magic Eden | Creates an incentive to present assets favourably. Neutrality is the product. | +| Hosted analytics on the explorer | upstream | Contradicts the privacy claim. The code path is now inert. | +| Enterprise upsells inside the API docs | upstream | Not this deployment's business model. Removed. | +| Trending lists with unpublished methodology | GeniiData, several asset explorers | A rank nobody can recompute is decoration. Every figure here ships its denominator. | +| Price, market cap, and floor figures | most asset explorers | Requires third-party market data and invites the reading that the explorer offers financial advice. | +| Server-side watchlists and alert accounts | BlockPing and similar | Builds exactly the profile this product refuses to hold. Local storage does the same job. | +| Rendering inscription content inline | several | Executing arbitrary inscribed data inside the explorer's own origin is not worth a preview. | +| An MCP or agent endpoint | Bitquery, Blockscout | Genuinely emerging, but out of scope for this release. The versioned public API is the prerequisite and it exists. | +| Multi-chain expansion | Blockchair, OKLink | The registry lists other chains for completeness and the UI separates them. Serving them is a different product. | + +## Closure evidence + +Discovery ran in four passes with different strategies: category search, +protocol-family search (Alkanes, Stamps, Atomicals, Runes, TAP, DMT, CAT-20), +adjacent-category search (visualizers, privacy explorers, agent interfaces, +alerting), and directory or aggregator search. The final two passes surfaced +new product names (Atomicals Hub, Atomscan, Bitatom, Wizz, OpenStamp Explorer, +Stampscan, TxCity, Tx.Town, BlocksViewer, Luminex, Esplora, Horizontal Systems +Block Explorer) but no new competitor category, capability class, user +expectation, or trend beyond those already recorded. Queries and dates are in +`source-ledger.md`. diff --git a/docs/research/source-ledger.md b/docs/research/source-ledger.md new file mode 100644 index 00000000000..e8f13ef59c7 --- /dev/null +++ b/docs/research/source-ledger.md @@ -0,0 +1,63 @@ +# Source ledger + +Traceability for the research that shaped this release. Access date for every +entry is 26 August 2026 unless stated otherwise. + +Evidence classes: **primary** (the product, its repository, or its own +documentation), **secondary** (reporting or analysis), **observed** (behaviour +seen while using the product), **inference** (reasoning from the above, always +labelled as such where it is used). + +## Search strategies and closure + +Discovery ran in four passes, each using a different strategy, so that closure +means something beyond query rephrasing. + +| Pass | Strategy | Queries | +| --- | --- | --- | +| 1 | Category and comparison | Bitcoin block explorer 2026 comparison mempool explorer protocol aware ordinals runes | +| 2 | Protocol family | Alkanes protocol explorer metashrew oyl indexer; Bitcoin Stamps SRC-20 explorer stampchain openstamp; Atomicals ARC-20 realms explorer; Runes explorer Ordiscan Best in Slot GeniiData Luminex mint progress; CAT-20 / TAP protocol / Digital Matter Theory bitcoin explorer | +| 3 | Adjacent capability | live bitcoin transaction visualizer TxStreet Bitfeed mempool animation; privacy Bitcoin explorer no javascript Tor self-hosted BTC RPC Explorer 3xpl Bitaps; blockchain explorer MCP server AI agent API bitcoin data; bitcoin address watchlist alerts explorer notifications on-chain activity tracker | +| 4 | Directory and closure | awesome bitcoin block explorers list open source self-hosted directory; bitcoin explorer UX accessibility WCAG mobile search identifier detection; Bitcoin Core v30 OP_RETURN datacarrier limit removed mempool policy impact explorers; mempool explorer user complaints missing features | + +Passes 3 and 4 produced new product names but no new competitor category, +capability class, user expectation, or trend. That is the closure condition +recorded in `market-lessons.md`. + +## Claim to source + +| Claim used in a decision | Source | Class | +| --- | --- | --- | +| v3.3.1 is the latest stable upstream release; v3.4.0 exists only as an alpha | upstream releases page, github.com/mempool/mempool/releases | primary | +| v3.3.0 added taproot script-tree visualization, sighash icons, stale-block comparison, sub-1 sat/vB support | upstream release notes | primary | +| Upstream declines to integrate an asset indexer | upstream project statements and issue history | primary | +| Bitcoin Core v30 released 10 October 2025; default `-datacarriersize` raised from 83 to 100,000 bytes | bitcoin/bitcoin release material and analysis of it | primary, secondary | +| Deprecation of `datacarrier` options was reverted before release | bitcoin/bitcoin pull request 33453 discussion | primary | +| Knots retains stricter data-carriage defaults and gained operators for that reason | comparison analyses published 2025 to 2026 | secondary | +| UniScan covers Ordinals, BRC-20, Runes, Alkanes on Bitcoin and Fractal; closed source | product surface | primary, observed | +| Ordiscan covers inscriptions, runes, rare sats, BRC-20, collections; has explicit rare-sat tooling | ordiscan.com | primary, observed | +| GeniiData leads with mint progress, holder counts, volume, activity | geniidata.com | primary, observed | +| Luminex is widely used for rune minting and etching | product and its documentation | primary, secondary | +| Stampchain publishes an open-source Stamps indexer, explorer, and API; OpenStamp adds a marketplace and explorer | stampchain-io repositories; docs.openstamp.io | primary | +| Alkanes launched at block 880000 and is indexed by the open-source Metashrew stack | kungfuflex/alkanes-rs; Alkanes documentation | primary | +| Atomicals ecosystem has several third-party explorers, and ARC-20 is backed one unit per satoshi | docs.atomicals.xyz; community tool lists | primary | +| TAP supports DMT deploy and mint operations and bitmap assets | Trac Systems TAP protocol specification | primary | +| TxStreet and Bitfeed are the reference live mempool visualizers | txstreet.com; bitfeed | primary, observed | +| 3xpl positions on speed, no third-party trackers, and a Tor hidden service | 3xpl.com | primary, observed | +| BTC RPC Explorer and Esplora are the established self-hostable base-chain explorers | janoside/btc-rpc-explorer; Blockstream Esplora | primary | +| Third-party wallet trackers log watched addresses and collect technical data | those products' own descriptions | primary | +| Agent-facing blockchain data interfaces are an emerging category with thin Bitcoin coverage | Bitquery and Blockscout agent-interface documentation | primary | +| WCAG 2.2 is the current standard, with touch-target and cognitive additions over 2.1 | W3C Web Accessibility Initiative | primary | + +## Environment evidence, gathered directly + +| Claim | How it was established | +| --- | --- | +| The public origin returned 502 before this release | HTTP request to the production origin | +| The gateway tunnel had never authenticated | gateway service journal, restart counter above 7500 | +| Ord 0.29 is the only healthy Bitcoin protocol authority | probes through the production tunnels to each configured authority | +| No explorer service existed on the target host | service listing and listening-socket inventory on that host | +| Release payloads were staged and built but never started | directory and build-artifact inspection on that host | + +Recorded in full in `audits/2026-08-26-go-state-baseline.md` in the project +workspace. diff --git a/docs/research/user-jobs.md b/docs/research/user-jobs.md new file mode 100644 index 00000000000..2f6014bf3f4 --- /dev/null +++ b/docs/research/user-jobs.md @@ -0,0 +1,64 @@ +# User jobs and recurring pain points + +Compiled 26 August 2026 from product testing across the competitor set, public +documentation, community discussion, and support material. Evidence class is +marked on every line: **observed** means the behaviour was seen in the product +itself, **reported** means it comes from public user discussion, and +**inferred** means it follows from the other two and is labelled as reasoning. + +## Jobs, ranked by how often they are the reason someone opens an explorer + +| # | Job | Who | Where it is served badly today | +| --- | --- | --- | --- | +| 1 | "Will my transaction confirm, and what will it cost" | everyone | Served well by mempool-first explorers, badly by asset-first ones (observed: asset explorers show a txid and a status, with no fee-market context). | +| 2 | "What exactly is on this output" | protocol holders | Served by nobody at output granularity with evidence. Asset explorers answer per address or per asset (observed). | +| 3 | "Did my transaction do what I meant" | builders, minters | Requires reading raw fields and knowing the protocol (observed across the whole set). | +| 4 | "What does this address hold across protocols" | holders | Served by closed hosted explorers, with no statement of coverage (observed). | +| 5 | "Is this mint still open, and how far along" | minters | Served on asset pages, methodology rarely stated (observed). | +| 6 | "What is happening on chain right now" | everyone | Served by live visualizers for base Bitcoin, by nobody for protocol activity (observed). | +| 7 | "Was my transaction replaced, and what happened to what it carried" | RBF users | Replacement timelines exist upstream; what the replacement did to a pending asset transfer is shown nowhere (observed). | +| 8 | "Give me a link that shows exactly this" | everyone | Deep links exist for transactions, blocks, and addresses; rarely for a state within them (observed). | +| 9 | "Watch this thing for me" | holders, operators | A separate product category, usually with an account and a server-side list (observed). | +| 10 | "Can I trust this data, and can I run it myself" | operators, researchers | Self-hosting is served by base-chain explorers only; no self-hostable protocol-aware explorer existed (observed). | + +## Recurring pain points + +1. **An empty cell that could mean two different things.** Explorers show + nothing both when an asset is absent and when the indexer failed to answer. + *(observed across the set; the single most consequential failure in this + category.)* +2. **Balances with no coverage statement.** A portfolio view that silently + truncates the outputs it scanned reads as complete. *(observed.)* +3. **Interpretation asserted as fact.** Pages describe transfers and sales that + the underlying data does not establish. *(observed.)* +4. **Precision lost on large amounts.** Token supplies beyond the safe integer + range render wrongly when passed through floating point. *(inferred from + the arithmetic; guarded against here with decimal strings and BigInt.)* +5. **Protocol coverage overstated.** A registry entry with no working indexer is + presented as supported. *(observed.)* +6. **Metaprotocol activity invisible until confirmation.** Pending protocol + operations are the moment that matters most and are the least visible. + *(observed.)* +7. **Hosted APIs disappearing.** Products built on them break with little + notice. *(reported, repeatedly, through 2026.)* +8. **Trackers on tools people use for financial privacy.** *(observed; + acknowledged in third-party tracker products' own documentation.)* +9. **Mobile treated as a narrowed desktop.** Dense tables scroll horizontally + and identifiers overflow. *(observed.)* +10. **Jargon with no on-ramp.** Terms are used without a one-line explanation + anywhere on the page. *(observed.)* + +## How this release answers each + +| Pain | Answer | +| --- | --- | +| 1 | Five distinct evidence states with distinct wording and colour, defined once in `universe-evidence.ts` and asserted in tests. | +| 2 | Every panel that samples publishes what it covered: outputs checked, outputs not checked, transactions checked. | +| 3 | The plain-language summary is generated only from reported actions and never uses trade vocabulary. | +| 4 | Decimal strings end to end; sums use BigInt; a malformed quantity is dropped rather than coerced. | +| 5 | Release status per protocol, with the reason a protocol is unavailable stated on its own page. | +| 6 | The pulse resolves pending transactions and labels them pending. | +| 7 | First-party authorities only, enforced by a build gate. | +| 8 | No analytics, no third-party requests, local-only personalization, one erase button. | +| 9 | Every new surface has its own mobile grid layout, tested from 320 pixels up. | +| 10 | Protocol pages explain what the protocol is and how to read its evidence in plain language. | diff --git a/frontend/README.md b/frontend/README.md index fb2a5e2917d..d4942c0ac66 100644 --- a/frontend/README.md +++ b/frontend/README.md @@ -9,7 +9,7 @@ Jump to a section in this doc: ## Quick Setup for Frontend Development -If you want to quickly improve the UI, fix typos, or make other updates that don't require any backend changes, you don't need to set up an entire backend—you can simply run the Mempool frontend locally and proxy to the mempool.space backend. +If you want to quickly improve the UI, fix typos, or make other updates that don't require any backend changes, you don't need to set up an entire backend: you can simply run the Mempool frontend locally and proxy to the mempool.space backend. ### 1. Clone Mempool Repository diff --git a/frontend/generate-themes.js b/frontend/generate-themes.js index da7f06c205b..3a5fe8e4630 100644 --- a/frontend/generate-themes.js +++ b/frontend/generate-themes.js @@ -3,7 +3,7 @@ const fs = require('fs'); const path = require('path'); const crypto = require('crypto'); -const THEMES = ['contrast', 'softsimon', 'bukele']; +const THEMES = ['dark', 'contrast']; const STAGING_DIR = path.join(__dirname, '.theme-build'); const DIST_DIR = path.join(__dirname, 'dist/mempool/browser'); const MANIFEST_FILE = path.join(__dirname, 'theme-manifest.json'); diff --git a/frontend/mempool-frontend-config.sample.json b/frontend/mempool-frontend-config.sample.json index 908c38c743d..069d0ae64f6 100644 --- a/frontend/mempool-frontend-config.sample.json +++ b/frontend/mempool-frontend-config.sample.json @@ -15,7 +15,7 @@ "MEMPOOL_BLOCKS_AMOUNT": 8, "BASE_MODULE": "mempool", "ROOT_NETWORK": "", - "MEMPOOL_WEBSITE_URL": "https://mempool.space", + "MEMPOOL_WEBSITE_URL": "https://explorer.bitcoinuniverse.io", "LIQUID_WEBSITE_URL": "https://liquid.network", "MINING_DASHBOARD": true, "AUDIT": false, @@ -36,5 +36,5 @@ "ACCELERATOR_BUTTON": true, "PUBLIC_ACCELERATIONS": false, "STRATUM_ENABLED": false, - "SERVICES_API": "https://mempool.space/api/v1/services" + "SERVICES_API": "/services" } diff --git a/frontend/package-lock.json b/frontend/package-lock.json index f1080b98661..017b7ba43a0 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -1,7 +1,7 @@ { "name": "mempool-frontend", "version": "3.3.1", - "lockfileVersion": 2, + "lockfileVersion": 3, "requires": true, "packages": { "": { @@ -9,19 +9,19 @@ "version": "3.3.1", "license": "GNU Affero General Public License v3.0", "dependencies": { - "@angular-devkit/build-angular": "^20.3.20", - "@angular/animations": "^20.3.18", - "@angular/cli": "^20.3.20", - "@angular/common": "^20.3.18", - "@angular/compiler": "^20.3.18", - "@angular/core": "^20.3.18", - "@angular/forms": "^20.3.18", - "@angular/localize": "^20.3.18", - "@angular/platform-browser": "^20.3.18", - "@angular/platform-browser-dynamic": "^20.3.18", - "@angular/platform-server": "^20.3.18", - "@angular/router": "^20.3.18", - "@angular/ssr": "^20.3.18", + "@angular-devkit/build-angular": "^20.3.35", + "@angular/animations": "^20.3.29", + "@angular/cli": "^20.3.35", + "@angular/common": "^20.3.29", + "@angular/compiler": "^20.3.29", + "@angular/core": "^20.3.29", + "@angular/forms": "^20.3.29", + "@angular/localize": "^20.3.29", + "@angular/platform-browser": "^20.3.29", + "@angular/platform-browser-dynamic": "^20.3.29", + "@angular/platform-server": "^20.3.29", + "@angular/router": "^20.3.29", + "@angular/ssr": "^20.3.35", "@fortawesome/angular-fontawesome": "^3.0.0", "@fortawesome/fontawesome-common-types": "~6.7.2", "@fortawesome/fontawesome-svg-core": "~6.7.2", @@ -41,7 +41,7 @@ "zone.js": "~0.15.1" }, "devDependencies": { - "@angular/compiler-cli": "^20.3.18", + "@angular/compiler-cli": "^20.3.29", "@angular/language-service": "^20.3.18", "@types/node": "^24.9.2", "@typescript-eslint/eslint-plugin": "^8.46.2", @@ -272,22 +272,13 @@ "node": ">=6.0.0" } }, - "node_modules/@ampproject/remapping/node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, "node_modules/@angular-devkit/architect": { - "version": "0.2003.22", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.2003.22.tgz", - "integrity": "sha512-gxVOslVweD+Co6gpRVlByHus/3HVAnsl99MobS9PBh8vh2g6bJ011PBgl0TKsP/pqBGawZOkJXYrRPeMKnobYA==", + "version": "0.2003.35", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.2003.35.tgz", + "integrity": "sha512-fuiccQamG0SBfuKRSA8uAoALI4VprZAWZbwwOGmpMaYrxoN9E4CgicR5hQUEEsp9IzMtuRvFpJPorudv2xzGMw==", "license": "MIT", "dependencies": { - "@angular-devkit/core": "20.3.22", + "@angular-devkit/core": "20.3.35", "rxjs": "7.8.2" }, "engines": { @@ -297,9 +288,9 @@ } }, "node_modules/@angular-devkit/architect/node_modules/@angular-devkit/core": { - "version": "20.3.22", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-20.3.22.tgz", - "integrity": "sha512-1vZnZTAjGcCM+86v2al+2eiROiSw0uAWeVllfHSQe0KsKOP1FE8UUUiWChhxVn7vIxypphlfGunkeeIn1C/ZFw==", + "version": "20.3.35", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-20.3.35.tgz", + "integrity": "sha512-RefMFJA7qRBxEDu3a6bVNK9o5vcHXxN8xKaCzENBrOIO6XamthoGMZIJrIT213KpHoEbLTcJjESqGFCpYmY6oA==", "license": "MIT", "dependencies": { "ajv": "8.18.0", @@ -356,12 +347,6 @@ } } }, - "node_modules/@angular-devkit/architect/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "license": "MIT" - }, "node_modules/@angular-devkit/architect/node_modules/picomatch": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", @@ -384,17 +369,17 @@ } }, "node_modules/@angular-devkit/build-angular": { - "version": "20.3.22", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-20.3.22.tgz", - "integrity": "sha512-PnKIRue/j30sWLWC9q2T3WwE5+GJekDX/zCXTYgjW6u0y/kt+7G/sR0uxXGkX2NwSVGnIz0ucVOBsbSl9PKd6A==", + "version": "20.3.35", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-20.3.35.tgz", + "integrity": "sha512-7gq/5pdQnJG5KGIoDuP1u7isv0jTEKQiR7RPLmuNSfLyHlx5FyEeZVdLBL+LSi13qfZlVHLDSqGITuJL+WoyhA==", "license": "MIT", "dependencies": { "@ampproject/remapping": "2.3.0", - "@angular-devkit/architect": "0.2003.22", - "@angular-devkit/build-webpack": "0.2003.22", - "@angular-devkit/core": "20.3.22", - "@angular/build": "20.3.22", - "@babel/core": "7.28.3", + "@angular-devkit/architect": "0.2003.35", + "@angular-devkit/build-webpack": "0.2003.35", + "@angular-devkit/core": "20.3.35", + "@angular/build": "20.3.35", + "@babel/core": "7.29.7", "@babel/generator": "7.28.3", "@babel/helper-annotate-as-pure": "7.27.3", "@babel/helper-split-export-declaration": "7.24.7", @@ -404,16 +389,16 @@ "@babel/preset-env": "7.28.3", "@babel/runtime": "7.28.3", "@discoveryjs/json-ext": "0.6.3", - "@ngtools/webpack": "20.3.22", + "@ngtools/webpack": "20.3.35", "ansi-colors": "4.1.3", "autoprefixer": "10.4.21", "babel-loader": "10.0.0", "browserslist": "^4.21.5", "copy-webpack-plugin": "14.0.0", "css-loader": "7.1.2", - "esbuild-wasm": "0.25.9", + "esbuild-wasm": "0.28.1", "fast-glob": "3.3.3", - "http-proxy-middleware": "3.0.5", + "http-proxy-middleware": "3.0.7", "istanbul-lib-instrument": "6.0.3", "jsonc-parser": "3.3.1", "karma-source-map-support": "1.4.0", @@ -425,8 +410,8 @@ "open": "10.2.0", "ora": "8.2.0", "picomatch": "4.0.4", - "piscina": "5.1.3", - "postcss": "8.5.6", + "piscina": "5.2.0", + "postcss": "8.5.23", "postcss-loader": "8.1.1", "resolve-url-loader": "5.0.0", "rxjs": "7.8.2", @@ -440,7 +425,7 @@ "tslib": "2.8.1", "webpack": "5.105.0", "webpack-dev-middleware": "7.4.2", - "webpack-dev-server": "5.2.2", + "webpack-dev-server": "5.2.6", "webpack-merge": "6.0.1", "webpack-subresource-integrity": "5.1.0" }, @@ -450,7 +435,7 @@ "yarn": ">= 1.13.0" }, "optionalDependencies": { - "esbuild": "0.25.9" + "esbuild": "0.28.1" }, "peerDependencies": { "@angular/compiler-cli": "^20.0.0", @@ -459,7 +444,7 @@ "@angular/platform-browser": "^20.0.0", "@angular/platform-server": "^20.0.0", "@angular/service-worker": "^20.0.0", - "@angular/ssr": "^20.3.22", + "@angular/ssr": "^20.3.35", "@web/test-runner": "^0.20.0", "browser-sync": "^3.0.2", "jest": "^29.5.0 || ^30.2.0", @@ -516,9 +501,9 @@ } }, "node_modules/@angular-devkit/build-angular/node_modules/@angular-devkit/core": { - "version": "20.3.22", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-20.3.22.tgz", - "integrity": "sha512-1vZnZTAjGcCM+86v2al+2eiROiSw0uAWeVllfHSQe0KsKOP1FE8UUUiWChhxVn7vIxypphlfGunkeeIn1C/ZFw==", + "version": "20.3.35", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-20.3.35.tgz", + "integrity": "sha512-RefMFJA7qRBxEDu3a6bVNK9o5vcHXxN8xKaCzENBrOIO6XamthoGMZIJrIT213KpHoEbLTcJjESqGFCpYmY6oA==", "license": "MIT", "dependencies": { "ajv": "8.18.0", @@ -542,219 +527,423 @@ } } }, - "node_modules/@angular-devkit/build-angular/node_modules/ajv": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", - "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", + "node_modules/@angular-devkit/build-angular/node_modules/@esbuild/aix-ppc64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.1.tgz", + "integrity": "sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==", + "cpu": [ + "ppc64" + ], "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" } }, - "node_modules/@angular-devkit/build-angular/node_modules/ajv-formats": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", - "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "node_modules/@angular-devkit/build-angular/node_modules/@esbuild/android-arm": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.1.tgz", + "integrity": "sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==", + "cpu": [ + "arm" + ], "license": "MIT", - "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" } }, - "node_modules/@angular-devkit/build-angular/node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "node_modules/@angular-devkit/build-angular/node_modules/@esbuild/android-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.1.tgz", + "integrity": "sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==", + "cpu": [ + "arm64" + ], "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, + "optional": true, + "os": [ + "android" + ], "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "node": ">=18" } }, - "node_modules/@angular-devkit/build-angular/node_modules/http-proxy-middleware": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-3.0.5.tgz", - "integrity": "sha512-GLZZm1X38BPY4lkXA01jhwxvDoOkkXqjgVyUzVxiEK4iuRu03PZoYHhHRwxnfhQMDuaxi3vVri0YgSro/1oWqg==", + "node_modules/@angular-devkit/build-angular/node_modules/@esbuild/android-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.1.tgz", + "integrity": "sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==", + "cpu": [ + "x64" + ], "license": "MIT", - "dependencies": { - "@types/http-proxy": "^1.17.15", - "debug": "^4.3.6", - "http-proxy": "^1.18.1", - "is-glob": "^4.0.3", - "is-plain-object": "^5.0.0", - "micromatch": "^4.0.8" - }, + "optional": true, + "os": [ + "android" + ], "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=18" } }, - "node_modules/@angular-devkit/build-angular/node_modules/is-plain-object": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "node_modules/@angular-devkit/build-angular/node_modules/@esbuild/darwin-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.1.tgz", + "integrity": "sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==", + "cpu": [ + "arm64" + ], "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=0.10.0" + "node": ">=18" } }, - "node_modules/@angular-devkit/build-angular/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "license": "MIT" - }, - "node_modules/@angular-devkit/build-angular/node_modules/loader-utils": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.3.1.tgz", - "integrity": "sha512-FMJTLMXfCLMLfJxcX9PFqX5qD88Z5MRGaZCVzfuqeZSPsyiBzs+pahDQjbIWz2QIzPZz0NX9Zy4FX3lmK6YHIg==", + "node_modules/@angular-devkit/build-angular/node_modules/@esbuild/darwin-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.1.tgz", + "integrity": "sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==", + "cpu": [ + "x64" + ], "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">= 12.13.0" + "node": ">=18" } }, - "node_modules/@angular-devkit/build-angular/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, - "node_modules/@angular-devkit/build-angular/node_modules/picomatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "node_modules/@angular-devkit/build-angular/node_modules/@esbuild/freebsd-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.1.tgz", + "integrity": "sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==", + "cpu": [ + "arm64" + ], "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" + "node": ">=18" } }, - "node_modules/@angular-devkit/build-angular/node_modules/semver": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", - "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, + "node_modules/@angular-devkit/build-angular/node_modules/@esbuild/freebsd-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.1.tgz", + "integrity": "sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], "engines": { - "node": ">=10" + "node": ">=18" } }, - "node_modules/@angular-devkit/build-angular/node_modules/source-map": { - "version": "0.7.6", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", - "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==", - "license": "BSD-3-Clause", + "node_modules/@angular-devkit/build-angular/node_modules/@esbuild/linux-arm": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.1.tgz", + "integrity": "sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">= 12" + "node": ">=18" } }, - "node_modules/@angular-devkit/build-angular/node_modules/terser": { - "version": "5.43.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.43.1.tgz", - "integrity": "sha512-+6erLbBm0+LROX2sPXlUYx/ux5PyE9K/a92Wrt6oA+WDAoFTdpHE5tCYCI5PNzq2y8df4rA+QgHLJuR4jNymsg==", - "license": "BSD-2-Clause", - "dependencies": { - "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.14.0", - "commander": "^2.20.0", - "source-map-support": "~0.5.20" - }, - "bin": { - "terser": "bin/terser" - }, + "node_modules/@angular-devkit/build-angular/node_modules/@esbuild/linux-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.1.tgz", + "integrity": "sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=10" + "node": ">=18" } }, - "node_modules/@angular-devkit/build-webpack": { - "version": "0.2003.22", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.2003.22.tgz", - "integrity": "sha512-ad4iW5CDGDYFXR9ZpdY8O2n4mx+tJtjx4mfC9Z+0ikwA4ir2IW2BOUhWvJ6IDq3f7kulFxP8S4zWN9r7jsZw3A==", + "node_modules/@angular-devkit/build-angular/node_modules/@esbuild/linux-ia32": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.1.tgz", + "integrity": "sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==", + "cpu": [ + "ia32" + ], "license": "MIT", - "dependencies": { - "@angular-devkit/architect": "0.2003.22", - "rxjs": "7.8.2" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": "^20.19.0 || ^22.12.0 || >=24.0.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - }, - "peerDependencies": { - "webpack": "^5.30.0", - "webpack-dev-server": "^5.0.2" + "node": ">=18" } }, - "node_modules/@angular-devkit/schematics": { - "version": "20.3.22", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-20.3.22.tgz", - "integrity": "sha512-gN2XSXRn3eErGEJlH0iSfQZZ7NdxVZNdjSxuVEGBEFhe3cVeC21LzM3GTWW6xwtBb4pxHglFyc7BUFiYtZiYtg==", + "node_modules/@angular-devkit/build-angular/node_modules/@esbuild/linux-loong64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.1.tgz", + "integrity": "sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==", + "cpu": [ + "loong64" + ], "license": "MIT", - "dependencies": { - "@angular-devkit/core": "20.3.22", - "jsonc-parser": "3.3.1", - "magic-string": "0.30.17", - "ora": "8.2.0", - "rxjs": "7.8.2" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": "^20.19.0 || ^22.12.0 || >=24.0.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" + "node": ">=18" } }, - "node_modules/@angular-devkit/schematics/node_modules/@angular-devkit/core": { - "version": "20.3.22", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-20.3.22.tgz", - "integrity": "sha512-1vZnZTAjGcCM+86v2al+2eiROiSw0uAWeVllfHSQe0KsKOP1FE8UUUiWChhxVn7vIxypphlfGunkeeIn1C/ZFw==", + "node_modules/@angular-devkit/build-angular/node_modules/@esbuild/linux-mips64el": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.1.tgz", + "integrity": "sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==", + "cpu": [ + "mips64el" + ], "license": "MIT", - "dependencies": { - "ajv": "8.18.0", - "ajv-formats": "3.0.1", - "jsonc-parser": "3.3.1", - "picomatch": "4.0.4", - "rxjs": "7.8.2", - "source-map": "0.7.6" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": "^20.19.0 || ^22.12.0 || >=24.0.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - }, - "peerDependencies": { - "chokidar": "^4.0.0" - }, - "peerDependenciesMeta": { - "chokidar": { - "optional": true - } + "node": ">=18" } }, - "node_modules/@angular-devkit/schematics/node_modules/ajv": { + "node_modules/@angular-devkit/build-angular/node_modules/@esbuild/linux-ppc64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.1.tgz", + "integrity": "sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/@esbuild/linux-riscv64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.1.tgz", + "integrity": "sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/@esbuild/linux-s390x": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.1.tgz", + "integrity": "sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/@esbuild/linux-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.1.tgz", + "integrity": "sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/@esbuild/netbsd-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.1.tgz", + "integrity": "sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/@esbuild/netbsd-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.1.tgz", + "integrity": "sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/@esbuild/openbsd-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.1.tgz", + "integrity": "sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/@esbuild/openbsd-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.1.tgz", + "integrity": "sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/@esbuild/openharmony-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.1.tgz", + "integrity": "sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/@esbuild/sunos-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.1.tgz", + "integrity": "sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/@esbuild/win32-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.1.tgz", + "integrity": "sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/@esbuild/win32-ia32": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.1.tgz", + "integrity": "sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/@esbuild/win32-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.1.tgz", + "integrity": "sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/ajv": { "version": "8.18.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", @@ -770,7 +959,7 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/@angular-devkit/schematics/node_modules/ajv-formats": { + "node_modules/@angular-devkit/build-angular/node_modules/ajv-formats": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", @@ -787,13 +976,107 @@ } } }, - "node_modules/@angular-devkit/schematics/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "node_modules/@angular-devkit/build-angular/node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/esbuild": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.1.tgz", + "integrity": "sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.28.1", + "@esbuild/android-arm": "0.28.1", + "@esbuild/android-arm64": "0.28.1", + "@esbuild/android-x64": "0.28.1", + "@esbuild/darwin-arm64": "0.28.1", + "@esbuild/darwin-x64": "0.28.1", + "@esbuild/freebsd-arm64": "0.28.1", + "@esbuild/freebsd-x64": "0.28.1", + "@esbuild/linux-arm": "0.28.1", + "@esbuild/linux-arm64": "0.28.1", + "@esbuild/linux-ia32": "0.28.1", + "@esbuild/linux-loong64": "0.28.1", + "@esbuild/linux-mips64el": "0.28.1", + "@esbuild/linux-ppc64": "0.28.1", + "@esbuild/linux-riscv64": "0.28.1", + "@esbuild/linux-s390x": "0.28.1", + "@esbuild/linux-x64": "0.28.1", + "@esbuild/netbsd-arm64": "0.28.1", + "@esbuild/netbsd-x64": "0.28.1", + "@esbuild/openbsd-arm64": "0.28.1", + "@esbuild/openbsd-x64": "0.28.1", + "@esbuild/openharmony-arm64": "0.28.1", + "@esbuild/sunos-x64": "0.28.1", + "@esbuild/win32-arm64": "0.28.1", + "@esbuild/win32-ia32": "0.28.1", + "@esbuild/win32-x64": "0.28.1" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/http-proxy-middleware": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-3.0.7.tgz", + "integrity": "sha512-iwbQltVlx8bCrqePUM8C+hllHvdawVhQJaLrj1X7qllkvFQdXFsr16pW/mo9+JDVjN+QO2XUx9jd8SmoFkE5qw==", + "license": "MIT", + "dependencies": { + "@types/http-proxy": "^1.17.15", + "debug": "^4.3.6", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.3", + "is-plain-object": "^5.0.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": "^14.18.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/is-plain-object": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.1.0.tgz", + "integrity": "sha512-bUi/yjmtKYcRVUtWRGr0UA6xEFh2I6zWUwMrUXB3s7bmYCaZ8a+0ZsTRkrawh/mzlSD1Y0Ph8bp/U+TvBpWDNw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/loader-utils": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.3.1.tgz", + "integrity": "sha512-FMJTLMXfCLMLfJxcX9PFqX5qD88Z5MRGaZCVzfuqeZSPsyiBzs+pahDQjbIWz2QIzPZz0NX9Zy4FX3lmK6YHIg==", + "license": "MIT", + "engines": { + "node": ">= 12.13.0" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "license": "MIT" }, - "node_modules/@angular-devkit/schematics/node_modules/picomatch": { + "node_modules/@angular-devkit/build-angular/node_modules/picomatch": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", @@ -805,7 +1088,19 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/@angular-devkit/schematics/node_modules/source-map": { + "node_modules/@angular-devkit/build-angular/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/source-map": { "version": "0.7.6", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==", @@ -814,37 +1109,174 @@ "node": ">= 12" } }, - "node_modules/@angular/animations": { - "version": "20.3.18", - "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-20.3.18.tgz", - "integrity": "sha512-XFxgSyjfs0SRD2vQVFJljmM4z9nTvUoI8TRqSre/+l8D2FgzD5pG67Aj2BgDgpSFAUkIcI37G48ijK7a3ZZ3WA==", - "license": "MIT", - "dependencies": { - "tslib": "^2.3.0" + "node_modules/@angular-devkit/build-angular/node_modules/terser": { + "version": "5.43.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.43.1.tgz", + "integrity": "sha512-+6erLbBm0+LROX2sPXlUYx/ux5PyE9K/a92Wrt6oA+WDAoFTdpHE5tCYCI5PNzq2y8df4rA+QgHLJuR4jNymsg==", + "license": "BSD-2-Clause", + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.14.0", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@angular-devkit/build-webpack": { + "version": "0.2003.35", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.2003.35.tgz", + "integrity": "sha512-RrWsGWaomLFcWYFWKxCrIXkh6ka4R+TRFpDrrJqZXp72GYb3XYW+lmH1Si6I9HKd8drtAe1uftKQszI7qKN3yw==", + "license": "MIT", + "dependencies": { + "@angular-devkit/architect": "0.2003.35", + "rxjs": "7.8.2" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "webpack": "^5.30.0", + "webpack-dev-server": "^5.0.2" + } + }, + "node_modules/@angular-devkit/schematics": { + "version": "20.3.35", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-20.3.35.tgz", + "integrity": "sha512-7lzrY5pYCTvL9dR/pi4fzAl1BS8PdiplTd+QNFEJv7/rZWTmqt+7rmDHm/8vEl1aYEFmBckzb3PMK+NBMuQkaw==", + "license": "MIT", + "dependencies": { + "@angular-devkit/core": "20.3.35", + "jsonc-parser": "3.3.1", + "magic-string": "0.30.17", + "ora": "8.2.0", + "rxjs": "7.8.2" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@angular-devkit/schematics/node_modules/@angular-devkit/core": { + "version": "20.3.35", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-20.3.35.tgz", + "integrity": "sha512-RefMFJA7qRBxEDu3a6bVNK9o5vcHXxN8xKaCzENBrOIO6XamthoGMZIJrIT213KpHoEbLTcJjESqGFCpYmY6oA==", + "license": "MIT", + "dependencies": { + "ajv": "8.18.0", + "ajv-formats": "3.0.1", + "jsonc-parser": "3.3.1", + "picomatch": "4.0.4", + "rxjs": "7.8.2", + "source-map": "0.7.6" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "chokidar": "^4.0.0" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/@angular-devkit/schematics/node_modules/ajv": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", + "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@angular-devkit/schematics/node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/@angular-devkit/schematics/node_modules/picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/@angular-devkit/schematics/node_modules/source-map": { + "version": "0.7.6", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", + "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==", + "license": "BSD-3-Clause", + "engines": { + "node": ">= 12" + } + }, + "node_modules/@angular/animations": { + "version": "20.3.29", + "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-20.3.29.tgz", + "integrity": "sha512-4ailq4Mg9I+GlcR8hk8gTcIFFpzyPEPvYwbYLSHIzpSJHKAq1kFZ17UEg0Bq+oJiyTylKHeV3CpYCS+I7sVaGg==", + "deprecated": "@angular/animations is deprecated. Use `animate.enter` and `animate.leave` instead. For more information see: https://v22.angular.dev/guide/animations.", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" }, "engines": { "node": "^20.19.0 || ^22.12.0 || >=24.0.0" }, "peerDependencies": { - "@angular/core": "20.3.18" + "@angular/core": "20.3.29" } }, "node_modules/@angular/build": { - "version": "20.3.22", - "resolved": "https://registry.npmjs.org/@angular/build/-/build-20.3.22.tgz", - "integrity": "sha512-sxjVZU6AZHXyKRHJUMawXOj4qMf3vm8XK6wUejr01UKj6BqW2YWaQO26RpRJssXD2ITTqn6+UBwL7pEwe2a4Jg==", + "version": "20.3.35", + "resolved": "https://registry.npmjs.org/@angular/build/-/build-20.3.35.tgz", + "integrity": "sha512-NwVaMXFZRfmpwodXwwoPXJw6eDZtG+HuBEjGMwyvGoGSMUc12MxKvgTash94pXqhe9SiwZTRgm3oVwrjG//2OA==", "license": "MIT", "dependencies": { "@ampproject/remapping": "2.3.0", - "@angular-devkit/architect": "0.2003.22", - "@babel/core": "7.28.3", + "@angular-devkit/architect": "0.2003.35", + "@babel/core": "7.29.7", "@babel/helper-annotate-as-pure": "7.27.3", "@babel/helper-split-export-declaration": "7.24.7", "@inquirer/confirm": "5.1.14", "@vitejs/plugin-basic-ssl": "2.1.0", "beasties": "0.3.5", "browserslist": "^4.23.0", - "esbuild": "0.25.9", + "esbuild": "0.28.1", "https-proxy-agent": "7.0.6", "istanbul-lib-instrument": "6.0.3", "jsonc-parser": "3.3.1", @@ -853,13 +1285,13 @@ "mrmime": "2.0.1", "parse5-html-rewriting-stream": "8.0.0", "picomatch": "4.0.4", - "piscina": "5.1.3", + "piscina": "5.2.0", "rollup": "4.59.0", "sass": "1.90.0", "semver": "7.7.2", "source-map-support": "0.5.21", "tinyglobby": "0.2.14", - "vite": "7.1.11", + "vite": "7.3.6", "watchpack": "2.4.4" }, "engines": { @@ -878,7 +1310,7 @@ "@angular/platform-browser": "^20.0.0", "@angular/platform-server": "^20.0.0", "@angular/service-worker": "^20.0.0", - "@angular/ssr": "^20.3.22", + "@angular/ssr": "^20.3.35", "karma": "^6.4.0", "less": "^4.2.0", "ng-packagr": "^20.0.0", @@ -927,428 +1359,426 @@ } } }, - "node_modules/@angular/build/node_modules/ansi-escapes": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.3.0.tgz", - "integrity": "sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg==", + "node_modules/@angular/build/node_modules/@esbuild/aix-ppc64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.1.tgz", + "integrity": "sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==", + "cpu": [ + "ppc64" + ], "license": "MIT", - "dependencies": { - "environment": "^1.0.0" - }, + "optional": true, + "os": [ + "aix" + ], "engines": { "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@angular/build/node_modules/ansi-regex": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", - "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "node_modules/@angular/build/node_modules/@esbuild/android-arm": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.1.tgz", + "integrity": "sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==", + "cpu": [ + "arm" + ], "license": "MIT", + "optional": true, + "os": [ + "android" + ], "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" + "node": ">=18" } }, - "node_modules/@angular/build/node_modules/ansi-styles": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", - "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "node_modules/@angular/build/node_modules/@esbuild/android-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.1.tgz", + "integrity": "sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==", + "cpu": [ + "arm64" + ], "license": "MIT", + "optional": true, + "os": [ + "android" + ], "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "node": ">=18" } }, - "node_modules/@angular/build/node_modules/cli-cursor": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", - "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", + "node_modules/@angular/build/node_modules/@esbuild/android-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.1.tgz", + "integrity": "sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==", + "cpu": [ + "x64" + ], "license": "MIT", - "dependencies": { - "restore-cursor": "^5.0.0" - }, + "optional": true, + "os": [ + "android" + ], "engines": { "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@angular/build/node_modules/cli-truncate": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-4.0.0.tgz", - "integrity": "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==", + "node_modules/@angular/build/node_modules/@esbuild/darwin-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.1.tgz", + "integrity": "sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==", + "cpu": [ + "arm64" + ], "license": "MIT", - "dependencies": { - "slice-ansi": "^5.0.0", - "string-width": "^7.0.0" - }, + "optional": true, + "os": [ + "darwin" + ], "engines": { "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@angular/build/node_modules/emoji-regex": { - "version": "10.6.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", - "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", - "license": "MIT" - }, - "node_modules/@angular/build/node_modules/eventemitter3": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz", - "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==", - "license": "MIT" + "node_modules/@angular/build/node_modules/@esbuild/darwin-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.1.tgz", + "integrity": "sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } }, - "node_modules/@angular/build/node_modules/is-fullwidth-code-point": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", - "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", + "node_modules/@angular/build/node_modules/@esbuild/freebsd-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.1.tgz", + "integrity": "sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==", + "cpu": [ + "arm64" + ], "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=18" } }, - "node_modules/@angular/build/node_modules/listr2": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-9.0.1.tgz", - "integrity": "sha512-SL0JY3DaxylDuo/MecFeiC+7pedM0zia33zl0vcjgwcq1q1FWWF1To9EIauPbl8GbMCU0R2e0uJ8bZunhYKD2g==", + "node_modules/@angular/build/node_modules/@esbuild/freebsd-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.1.tgz", + "integrity": "sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==", + "cpu": [ + "x64" + ], "license": "MIT", - "dependencies": { - "cli-truncate": "^4.0.0", - "colorette": "^2.0.20", - "eventemitter3": "^5.0.1", - "log-update": "^6.1.0", - "rfdc": "^1.4.1", - "wrap-ansi": "^9.0.0" - }, + "optional": true, + "os": [ + "freebsd" + ], "engines": { - "node": ">=20.0.0" + "node": ">=18" } }, - "node_modules/@angular/build/node_modules/log-update": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.1.0.tgz", - "integrity": "sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==", + "node_modules/@angular/build/node_modules/@esbuild/linux-arm": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.1.tgz", + "integrity": "sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==", + "cpu": [ + "arm" + ], "license": "MIT", - "dependencies": { - "ansi-escapes": "^7.0.0", - "cli-cursor": "^5.0.0", - "slice-ansi": "^7.1.0", - "strip-ansi": "^7.1.0", - "wrap-ansi": "^9.0.0" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@angular/build/node_modules/log-update/node_modules/is-fullwidth-code-point": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.1.0.tgz", - "integrity": "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==", + "node_modules/@angular/build/node_modules/@esbuild/linux-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.1.tgz", + "integrity": "sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==", + "cpu": [ + "arm64" + ], "license": "MIT", - "dependencies": { - "get-east-asian-width": "^1.3.1" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@angular/build/node_modules/log-update/node_modules/slice-ansi": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.2.tgz", - "integrity": "sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w==", + "node_modules/@angular/build/node_modules/@esbuild/linux-ia32": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.1.tgz", + "integrity": "sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==", + "cpu": [ + "ia32" + ], "license": "MIT", - "dependencies": { - "ansi-styles": "^6.2.1", - "is-fullwidth-code-point": "^5.0.0" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { "node": ">=18" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, - "node_modules/@angular/build/node_modules/onetime": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", - "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", + "node_modules/@angular/build/node_modules/@esbuild/linux-loong64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.1.tgz", + "integrity": "sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==", + "cpu": [ + "loong64" + ], "license": "MIT", - "dependencies": { - "mimic-function": "^5.0.0" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@angular/build/node_modules/picomatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "node_modules/@angular/build/node_modules/@esbuild/linux-mips64el": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.1.tgz", + "integrity": "sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==", + "cpu": [ + "mips64el" + ], "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" + "node": ">=18" } }, - "node_modules/@angular/build/node_modules/restore-cursor": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", - "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", + "node_modules/@angular/build/node_modules/@esbuild/linux-ppc64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.1.tgz", + "integrity": "sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==", + "cpu": [ + "ppc64" + ], "license": "MIT", - "dependencies": { - "onetime": "^7.0.0", - "signal-exit": "^4.1.0" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@angular/build/node_modules/semver": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", - "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" } }, - "node_modules/@angular/build/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "license": "ISC", + "node_modules/@angular/build/node_modules/@esbuild/linux-riscv64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.1.tgz", + "integrity": "sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": ">=18" } }, - "node_modules/@angular/build/node_modules/slice-ansi": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", - "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", + "node_modules/@angular/build/node_modules/@esbuild/linux-s390x": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.1.tgz", + "integrity": "sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==", + "cpu": [ + "s390x" + ], "license": "MIT", - "dependencies": { - "ansi-styles": "^6.0.0", - "is-fullwidth-code-point": "^4.0.0" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" + "node": ">=18" } }, - "node_modules/@angular/build/node_modules/string-width": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", - "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "node_modules/@angular/build/node_modules/@esbuild/linux-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.1.tgz", + "integrity": "sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==", + "cpu": [ + "x64" + ], "license": "MIT", - "dependencies": { - "emoji-regex": "^10.3.0", - "get-east-asian-width": "^1.0.0", - "strip-ansi": "^7.1.0" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@angular/build/node_modules/strip-ansi": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", - "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "node_modules/@angular/build/node_modules/@esbuild/netbsd-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.1.tgz", + "integrity": "sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==", + "cpu": [ + "arm64" + ], "license": "MIT", - "dependencies": { - "ansi-regex": "^6.2.2" - }, + "optional": true, + "os": [ + "netbsd" + ], "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" + "node": ">=18" } }, - "node_modules/@angular/build/node_modules/wrap-ansi": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", - "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", + "node_modules/@angular/build/node_modules/@esbuild/netbsd-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.1.tgz", + "integrity": "sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==", + "cpu": [ + "x64" + ], "license": "MIT", - "dependencies": { - "ansi-styles": "^6.2.1", - "string-width": "^7.0.0", - "strip-ansi": "^7.1.0" - }, + "optional": true, + "os": [ + "netbsd" + ], "engines": { "node": ">=18" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/@angular/cli": { - "version": "20.3.22", - "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-20.3.22.tgz", - "integrity": "sha512-0uyQPF0gGuzioWJKNyOzWSQrrC5GiidR+8gz1lODoJTnJZZdsP5n3nvccbcRmhy55B1WByHvQBE+6eDBbh06/g==", + "node_modules/@angular/build/node_modules/@esbuild/openbsd-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.1.tgz", + "integrity": "sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==", + "cpu": [ + "arm64" + ], "license": "MIT", - "dependencies": { - "@angular-devkit/architect": "0.2003.22", - "@angular-devkit/core": "20.3.22", - "@angular-devkit/schematics": "20.3.22", - "@inquirer/prompts": "7.8.2", - "@listr2/prompt-adapter-inquirer": "3.0.1", - "@modelcontextprotocol/sdk": "1.26.0", - "@schematics/angular": "20.3.22", - "@yarnpkg/lockfile": "1.1.0", - "algoliasearch": "5.35.0", - "ini": "5.0.0", - "jsonc-parser": "3.3.1", - "listr2": "9.0.1", - "npm-package-arg": "13.0.0", - "pacote": "21.0.4", - "resolve": "1.22.10", - "semver": "7.7.2", - "yargs": "18.0.0", - "zod": "4.1.13" - }, - "bin": { - "ng": "bin/ng.js" - }, + "optional": true, + "os": [ + "openbsd" + ], "engines": { - "node": "^20.19.0 || ^22.12.0 || >=24.0.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" + "node": ">=18" } }, - "node_modules/@angular/cli/node_modules/@angular-devkit/core": { - "version": "20.3.22", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-20.3.22.tgz", - "integrity": "sha512-1vZnZTAjGcCM+86v2al+2eiROiSw0uAWeVllfHSQe0KsKOP1FE8UUUiWChhxVn7vIxypphlfGunkeeIn1C/ZFw==", + "node_modules/@angular/build/node_modules/@esbuild/openbsd-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.1.tgz", + "integrity": "sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==", + "cpu": [ + "x64" + ], "license": "MIT", - "dependencies": { - "ajv": "8.18.0", - "ajv-formats": "3.0.1", - "jsonc-parser": "3.3.1", - "picomatch": "4.0.4", - "rxjs": "7.8.2", - "source-map": "0.7.6" - }, + "optional": true, + "os": [ + "openbsd" + ], "engines": { - "node": "^20.19.0 || ^22.12.0 || >=24.0.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - }, - "peerDependencies": { - "chokidar": "^4.0.0" - }, - "peerDependenciesMeta": { - "chokidar": { - "optional": true - } + "node": ">=18" } }, - "node_modules/@angular/cli/node_modules/@listr2/prompt-adapter-inquirer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@listr2/prompt-adapter-inquirer/-/prompt-adapter-inquirer-3.0.1.tgz", - "integrity": "sha512-3XFmGwm3u6ioREG+ynAQB7FoxfajgQnMhIu8wC5eo/Lsih4aKDg0VuIMGaOsYn7hJSJagSeaD4K8yfpkEoDEmA==", + "node_modules/@angular/build/node_modules/@esbuild/openharmony-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.1.tgz", + "integrity": "sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==", + "cpu": [ + "arm64" + ], "license": "MIT", - "dependencies": { - "@inquirer/type": "^3.0.7" - }, + "optional": true, + "os": [ + "openharmony" + ], "engines": { - "node": ">=20.0.0" - }, - "peerDependencies": { - "@inquirer/prompts": ">= 3 < 8", - "listr2": "9.0.1" + "node": ">=18" } }, - "node_modules/@angular/cli/node_modules/ajv": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", - "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", + "node_modules/@angular/build/node_modules/@esbuild/sunos-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.1.tgz", + "integrity": "sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==", + "cpu": [ + "x64" + ], "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" } }, - "node_modules/@angular/cli/node_modules/ajv-formats": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", - "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "node_modules/@angular/build/node_modules/@esbuild/win32-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.1.tgz", + "integrity": "sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==", + "cpu": [ + "arm64" + ], "license": "MIT", - "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" } }, - "node_modules/@angular/cli/node_modules/ansi-escapes": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.3.0.tgz", - "integrity": "sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg==", + "node_modules/@angular/build/node_modules/@esbuild/win32-ia32": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.1.tgz", + "integrity": "sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==", + "cpu": [ + "ia32" + ], "license": "MIT", - "dependencies": { - "environment": "^1.0.0" - }, + "optional": true, + "os": [ + "win32" + ], "engines": { "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@angular/cli/node_modules/ansi-regex": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", - "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "node_modules/@angular/build/node_modules/@esbuild/win32-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.1.tgz", + "integrity": "sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@angular/build/node_modules/ansi-regex": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.3.0.tgz", + "integrity": "sha512-WpDfL7NO6j7tH88IDBNVdUJxDh9nmCteAVW9dsep846XdwF4naCBK+/tGLX3KJgcpgMRXCFlTM2hKGoK9FsdrQ==", "license": "MIT", "engines": { "node": ">=12" @@ -1357,7 +1787,7 @@ "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, - "node_modules/@angular/cli/node_modules/ansi-styles": { + "node_modules/@angular/build/node_modules/ansi-styles": { "version": "6.2.3", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", @@ -1369,22 +1799,7 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/@angular/cli/node_modules/cli-cursor": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", - "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", - "license": "MIT", - "dependencies": { - "restore-cursor": "^5.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@angular/cli/node_modules/cli-truncate": { + "node_modules/@angular/build/node_modules/cli-truncate": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-4.0.0.tgz", "integrity": "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==", @@ -1400,19 +1815,60 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@angular/cli/node_modules/emoji-regex": { + "node_modules/@angular/build/node_modules/emoji-regex": { "version": "10.6.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", "license": "MIT" }, - "node_modules/@angular/cli/node_modules/eventemitter3": { + "node_modules/@angular/build/node_modules/esbuild": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.1.tgz", + "integrity": "sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.28.1", + "@esbuild/android-arm": "0.28.1", + "@esbuild/android-arm64": "0.28.1", + "@esbuild/android-x64": "0.28.1", + "@esbuild/darwin-arm64": "0.28.1", + "@esbuild/darwin-x64": "0.28.1", + "@esbuild/freebsd-arm64": "0.28.1", + "@esbuild/freebsd-x64": "0.28.1", + "@esbuild/linux-arm": "0.28.1", + "@esbuild/linux-arm64": "0.28.1", + "@esbuild/linux-ia32": "0.28.1", + "@esbuild/linux-loong64": "0.28.1", + "@esbuild/linux-mips64el": "0.28.1", + "@esbuild/linux-ppc64": "0.28.1", + "@esbuild/linux-riscv64": "0.28.1", + "@esbuild/linux-s390x": "0.28.1", + "@esbuild/linux-x64": "0.28.1", + "@esbuild/netbsd-arm64": "0.28.1", + "@esbuild/netbsd-x64": "0.28.1", + "@esbuild/openbsd-arm64": "0.28.1", + "@esbuild/openbsd-x64": "0.28.1", + "@esbuild/openharmony-arm64": "0.28.1", + "@esbuild/sunos-x64": "0.28.1", + "@esbuild/win32-arm64": "0.28.1", + "@esbuild/win32-ia32": "0.28.1", + "@esbuild/win32-x64": "0.28.1" + } + }, + "node_modules/@angular/build/node_modules/eventemitter3": { "version": "5.0.4", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz", "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==", "license": "MIT" }, - "node_modules/@angular/cli/node_modules/is-fullwidth-code-point": { + "node_modules/@angular/build/node_modules/is-fullwidth-code-point": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", @@ -1424,13 +1880,7 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@angular/cli/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "license": "MIT" - }, - "node_modules/@angular/cli/node_modules/listr2": { + "node_modules/@angular/build/node_modules/listr2": { "version": "9.0.1", "resolved": "https://registry.npmjs.org/listr2/-/listr2-9.0.1.tgz", "integrity": "sha512-SL0JY3DaxylDuo/MecFeiC+7pedM0zia33zl0vcjgwcq1q1FWWF1To9EIauPbl8GbMCU0R2e0uJ8bZunhYKD2g==", @@ -1447,63 +1897,55 @@ "node": ">=20.0.0" } }, - "node_modules/@angular/cli/node_modules/log-update": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.1.0.tgz", - "integrity": "sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==", + "node_modules/@angular/build/node_modules/picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "license": "MIT", - "dependencies": { - "ansi-escapes": "^7.0.0", - "cli-cursor": "^5.0.0", - "slice-ansi": "^7.1.0", - "strip-ansi": "^7.1.0", - "wrap-ansi": "^9.0.0" - }, "engines": { - "node": ">=18" + "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/@angular/cli/node_modules/log-update/node_modules/is-fullwidth-code-point": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.1.0.tgz", - "integrity": "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==", - "license": "MIT", - "dependencies": { - "get-east-asian-width": "^1.3.1" + "node_modules/@angular/build/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" }, "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=10" } }, - "node_modules/@angular/cli/node_modules/log-update/node_modules/slice-ansi": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.2.tgz", - "integrity": "sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w==", + "node_modules/@angular/build/node_modules/slice-ansi": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", + "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", "license": "MIT", "dependencies": { - "ansi-styles": "^6.2.1", - "is-fullwidth-code-point": "^5.0.0" + "ansi-styles": "^6.0.0", + "is-fullwidth-code-point": "^4.0.0" }, "engines": { - "node": ">=18" + "node": ">=12" }, "funding": { "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, - "node_modules/@angular/cli/node_modules/onetime": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", - "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", + "node_modules/@angular/build/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", "license": "MIT", "dependencies": { - "mimic-function": "^5.0.0" + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" }, "engines": { "node": ">=18" @@ -1512,56 +1954,251 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@angular/cli/node_modules/picomatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "node_modules/@angular/build/node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, "engines": { "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/jonschlinkert" + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "node_modules/@angular/cli/node_modules/restore-cursor": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", - "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", + "node_modules/@angular/build/node_modules/wrap-ansi": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", "license": "MIT", "dependencies": { - "onetime": "^7.0.0", - "signal-exit": "^4.1.0" + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" }, "engines": { "node": ">=18" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/@angular/cli/node_modules/semver": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", - "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" + "node_modules/@angular/cli": { + "version": "20.3.35", + "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-20.3.35.tgz", + "integrity": "sha512-pKzfR4FslcKDELiUQD2zu1obx5A7pTZC3l2/TgFtVdx0N/cUZz5TlFTa6CQaq8r6P6/4ZchzCIVNGUjkkLfjxw==", + "license": "MIT", + "dependencies": { + "@angular-devkit/architect": "0.2003.35", + "@angular-devkit/core": "20.3.35", + "@angular-devkit/schematics": "20.3.35", + "@inquirer/prompts": "7.8.2", + "@listr2/prompt-adapter-inquirer": "3.0.1", + "@modelcontextprotocol/sdk": "1.30.0", + "@schematics/angular": "20.3.35", + "@yarnpkg/lockfile": "1.1.0", + "algoliasearch": "5.35.0", + "ini": "5.0.0", + "jsonc-parser": "3.3.1", + "listr2": "9.0.1", + "npm-package-arg": "13.0.0", + "pacote": "21.5.1", + "resolve": "1.22.10", + "semver": "7.7.2", + "yargs": "18.0.0", + "zod": "4.1.13" + }, + "bin": { + "ng": "bin/ng.js" }, "engines": { - "node": ">=10" + "node": "^20.19.0 || ^22.12.0 || >=24.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" } }, - "node_modules/@angular/cli/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "license": "ISC", + "node_modules/@angular/cli/node_modules/@angular-devkit/core": { + "version": "20.3.35", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-20.3.35.tgz", + "integrity": "sha512-RefMFJA7qRBxEDu3a6bVNK9o5vcHXxN8xKaCzENBrOIO6XamthoGMZIJrIT213KpHoEbLTcJjESqGFCpYmY6oA==", + "license": "MIT", + "dependencies": { + "ajv": "8.18.0", + "ajv-formats": "3.0.1", + "jsonc-parser": "3.3.1", + "picomatch": "4.0.4", + "rxjs": "7.8.2", + "source-map": "0.7.6" + }, "engines": { - "node": ">=14" + "node": "^20.19.0 || ^22.12.0 || >=24.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "chokidar": "^4.0.0" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/@angular/cli/node_modules/@listr2/prompt-adapter-inquirer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@listr2/prompt-adapter-inquirer/-/prompt-adapter-inquirer-3.0.1.tgz", + "integrity": "sha512-3XFmGwm3u6ioREG+ynAQB7FoxfajgQnMhIu8wC5eo/Lsih4aKDg0VuIMGaOsYn7hJSJagSeaD4K8yfpkEoDEmA==", + "license": "MIT", + "dependencies": { + "@inquirer/type": "^3.0.7" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@inquirer/prompts": ">= 3 < 8", + "listr2": "9.0.1" + } + }, + "node_modules/@angular/cli/node_modules/ajv": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", + "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@angular/cli/node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/@angular/cli/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@angular/cli/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@angular/cli/node_modules/cli-truncate": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-4.0.0.tgz", + "integrity": "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==", + "license": "MIT", + "dependencies": { + "slice-ansi": "^5.0.0", + "string-width": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@angular/cli/node_modules/emoji-regex": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "license": "MIT" + }, + "node_modules/@angular/cli/node_modules/eventemitter3": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz", + "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==", + "license": "MIT" + }, + "node_modules/@angular/cli/node_modules/is-fullwidth-code-point": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", + "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@angular/cli/node_modules/listr2": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-9.0.1.tgz", + "integrity": "sha512-SL0JY3DaxylDuo/MecFeiC+7pedM0zia33zl0vcjgwcq1q1FWWF1To9EIauPbl8GbMCU0R2e0uJ8bZunhYKD2g==", + "license": "MIT", + "dependencies": { + "cli-truncate": "^4.0.0", + "colorette": "^2.0.20", + "eventemitter3": "^5.0.1", + "log-update": "^6.1.0", + "rfdc": "^1.4.1", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@angular/cli/node_modules/picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/@angular/cli/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, "node_modules/@angular/cli/node_modules/slice-ansi": { @@ -1639,9 +2276,9 @@ } }, "node_modules/@angular/common": { - "version": "20.3.18", - "resolved": "https://registry.npmjs.org/@angular/common/-/common-20.3.18.tgz", - "integrity": "sha512-M62oQbSTRmnGavIVCwimoadg/PDWadgNhactMm9fgH0eM9rx+iWBAYJk4VufO0bwOhysFpRZpJgXlFjOifz/Jw==", + "version": "20.3.29", + "resolved": "https://registry.npmjs.org/@angular/common/-/common-20.3.29.tgz", + "integrity": "sha512-tlX353N11Uu9Cqn7EssfQNh7zjML9ddHRzhlo+3rsaxd+ngqsFpXieogBUSoo5yDhY3ACam/Bls9aGMfklr2SA==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -1650,14 +2287,14 @@ "node": "^20.19.0 || ^22.12.0 || >=24.0.0" }, "peerDependencies": { - "@angular/core": "20.3.18", + "@angular/core": "20.3.29", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/compiler": { - "version": "20.3.18", - "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-20.3.18.tgz", - "integrity": "sha512-AaP/LCiDNcYmF135EEozjyR04NRBT38ZfBHQwjhgwiBBTejmvcpHwJaHSkraLpZqZzE4BQqqmgiQ1EJqxEwLVA==", + "version": "20.3.29", + "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-20.3.29.tgz", + "integrity": "sha512-AgR6Wq9ht5mpliSkJoUvWBILVLFdM7cEQ42pQIlPfGivmVp6Pe0eFqZezsmdDqlu4lsfWBei/FpzQbwak46DLw==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -1667,12 +2304,12 @@ } }, "node_modules/@angular/compiler-cli": { - "version": "20.3.18", - "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-20.3.18.tgz", - "integrity": "sha512-zsoEgLgnblmRbi47YwMghKirJ8IBKJ3+I8TxLBRIBrhx+KHFp+6oeDeLyu9H+djdyk88zexVd09wzR/YK73F0g==", + "version": "20.3.29", + "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-20.3.29.tgz", + "integrity": "sha512-p4Qru/CRyBlk4Q4U2OXKkG1Ua5gbjQZuoGXAEIj9twwBvUWN159zCTuIgwdGj+KpmjHP/LcyCz25FZFSJN975A==", "license": "MIT", "dependencies": { - "@babel/core": "7.28.3", + "@babel/core": "7.29.7", "@jridgewell/sourcemap-codec": "^1.4.14", "chokidar": "^4.0.0", "convert-source-map": "^1.5.1", @@ -1689,7 +2326,7 @@ "node": "^20.19.0 || ^22.12.0 || >=24.0.0" }, "peerDependencies": { - "@angular/compiler": "20.3.18", + "@angular/compiler": "20.3.29", "typescript": ">=5.8 <6.0" }, "peerDependenciesMeta": { @@ -1727,9 +2364,9 @@ } }, "node_modules/@angular/core": { - "version": "20.3.18", - "resolved": "https://registry.npmjs.org/@angular/core/-/core-20.3.18.tgz", - "integrity": "sha512-B+NQQngd/aDbcfW0zGLis3wTLDeHTeTYMl/mGKQH+HwdPaRCKI1wEtaXaOYVJXkP2FeThocPevB8gLwNlPQUUw==", + "version": "20.3.29", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-20.3.29.tgz", + "integrity": "sha512-aOgEd1+YxC1bcn6Mju0rfz/2/yJyOGd38qY+DEaRDIS24nB6Epr6i0fY6OUW2uDG/nQUyY9kt1L7xjg+1aVitQ==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -1738,7 +2375,7 @@ "node": "^20.19.0 || ^22.12.0 || >=24.0.0" }, "peerDependencies": { - "@angular/compiler": "20.3.18", + "@angular/compiler": "20.3.29", "rxjs": "^6.5.3 || ^7.4.0", "zone.js": "~0.15.0" }, @@ -1752,9 +2389,9 @@ } }, "node_modules/@angular/forms": { - "version": "20.3.18", - "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-20.3.18.tgz", - "integrity": "sha512-x6/99LfxolyZIFUL3Wr0OrtuXHEDwEz/rwx+WzE7NL+n35yO40t3kp0Sn5uMFwI94i91QZJmXHltMpZhrVLuYg==", + "version": "20.3.29", + "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-20.3.29.tgz", + "integrity": "sha512-SK2wW2o7LMoMvzScihs4H4L03PPy5lS3/vNfB3J53C5BW9g1fm3NIvkIHzww2pTvildTvVdRAcdWDDYTCkxcyw==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -1763,16 +2400,16 @@ "node": "^20.19.0 || ^22.12.0 || >=24.0.0" }, "peerDependencies": { - "@angular/common": "20.3.18", - "@angular/core": "20.3.18", - "@angular/platform-browser": "20.3.18", + "@angular/common": "20.3.29", + "@angular/core": "20.3.29", + "@angular/platform-browser": "20.3.29", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/language-service": { - "version": "20.3.18", - "resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-20.3.18.tgz", - "integrity": "sha512-V1ZBqeTtZYH9H8/G1qCw6gafsJmhMIMFjLX0Hv2KpTpmfK9nxIHPEVnshr3xT+qKYJIrMV/cU5YOzInEapLpuQ==", + "version": "20.3.29", + "resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-20.3.29.tgz", + "integrity": "sha512-2XZpg+Dx3a37o3vO6Zp2As6G0cUoKcsGYdi95HwuPxTeNIuDltN6dnV1dOI57eOUcY9pbSm3iVui6j2yHRMP6A==", "dev": true, "license": "MIT", "engines": { @@ -1780,12 +2417,12 @@ } }, "node_modules/@angular/localize": { - "version": "20.3.18", - "resolved": "https://registry.npmjs.org/@angular/localize/-/localize-20.3.18.tgz", - "integrity": "sha512-Zx7LiyMjTvooPhy/r6RoyWzGECfWiA8jH4zwsa/xPF6RX8MD/hOi8vcS4UxTdLSWB4lM5ZtSifAnOfwcm/0CyQ==", + "version": "20.3.29", + "resolved": "https://registry.npmjs.org/@angular/localize/-/localize-20.3.29.tgz", + "integrity": "sha512-4Tki/OueuizK4apx2hOtuah22Dl0ByEBKcTt9oLVNUamb0IqVjkSBs7I+ankQ6LkA9zOCjR4p3Y2E/ceQ9Z5sw==", "license": "MIT", "dependencies": { - "@babel/core": "7.28.3", + "@babel/core": "7.29.7", "@types/babel__core": "7.20.5", "tinyglobby": "^0.2.12", "yargs": "^18.0.0" @@ -1799,14 +2436,14 @@ "node": "^20.19.0 || ^22.12.0 || >=24.0.0" }, "peerDependencies": { - "@angular/compiler": "20.3.18", - "@angular/compiler-cli": "20.3.18" + "@angular/compiler": "20.3.29", + "@angular/compiler-cli": "20.3.29" } }, "node_modules/@angular/platform-browser": { - "version": "20.3.18", - "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-20.3.18.tgz", - "integrity": "sha512-q6s5rEN1yYazpHYp+k4pboXRzMsRB9auzTRBEhyXSGYxqzrnn3qHN0DqgsLC9WAdyhCgnIEMFA8kRT+W277DqQ==", + "version": "20.3.29", + "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-20.3.29.tgz", + "integrity": "sha512-Mrk4Clmi1bTDTn6YBHfb4Fa9t2o6T8ml5DgooZPz2XCun/UlqYFwz+xBWQvWTEyzvDF9g7fu+Gpe4b/LHYHEYg==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -1815,9 +2452,9 @@ "node": "^20.19.0 || ^22.12.0 || >=24.0.0" }, "peerDependencies": { - "@angular/animations": "20.3.18", - "@angular/common": "20.3.18", - "@angular/core": "20.3.18" + "@angular/animations": "20.3.29", + "@angular/common": "20.3.29", + "@angular/core": "20.3.29" }, "peerDependenciesMeta": { "@angular/animations": { @@ -1826,9 +2463,10 @@ } }, "node_modules/@angular/platform-browser-dynamic": { - "version": "20.3.18", - "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-20.3.18.tgz", - "integrity": "sha512-NyTobOGYVzGmPmtI+3lxMzxi0TbLq4SRNQ2ENEJAt6k2JnMmHBm483ppLRAM47nGlDdiraW0IX93EtYYNkiK3g==", + "version": "20.3.29", + "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-20.3.29.tgz", + "integrity": "sha512-R5/vu37FZ1talowvQCHg5oXvRyeIew2pJcso3GMXRtj4RW6/nJPSNFQUGBKrfT6UBJEfkVFX5X+FGkRDHTzoUg==", + "deprecated": "@angular/platform-browser-dynamic is deprecated. Use `@angular/platform-browser` instead.", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -1837,16 +2475,16 @@ "node": "^20.19.0 || ^22.12.0 || >=24.0.0" }, "peerDependencies": { - "@angular/common": "20.3.18", - "@angular/compiler": "20.3.18", - "@angular/core": "20.3.18", - "@angular/platform-browser": "20.3.18" + "@angular/common": "20.3.29", + "@angular/compiler": "20.3.29", + "@angular/core": "20.3.29", + "@angular/platform-browser": "20.3.29" } }, "node_modules/@angular/platform-server": { - "version": "20.3.18", - "resolved": "https://registry.npmjs.org/@angular/platform-server/-/platform-server-20.3.18.tgz", - "integrity": "sha512-iw4QSmEWEKbyMT5u8QdhalNiPqRc7cRuo6lulU75pjXqVLwLb3Gq8it+Vo+LSKY6qI/bMO7olS7iyw09wXJ0OQ==", + "version": "20.3.29", + "resolved": "https://registry.npmjs.org/@angular/platform-server/-/platform-server-20.3.29.tgz", + "integrity": "sha512-+xQKvjB18d5pdkv3P53XpYH6OoplFAuzVstjVnhWe8LWr/9mnuB3G8th2srdYwiuMgADEEACpHfvxLvZJNVOQg==", "license": "MIT", "dependencies": { "tslib": "^2.3.0", @@ -1856,17 +2494,17 @@ "node": "^20.19.0 || ^22.12.0 || >=24.0.0" }, "peerDependencies": { - "@angular/common": "20.3.18", - "@angular/compiler": "20.3.18", - "@angular/core": "20.3.18", - "@angular/platform-browser": "20.3.18", + "@angular/common": "20.3.29", + "@angular/compiler": "20.3.29", + "@angular/core": "20.3.29", + "@angular/platform-browser": "20.3.29", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/router": { - "version": "20.3.18", - "resolved": "https://registry.npmjs.org/@angular/router/-/router-20.3.18.tgz", - "integrity": "sha512-3CWejsEYr+ze+ktvWN/qHdyq5WLrj96QZpGYJyxh1pchIcpMPE9MmLpdjf0CUrWYB7g/85u0Geq/xsz72JrGng==", + "version": "20.3.29", + "resolved": "https://registry.npmjs.org/@angular/router/-/router-20.3.29.tgz", + "integrity": "sha512-42KOJH35PEUYJ31b8xRHEMPiosNO21YzC43cojvzt39lAqEOAtM6aCDPn9QHcvQXj6JrELLvwmfOXD6gNb2u+g==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -1875,16 +2513,16 @@ "node": "^20.19.0 || ^22.12.0 || >=24.0.0" }, "peerDependencies": { - "@angular/common": "20.3.18", - "@angular/core": "20.3.18", - "@angular/platform-browser": "20.3.18", + "@angular/common": "20.3.29", + "@angular/core": "20.3.29", + "@angular/platform-browser": "20.3.29", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/ssr": { - "version": "20.3.22", - "resolved": "https://registry.npmjs.org/@angular/ssr/-/ssr-20.3.22.tgz", - "integrity": "sha512-QwddgNmlFyLTzpAmEgUTzxYg6Q+c6Y2ztyVLpDfp+Xzi/FTmpIe5PXYxcjSRKdhcPwJe/qjYBSxDqq6whJ52GA==", + "version": "20.3.35", + "resolved": "https://registry.npmjs.org/@angular/ssr/-/ssr-20.3.35.tgz", + "integrity": "sha512-eYke+tuHfBRd1N5dmCnwGqDmZXGnE63qat/891DFFoeDYI9uSf3zzMkF5cFusAJnPuny3SMQm0M5XI2OnJo9pw==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -1935,12 +2573,12 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", - "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", + "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.27.1", + "@babel/helper-validator-identifier": "^7.29.7", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" }, @@ -1949,30 +2587,30 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.5.tgz", - "integrity": "sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.7.tgz", + "integrity": "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==", "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.3.tgz", - "integrity": "sha512-yDBHV9kQNcr2/sUr9jghVyz9C3Y5G2zUM2H2lo+9mKv4sFgbA8s8Z9t8D1jiTkGoO/NoIfKMyKWr4s6CN23ZwQ==", - "license": "MIT", - "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.28.3", - "@babel/helper-compilation-targets": "^7.27.2", - "@babel/helper-module-transforms": "^7.28.3", - "@babel/helpers": "^7.28.3", - "@babel/parser": "^7.28.3", - "@babel/template": "^7.27.2", - "@babel/traverse": "^7.28.3", - "@babel/types": "^7.28.2", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz", + "integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.7", + "@babel/helper-compilation-targets": "^7.29.7", + "@babel/helper-module-transforms": "^7.29.7", + "@babel/helpers": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/template": "^7.29.7", + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7", + "@jridgewell/remapping": "^2.3.5", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -1987,6 +2625,22 @@ "url": "https://opencollective.com/babel" } }, + "node_modules/@babel/core/node_modules/@babel/generator": { + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.8.tgz", + "integrity": "sha512-gZbepsdh3WDtgZKWL+vTPh71LSBrm/Y4/QDZBVCcYfmeTEEuoOYwlSy+G1StfJg+/Zy550u/3TATbm7qDbbMtg==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.8", + "@babel/types": "^7.29.8", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/core/node_modules/convert-source-map": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", @@ -2016,16 +2670,6 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/generator/node_modules/@jridgewell/trace-mapping": { - "version": "0.3.31", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", - "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, "node_modules/@babel/helper-annotate-as-pure": { "version": "7.27.3", "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz", @@ -2039,13 +2683,13 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", - "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz", + "integrity": "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==", "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.27.2", - "@babel/helper-validator-option": "^7.27.1", + "@babel/compat-data": "^7.29.7", + "@babel/helper-validator-option": "^7.29.7", "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" @@ -2174,9 +2818,9 @@ "license": "MIT" }, "node_modules/@babel/helper-globals": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", - "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz", + "integrity": "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==", "license": "MIT", "engines": { "node": ">=6.9.0" @@ -2196,27 +2840,27 @@ } }, "node_modules/@babel/helper-module-imports": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", - "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz", + "integrity": "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==", "license": "MIT", "dependencies": { - "@babel/traverse": "^7.27.1", - "@babel/types": "^7.27.1" + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz", - "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz", + "integrity": "sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==", "license": "MIT", "dependencies": { - "@babel/helper-module-imports": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1", - "@babel/traverse": "^7.28.3" + "@babel/helper-module-imports": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7", + "@babel/traverse": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -2238,9 +2882,9 @@ } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", - "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.29.7.tgz", + "integrity": "sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw==", "license": "MIT", "engines": { "node": ">=6.9.0" @@ -2306,27 +2950,27 @@ } }, "node_modules/@babel/helper-string-parser": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", - "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz", + "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==", "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", - "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", + "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", - "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz", + "integrity": "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==", "license": "MIT", "engines": { "node": ">=6.9.0" @@ -2347,25 +2991,25 @@ } }, "node_modules/@babel/helpers": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz", - "integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.7.tgz", + "integrity": "sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==", "license": "MIT", "dependencies": { - "@babel/template": "^7.27.2", - "@babel/types": "^7.28.4" + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/parser": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz", - "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==", + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.8.tgz", + "integrity": "sha512-E8lTAYNB1KW+FH+VGJuZM1ioAx2E6oVlvQFRrf5P8ZZmsiJXYAD9vTFV7yyEURNzgh1dFqMZuO6tUwcARbqFCA==", "license": "MIT", "dependencies": { - "@babel/types": "^7.28.5" + "@babel/types": "^7.29.8" }, "bin": { "parser": "bin/babel-parser.js" @@ -2908,15 +3552,15 @@ } }, "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.28.5.tgz", - "integrity": "sha512-vn5Jma98LCOeBy/KpeQhXcV2WZgaRUtjwQmjoBuLNlOmkg0fB5pdvYVeWRYI69wWKwK2cD1QbMiUQnoujWvrew==", + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.29.8.tgz", + "integrity": "sha512-6iSnEK0zlkLKU4heofK/AdmRD4e2SHVpJMtrwnTCzhnaM98ria4rTrOXBBi45BTTYnJtO8txnPsX4fChYXkmeA==", "license": "MIT", "dependencies": { - "@babel/helper-module-transforms": "^7.28.3", - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-validator-identifier": "^7.28.5", - "@babel/traverse": "^7.28.5" + "@babel/helper-module-transforms": "^7.29.7", + "@babel/helper-plugin-utils": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7", + "@babel/traverse": "^7.29.8" }, "engines": { "node": ">=6.9.0" @@ -3462,31 +4106,31 @@ } }, "node_modules/@babel/template": { - "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", - "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz", + "integrity": "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==", "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/parser": "^7.27.2", - "@babel/types": "^7.27.1" + "@babel/code-frame": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.5.tgz", - "integrity": "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==", + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.8.tgz", + "integrity": "sha512-I5z7H3bf/41ktsNVLtpN0wAa336HkqIHQ5BuPLEhTkt1jVSyZpeNKIzTgEWmlxjdg81R0IgUCcaE+Ok3NvrfZg==", "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.28.5", - "@babel/helper-globals": "^7.28.0", - "@babel/parser": "^7.28.5", - "@babel/template": "^7.27.2", - "@babel/types": "^7.28.5", + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.8", + "@babel/helper-globals": "^7.29.7", + "@babel/parser": "^7.29.8", + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.8", "debug": "^4.3.1" }, "engines": { @@ -3494,13 +4138,13 @@ } }, "node_modules/@babel/traverse/node_modules/@babel/generator": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.5.tgz", - "integrity": "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==", + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.8.tgz", + "integrity": "sha512-gZbepsdh3WDtgZKWL+vTPh71LSBrm/Y4/QDZBVCcYfmeTEEuoOYwlSy+G1StfJg+/Zy550u/3TATbm7qDbbMtg==", "license": "MIT", "dependencies": { - "@babel/parser": "^7.28.5", - "@babel/types": "^7.28.5", + "@babel/parser": "^7.29.8", + "@babel/types": "^7.29.8", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" @@ -3509,24 +4153,14 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/traverse/node_modules/@jridgewell/trace-mapping": { - "version": "0.3.31", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", - "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, "node_modules/@babel/types": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz", - "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==", + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.8.tgz", + "integrity": "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==", "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.28.5" + "@babel/helper-string-parser": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -3550,6 +4184,7 @@ "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "0.3.9" }, @@ -3557,6 +4192,17 @@ "node": ">=12" } }, + "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, "node_modules/@csstools/color-helpers": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-6.1.1.tgz", @@ -3698,9 +4344,9 @@ } }, "node_modules/@cypress/request": { - "version": "3.0.10", - "resolved": "https://registry.npmjs.org/@cypress/request/-/request-3.0.10.tgz", - "integrity": "sha512-hauBrOdvu08vOsagkZ/Aju5XuiZx6ldsLfByg1htFeldhex+PeMrYauANzFsMJeAA0+dyPLbDoX2OYuvVoLDkQ==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@cypress/request/-/request-4.0.1.tgz", + "integrity": "sha512-y20e+e6dFYkOUUJLVUZTsJRuTiXZaUQ32WD+R/ux/HBybbTx4ge7cNINcua0pU8+SNkKuRbOF12mBmzuzM8n5w==", "license": "Apache-2.0", "optional": true, "dependencies": { @@ -3717,14 +4363,13 @@ "json-stringify-safe": "~5.0.1", "mime-types": "~2.1.19", "performance-now": "^2.1.0", - "qs": "~6.14.1", + "qs": "^6.15.2", "safe-buffer": "^5.1.2", "tough-cookie": "^5.0.0", - "tunnel-agent": "^0.6.0", - "uuid": "^8.3.2" + "tunnel-agent": "^0.6.0" }, "engines": { - "node": ">= 6" + "node": ">= 14.17.0" } }, "node_modules/@cypress/schematic": { @@ -3788,9 +4433,9 @@ } }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.9.tgz", - "integrity": "sha512-OaGtL73Jck6pBKjNIe24BnFE6agGl+6KxDtTfHhy1HmhthfKouEcOhqpSL64K4/0WCtbKFLOdzD/44cJ4k9opA==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.2.tgz", + "integrity": "sha512-XExcO+dvLKvVtNTibSTBej1NCAbaGhWn9Ww1ZPx80qsahhPFe/8jgWP0IchNe0F3HwkU7n8ejhH8bjonqht8mQ==", "cpu": [ "ppc64" ], @@ -3804,9 +4449,9 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.9.tgz", - "integrity": "sha512-5WNI1DaMtxQ7t7B6xa572XMXpHAaI/9Hnhk8lcxF4zVN4xstUgTlvuGDorBguKEnZO70qwEcLpfifMLoxiPqHQ==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.2.tgz", + "integrity": "sha512-kXXoiPVVGQcnIYGOeaovwOURpniDBpSq4A03qkQ+BMQqtGG6HYap3xne9C1O1yo4TR3qxlCX5IqqmX6fFo2Lqg==", "cpu": [ "arm" ], @@ -3820,9 +4465,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.9.tgz", - "integrity": "sha512-IDrddSmpSv51ftWslJMvl3Q2ZT98fUSL2/rlUXuVqRXHCs5EUF1/f+jbjF5+NG9UffUDMCiTyh8iec7u8RlTLg==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.2.tgz", + "integrity": "sha512-5YfKeeI8qWfBZIX+u2xZC3Zlb3Os/gLS2sbEKM+I4ZOcsWmHS2WLysCcQZDAFRslDUU5Oiq44gf6PYN1vGwG5A==", "cpu": [ "arm64" ], @@ -3836,9 +4481,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.9.tgz", - "integrity": "sha512-I853iMZ1hWZdNllhVZKm34f4wErd4lMyeV7BLzEExGEIZYsOzqDWDf+y082izYUE8gtJnYHdeDpN/6tUdwvfiw==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.2.tgz", + "integrity": "sha512-O387ite7SzUyCcy3JQX4P4bLtEA7bLLkx+esve5JHnyYfNTxcVpXZo9jhdB0lTKN44gztELTdU7nS8Nr16Fs1Q==", "cpu": [ "x64" ], @@ -3852,9 +4497,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.9.tgz", - "integrity": "sha512-XIpIDMAjOELi/9PB30vEbVMs3GV1v2zkkPnuyRRURbhqjyzIINwj+nbQATh4H9GxUgH1kFsEyQMxwiLFKUS6Rg==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.2.tgz", + "integrity": "sha512-n4KqkOQrraxHJcgjM1RvwbigfQKIKJVpM7xp+KsxiyUSrRdIXnt73VhrPAx0fV44hgfmIVKjxMN9J1t5jySVkw==", "cpu": [ "arm64" ], @@ -3868,9 +4513,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.9.tgz", - "integrity": "sha512-jhHfBzjYTA1IQu8VyrjCX4ApJDnH+ez+IYVEoJHeqJm9VhG9Dh2BYaJritkYK3vMaXrf7Ogr/0MQ8/MeIefsPQ==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.2.tgz", + "integrity": "sha512-uq6suIWYP37qzGddBKPw5QEQPi6HiLGsO7UmkpfyaYNQ3D+rN6w6WfwH+nuqcGXWvawGwxOEroO4YGnFh95azw==", "cpu": [ "x64" ], @@ -3884,9 +4529,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.9.tgz", - "integrity": "sha512-z93DmbnY6fX9+KdD4Ue/H6sYs+bhFQJNCPZsi4XWJoYblUqT06MQUdBCpcSfuiN72AbqeBFu5LVQTjfXDE2A6Q==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.2.tgz", + "integrity": "sha512-n+I0BTSRIoy+d6RPKnEVwql5UwBJolytvY4mAOIEJorKlqgPII8ix6slVVrfZ5Tnj7glIZvloylbB/EJPMWEXw==", "cpu": [ "arm64" ], @@ -3900,9 +4545,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.9.tgz", - "integrity": "sha512-mrKX6H/vOyo5v71YfXWJxLVxgy1kyt1MQaD8wZJgJfG4gq4DpQGpgTB74e5yBeQdyMTbgxp0YtNj7NuHN0PoZg==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.2.tgz", + "integrity": "sha512-78XJTJkvPs0kz2w61301PJjXl4g7q3JqiYMZ/M/yVI73EHBrCRTgkhu9oqG7vPqq+a/yadEW8aD+agKlk5xrmg==", "cpu": [ "x64" ], @@ -3916,9 +4561,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.9.tgz", - "integrity": "sha512-HBU2Xv78SMgaydBmdor38lg8YDnFKSARg1Q6AT0/y2ezUAKiZvc211RDFHlEZRFNRVhcMamiToo7bDx3VEOYQw==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.2.tgz", + "integrity": "sha512-XlDnu2q5yoqems+xay6wSAcg9DDD7K9RLKZEBOMZm3ckNpJBvOX20tSfby8KfrrhINDyv9V2YVZKY/SpoGJI8w==", "cpu": [ "arm" ], @@ -3932,9 +4577,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.9.tgz", - "integrity": "sha512-BlB7bIcLT3G26urh5Dmse7fiLmLXnRlopw4s8DalgZ8ef79Jj4aUcYbk90g8iCa2467HX8SAIidbL7gsqXHdRw==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.2.tgz", + "integrity": "sha512-pW4AC0P3it8c7do9MVM4p51FzHzdM/TZrerurgRcHJ2WTa1VQ1CIq18xncfpBJw4ojkiZZrKW2yIBWBP92j6Ug==", "cpu": [ "arm64" ], @@ -3948,9 +4593,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.9.tgz", - "integrity": "sha512-e7S3MOJPZGp2QW6AK6+Ly81rC7oOSerQ+P8L0ta4FhVi+/j/v2yZzx5CqqDaWjtPFfYz21Vi1S0auHrap3Ma3A==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.2.tgz", + "integrity": "sha512-CYbnj78HsIeA+DhgUKgFCfvNsTHFhMMrinUrMZpDXJXKN8T3XViTZ/+wtHeVxEWY8ewSzTFN+nRmSwO2tZaLUQ==", "cpu": [ "ia32" ], @@ -3964,9 +4609,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.9.tgz", - "integrity": "sha512-Sbe10Bnn0oUAB2AalYztvGcK+o6YFFA/9829PhOCUS9vkJElXGdphz0A3DbMdP8gmKkqPmPcMJmJOrI3VYB1JQ==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.2.tgz", + "integrity": "sha512-buwkd8nsph4R+ajRvw0qM5Hja/TXQow3ptzWO2EbG/cqcIkHloRrdlBtQlshyYGTNFvfkfJ5tpPLVkY4DtsPfQ==", "cpu": [ "loong64" ], @@ -3980,9 +4625,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.9.tgz", - "integrity": "sha512-YcM5br0mVyZw2jcQeLIkhWtKPeVfAerES5PvOzaDxVtIyZ2NUBZKNLjC5z3/fUlDgT6w89VsxP2qzNipOaaDyA==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.2.tgz", + "integrity": "sha512-ZVykbDyk7519VwiNb9Lcj9m8XM6v5V9uKPvrEMkkEedVewf+0itkhahp4HDpgERXhwLRpWFypsGbG/J8s0QjJA==", "cpu": [ "mips64el" ], @@ -3996,9 +4641,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.9.tgz", - "integrity": "sha512-++0HQvasdo20JytyDpFvQtNrEsAgNG2CY1CLMwGXfFTKGBGQT3bOeLSYE2l1fYdvML5KUuwn9Z8L1EWe2tzs1w==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.2.tgz", + "integrity": "sha512-CAXl+Dtd9UUuJd8pKKdwh6MLm3MUMiqMPmhZ3tTSXPqfyQ3vDl6R5hZdZ/kYojK4ofXtdfSv1tFq8XzWx3heNQ==", "cpu": [ "ppc64" ], @@ -4012,9 +4657,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.9.tgz", - "integrity": "sha512-uNIBa279Y3fkjV+2cUjx36xkx7eSjb8IvnL01eXUKXez/CBHNRw5ekCGMPM0BcmqBxBcdgUWuUXmVWwm4CH9kg==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.2.tgz", + "integrity": "sha512-GeXCej4IQtU1B+QlDV8W/RRvbzI3O/Stss+/bCXv4lZls5WGRtu2a+3JkA3i4qIUlMXpcHebWpF8AkJhATowuA==", "cpu": [ "riscv64" ], @@ -4028,9 +4673,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.9.tgz", - "integrity": "sha512-Mfiphvp3MjC/lctb+7D287Xw1DGzqJPb/J2aHHcHxflUo+8tmN/6d4k6I2yFR7BVo5/g7x2Monq4+Yew0EHRIA==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.2.tgz", + "integrity": "sha512-3H1weTYZPxt/WOhByszQZybS9w5lKzUn1FDMsgEChbHWQwHYQQRfBxgCcZvPhjHfKyJjIievvMmEUawJrdY9Dg==", "cpu": [ "s390x" ], @@ -4044,9 +4689,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.9.tgz", - "integrity": "sha512-iSwByxzRe48YVkmpbgoxVzn76BXjlYFXC7NvLYq+b+kDjyyk30J0JY47DIn8z1MO3K0oSl9fZoRmZPQI4Hklzg==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.2.tgz", + "integrity": "sha512-4xTZr1FUmSoQW4XIWmit3tzQrUTZM+N3P0XV8xROKYF50XfI7xeO90+1bZvNwxIufQ9hDQVRJH5YhgPVF8A/HQ==", "cpu": [ "x64" ], @@ -4060,9 +4705,9 @@ } }, "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.9.tgz", - "integrity": "sha512-9jNJl6FqaUG+COdQMjSCGW4QiMHH88xWbvZ+kRVblZsWrkXlABuGdFJ1E9L7HK+T0Yqd4akKNa/lO0+jDxQD4Q==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.2.tgz", + "integrity": "sha512-sSATRjPeDBg3pdgHoQfoYBob11Kk1FGa9lui5RIHZCoCkJa9QKlvl3/vKz2usCmYYjs7ymJR/2Nnsqe+Hjt5nw==", "cpu": [ "arm64" ], @@ -4076,9 +4721,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.9.tgz", - "integrity": "sha512-RLLdkflmqRG8KanPGOU7Rpg829ZHu8nFy5Pqdi9U01VYtG9Y0zOG6Vr2z4/S+/3zIyOxiK6cCeYNWOFR9QP87g==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.2.tgz", + "integrity": "sha512-lqnzCV+mM0gIADaKihiCg6ifgfU2L3h5E33rNQBN1Y4MaVGnzryzmvvf7UHxprpQdE8hpqLolJ9Rl+SkIRDpyw==", "cpu": [ "x64" ], @@ -4092,9 +4737,9 @@ } }, "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.9.tgz", - "integrity": "sha512-YaFBlPGeDasft5IIM+CQAhJAqS3St3nJzDEgsgFixcfZeyGPCd6eJBWzke5piZuZ7CtL656eOSYKk4Ls2C0FRQ==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.2.tgz", + "integrity": "sha512-AL2qJILH7lNjrDmCQDvdxMfAUIv8KMNZOvrwAQ8i8//ntL9FflhOyMJ8OZSMBb8/AWXe3/5v5S20y3zCoZWKoQ==", "cpu": [ "arm64" ], @@ -4108,9 +4753,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.9.tgz", - "integrity": "sha512-1MkgTCuvMGWuqVtAvkpkXFmtL8XhWy+j4jaSO2wxfJtilVCi0ZE37b8uOdMItIHz4I6z1bWWtEX4CJwcKYLcuA==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.2.tgz", + "integrity": "sha512-QtiuPytchRyC4rwUKhexJdQKvDuZ6hWloi3igqPQNUJCS1/v9EiO3UTOXR6A3FoMo4fnAKbWJdqaIwhOzh8qEw==", "cpu": [ "x64" ], @@ -4124,9 +4769,9 @@ } }, "node_modules/@esbuild/openharmony-arm64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.9.tgz", - "integrity": "sha512-4Xd0xNiMVXKh6Fa7HEJQbrpP3m3DDn43jKxMjxLLRjWnRsfxjORYJlXPO4JNcXtOyfajXorRKY9NkOpTHptErg==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.2.tgz", + "integrity": "sha512-WkhYDmpTjLvGlScA1rwjRUmhl4k8oXR3cIbtqWmELgU/dFeHHlEllxDvdWcNJV9rbzCexB5vz8gtNewWLgCT7Q==", "cpu": [ "arm64" ], @@ -4140,9 +4785,9 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.9.tgz", - "integrity": "sha512-WjH4s6hzo00nNezhp3wFIAfmGZ8U7KtrJNlFMRKxiI9mxEK1scOMAaa9i4crUtu+tBr+0IN6JCuAcSBJZfnphw==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.2.tgz", + "integrity": "sha512-GPMSkTOtMnv2U2F8gxe4Io6qmVs+YKyp832Etqqxr0hFngmXQ3rzwytelm3GIn7T4VviRUlf3sOgBOiTdvaf7g==", "cpu": [ "x64" ], @@ -4156,9 +4801,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.9.tgz", - "integrity": "sha512-mGFrVJHmZiRqmP8xFOc6b84/7xa5y5YvR1x8djzXpJBSv/UsNK6aqec+6JDjConTgvvQefdGhFDAs2DLAds6gQ==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.2.tgz", + "integrity": "sha512-PIhhEkE9uPBleRBrQEJpUn7MBnibZzbGzYWPmY3x+YoVg/95zbjB4CxPPOQ8l5tYYM4mMaCthF8/1DIfBQQyWQ==", "cpu": [ "arm64" ], @@ -4172,9 +4817,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.9.tgz", - "integrity": "sha512-b33gLVU2k11nVx1OhX3C8QQP6UHQK4ZtN56oFWvVXvz2VkDoe6fbG8TOgHFxEvqeqohmRnIHe5A1+HADk4OQww==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.2.tgz", + "integrity": "sha512-YmJbfTlvU7Sdn9BB+4PRES4oB6pxgS37MAONj+hBr/cpXS1aBPKXxNnDbu+QCWPj0o9dgyxeq79g6c5P8KeuYA==", "cpu": [ "ia32" ], @@ -4188,9 +4833,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.9.tgz", - "integrity": "sha512-PPOl1mi6lpLNQxnGoyAfschAodRFYXJ+9fs6WHXz7CSWKbOqiMZsubC+BQsVKuul+3vKLuwTHsS2c2y9EoKwxQ==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.2.tgz", + "integrity": "sha512-5ebpxr3nWMzrL/rnUI755Jkuee0bHL/Gq0WTF9lvcpv73wAp5eu8MfBUgWK9bhWvZjj7yX8etf/8tI8Ney695g==", "cpu": [ "x64" ], @@ -4204,9 +4849,9 @@ } }, "node_modules/@eslint-community/eslint-utils": { - "version": "4.9.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz", - "integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==", + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.10.1.tgz", + "integrity": "sha512-cuadcxVFE8sDK6iWJbs8Sn0av2Nrh2QSGQhVlBW9AaAHqHwjWsZHT8LJ4hFGPh7ASBV2deFdM7H/DPjulmh8rg==", "dev": true, "license": "MIT", "dependencies": { @@ -4233,15 +4878,15 @@ } }, "node_modules/@eslint/config-array": { - "version": "0.21.1", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz", - "integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==", + "version": "0.21.2", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.2.tgz", + "integrity": "sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw==", "dev": true, "license": "Apache-2.0", "dependencies": { "@eslint/object-schema": "^2.1.7", "debug": "^4.3.1", - "minimatch": "^3.1.2" + "minimatch": "^3.1.5" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -4274,20 +4919,20 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", - "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.6.tgz", + "integrity": "sha512-l2Ul9PrHsPCKcEY/ac7VgFj9D80C7S68sOKc618SyHDPK36s1XcFebXY0iTzUVn4Yq+YbwvSnDmCz9yxjX+QrA==", "dev": true, "license": "MIT", "dependencies": { - "ajv": "^6.12.4", + "ajv": "^6.14.0", "debug": "^4.3.2", "espree": "^10.0.1", "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", + "js-yaml": "^4.3.0", + "minimatch": "^3.1.5", "strip-json-comments": "^3.1.1" }, "engines": { @@ -4297,6 +4942,23 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/@eslint/eslintrc/node_modules/ajv": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, "node_modules/@eslint/eslintrc/node_modules/ignore": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", @@ -4307,10 +4969,17 @@ "node": ">= 4" } }, + "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, "node_modules/@eslint/js": { - "version": "9.39.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.0.tgz", - "integrity": "sha512-BIhe0sW91JGPiaF1mOuPy5v8NflqfjIcDNpC+LbW9f609WVRX1rArrhi6Z2ymvrAry9jw+5POTj4t2t62o8Bmw==", + "version": "9.39.5", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.5.tgz", + "integrity": "sha512-QywQuszQh77pIXCsq998c8hbhSTI/azTty1Z6N53dmAudKHhy573j3yvRLsX2BSp8YpLtoCEG8E9DJe+8zUh4A==", "dev": true, "license": "MIT", "engines": { @@ -4429,6 +5098,15 @@ "node": ">=6" } }, + "node_modules/@gar/promise-retry": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@gar/promise-retry/-/promise-retry-1.0.3.tgz", + "integrity": "sha512-GmzA9ckNokPypTg10pgpeHNQe7ph+iIKKmhKu3Ob9ANkswreCx7R3cKmY781K8QK3AqVL3xVh9A42JvIAbkkSA==", + "license": "MIT", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, "node_modules/@hapi/address": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/@hapi/address/-/address-5.1.1.tgz", @@ -4484,41 +5162,55 @@ } }, "node_modules/@hono/node-server": { - "version": "1.19.11", - "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.11.tgz", - "integrity": "sha512-dr8/3zEaB+p0D2n/IUrlPF1HZm586qgJNXK1a9fhg/PzdtkK7Ksd5l312tJX2yBuALqDYBlG20QEbayqPyxn+g==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-2.1.1.tgz", + "integrity": "sha512-ELuehkj5VCBdgEw9zs+ivkKwyzzUCSQuE96YmiPvn1ECBoZCczbFXJLeEGMTYjphP6gydh4pHMqEYPVMYUVgQg==", "license": "MIT", "engines": { - "node": ">=18.14.1" + "node": ">=20" }, "peerDependencies": { "hono": "^4" } }, "node_modules/@humanfs/core": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", - "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.2.tgz", + "integrity": "sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==", "dev": true, "license": "Apache-2.0", + "dependencies": { + "@humanfs/types": "^0.15.0" + }, "engines": { "node": ">=18.18.0" } }, "node_modules/@humanfs/node": { - "version": "0.16.7", - "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", - "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", + "version": "0.16.8", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.8.tgz", + "integrity": "sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@humanfs/core": "^0.19.1", + "@humanfs/core": "^0.19.2", + "@humanfs/types": "^0.15.0", "@humanwhocodes/retry": "^0.4.0" }, "engines": { "node": ">=18.18.0" } }, + "node_modules/@humanfs/types": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/@humanfs/types/-/types-0.15.0.tgz", + "integrity": "sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", @@ -4913,6 +5605,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", + "license": "ISC", "dependencies": { "minipass": "^7.0.4" }, @@ -4921,9 +5614,9 @@ } }, "node_modules/@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.6.tgz", + "integrity": "sha512-+Sg6GCR/wy1oSmQDFq4LQDAhm3ETKnorxN+y5nbLULOR3P0c14f2Wurzj3/xqPXtasLFfHd5iRFQ7AJt4KH2cw==", "license": "MIT", "engines": { "node": ">=8" @@ -4939,13 +5632,14 @@ "@jridgewell/trace-mapping": "^0.3.24" } }, - "node_modules/@jridgewell/gen-mapping/node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "license": "MIT", "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" } }, "node_modules/@jridgewell/resolve-uri": { @@ -4972,12 +5666,13 @@ "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "license": "MIT", "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, "node_modules/@jsonjoy.com/base64": { @@ -5029,13 +5724,13 @@ } }, "node_modules/@jsonjoy.com/fs-core": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-core/-/fs-core-4.57.1.tgz", - "integrity": "sha512-YrEi/ZPmgc+GfdO0esBF04qv8boK9Dg9WpRQw/+vM8Qt3nnVIJWIa8HwZ/LXVZ0DB11XUROM8El/7yYTJX+WtA==", + "version": "4.68.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-core/-/fs-core-4.68.1.tgz", + "integrity": "sha512-V5oZ4Gt9WJKyQef0n9cAd0N9qjSkIBm3E4MYsgNIWBk5aINCDPKxMPo1i29rBxqiT4Ixf1epklqV9VJMKIxwlw==", "license": "Apache-2.0", "dependencies": { - "@jsonjoy.com/fs-node-builtins": "4.57.1", - "@jsonjoy.com/fs-node-utils": "4.57.1", + "@jsonjoy.com/fs-node-builtins": "4.68.1", + "@jsonjoy.com/fs-node-utils": "4.68.1", "thingies": "^2.5.0" }, "engines": { @@ -5050,14 +5745,14 @@ } }, "node_modules/@jsonjoy.com/fs-fsa": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-fsa/-/fs-fsa-4.57.1.tgz", - "integrity": "sha512-ooEPvSW/HQDivPDPZMibHGKZf/QS4WRir1czGZmXmp3MsQqLECZEpN0JobrD8iV9BzsuwdIv+PxtWX9WpPLsIA==", + "version": "4.68.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-fsa/-/fs-fsa-4.68.1.tgz", + "integrity": "sha512-HCG72UioncuO7Gw09XNVG+S85e3cq2hrUC/mexBrsWsa3mI7eePkkqWie3uVYbtsb64OR9YGQs5SqaufDRYBcg==", "license": "Apache-2.0", "dependencies": { - "@jsonjoy.com/fs-core": "4.57.1", - "@jsonjoy.com/fs-node-builtins": "4.57.1", - "@jsonjoy.com/fs-node-utils": "4.57.1", + "@jsonjoy.com/fs-core": "4.68.1", + "@jsonjoy.com/fs-node-builtins": "4.68.1", + "@jsonjoy.com/fs-node-utils": "4.68.1", "thingies": "^2.5.0" }, "engines": { @@ -5072,16 +5767,16 @@ } }, "node_modules/@jsonjoy.com/fs-node": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node/-/fs-node-4.57.1.tgz", - "integrity": "sha512-3YaKhP8gXEKN+2O49GLNfNb5l2gbnCFHyAaybbA2JkkbQP3dpdef7WcUaHAulg/c5Dg4VncHsA3NWAUSZMR5KQ==", + "version": "4.68.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node/-/fs-node-4.68.1.tgz", + "integrity": "sha512-R5D9mWtqdURzcOWj1vdXr3APCwX0xchtFT+kmW7fXLNDifWdDrnh26jSID8pdnUfFBxTyfHtFtTL/NWKzIH7kQ==", "license": "Apache-2.0", "dependencies": { - "@jsonjoy.com/fs-core": "4.57.1", - "@jsonjoy.com/fs-node-builtins": "4.57.1", - "@jsonjoy.com/fs-node-utils": "4.57.1", - "@jsonjoy.com/fs-print": "4.57.1", - "@jsonjoy.com/fs-snapshot": "4.57.1", + "@jsonjoy.com/fs-core": "4.68.1", + "@jsonjoy.com/fs-node-builtins": "4.68.1", + "@jsonjoy.com/fs-node-utils": "4.68.1", + "@jsonjoy.com/fs-print": "4.68.1", + "@jsonjoy.com/fs-snapshot": "4.68.1", "glob-to-regex.js": "^1.0.0", "thingies": "^2.5.0" }, @@ -5097,9 +5792,9 @@ } }, "node_modules/@jsonjoy.com/fs-node-builtins": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node-builtins/-/fs-node-builtins-4.57.1.tgz", - "integrity": "sha512-XHkFKQ5GSH3uxm8c3ZYXVrexGdscpWKIcMWKFQpMpMJc8gA3AwOMBJXJlgpdJqmrhPyQXxaY9nbkNeYpacC0Og==", + "version": "4.68.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node-builtins/-/fs-node-builtins-4.68.1.tgz", + "integrity": "sha512-HK1BTksysokNZxNspqDH0yPaqN9YgR/AYIlYiIaU2Ys4BOk5CdybI7r6BgiZuiiPiV8n4sK/kZdice7Znpy2Kw==", "license": "Apache-2.0", "engines": { "node": ">=10.0" @@ -5113,14 +5808,14 @@ } }, "node_modules/@jsonjoy.com/fs-node-to-fsa": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node-to-fsa/-/fs-node-to-fsa-4.57.1.tgz", - "integrity": "sha512-pqGHyWWzNck4jRfaGV39hkqpY5QjRUQ/nRbNT7FYbBa0xf4bDG+TE1Gt2KWZrSkrkZZDE3qZUjYMbjwSliX6pg==", + "version": "4.68.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node-to-fsa/-/fs-node-to-fsa-4.68.1.tgz", + "integrity": "sha512-lpKmU4X9e/oh8GIuAI7EXaS5QiLNM3KD15CkdhfS6PYmrGvoJqKQcyEfnLgnnaGslh/PFUMYSIZBCf2ejJGw8g==", "license": "Apache-2.0", "dependencies": { - "@jsonjoy.com/fs-fsa": "4.57.1", - "@jsonjoy.com/fs-node-builtins": "4.57.1", - "@jsonjoy.com/fs-node-utils": "4.57.1" + "@jsonjoy.com/fs-fsa": "4.68.1", + "@jsonjoy.com/fs-node-builtins": "4.68.1", + "@jsonjoy.com/fs-node-utils": "4.68.1" }, "engines": { "node": ">=10.0" @@ -5134,12 +5829,13 @@ } }, "node_modules/@jsonjoy.com/fs-node-utils": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node-utils/-/fs-node-utils-4.57.1.tgz", - "integrity": "sha512-vp+7ZzIB8v43G+GLXTS4oDUSQmhAsRz532QmmWBbdYA20s465JvwhkSFvX9cVTqRRAQg+vZ7zWDaIEh0lFe2gw==", + "version": "4.68.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node-utils/-/fs-node-utils-4.68.1.tgz", + "integrity": "sha512-/GxfW1DWm9SCdkfbvqevLO/P5duobQfmKkHXxdMIDbcZMQeAgooAstIfZhkXpATzq9QbCQsnoWFM/dGHdZfndw==", "license": "Apache-2.0", "dependencies": { - "@jsonjoy.com/fs-node-builtins": "4.57.1" + "@jsonjoy.com/fs-node-builtins": "4.68.1", + "glob-to-regex.js": "^1.0.1" }, "engines": { "node": ">=10.0" @@ -5153,12 +5849,12 @@ } }, "node_modules/@jsonjoy.com/fs-print": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-print/-/fs-print-4.57.1.tgz", - "integrity": "sha512-Ynct7ZJmfk6qoXDOKfpovNA36ITUx8rChLmRQtW08J73VOiuNsU8PB6d/Xs7fxJC2ohWR3a5AqyjmLojfrw5yw==", + "version": "4.68.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-print/-/fs-print-4.68.1.tgz", + "integrity": "sha512-oGeZOGPYKK9v1CgeVeEDsLomH1lCnslSpqUN5GmPzrmAVGQlsmsdcXNA2O4lV8Y4xkuSuynx2ITBkUHJVaTbow==", "license": "Apache-2.0", "dependencies": { - "@jsonjoy.com/fs-node-utils": "4.57.1", + "@jsonjoy.com/fs-node-utils": "4.68.1", "tree-dump": "^1.1.0" }, "engines": { @@ -5173,13 +5869,13 @@ } }, "node_modules/@jsonjoy.com/fs-snapshot": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-snapshot/-/fs-snapshot-4.57.1.tgz", - "integrity": "sha512-/oG8xBNFMbDXTq9J7vepSA1kerS5vpgd3p5QZSPd+nX59uwodGJftI51gDYyHRpP57P3WCQf7LHtBYPqwUg2Bg==", + "version": "4.68.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-snapshot/-/fs-snapshot-4.68.1.tgz", + "integrity": "sha512-XZfP0FDZN32bbc4t2bZN2qRrYHg5AktJnzk22HRoKGK4BprrbNRH2k5ceSNS/kupKYcofCs+O841+xaAbjnxwQ==", "license": "Apache-2.0", "dependencies": { "@jsonjoy.com/buffers": "^17.65.0", - "@jsonjoy.com/fs-node-utils": "4.57.1", + "@jsonjoy.com/fs-node-utils": "4.68.1", "@jsonjoy.com/json-pack": "^17.65.0", "@jsonjoy.com/util": "^17.65.0" }, @@ -5487,12 +6183,12 @@ ] }, "node_modules/@modelcontextprotocol/sdk": { - "version": "1.26.0", - "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.26.0.tgz", - "integrity": "sha512-Y5RmPncpiDtTXDbLKswIJzTqu2hyBKxTNsgKqKclDbhIgg1wgtf1fRuvxgTnRfcnxtvvgbIEcqUOzZrJ6iSReg==", + "version": "1.30.0", + "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.30.0.tgz", + "integrity": "sha512-xKd8OIzlqNzcqcNumGAa6g+PW2kjD5vrpcKOnfldAUPP3j7lnqMPwlTXQm8gF+UwH72z0lqaRbjr9hqGz0eITA==", "license": "MIT", "dependencies": { - "@hono/node-server": "^1.19.9", + "@hono/node-server": "^1.19.9 || ^2.0.5", "ajv": "^8.17.1", "ajv-formats": "^3.0.1", "content-type": "^1.0.5", @@ -5526,22 +6222,6 @@ } } }, - "node_modules/@modelcontextprotocol/sdk/node_modules/ajv": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", - "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, "node_modules/@modelcontextprotocol/sdk/node_modules/ajv-formats": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", @@ -5580,9 +6260,9 @@ } }, "node_modules/@modelcontextprotocol/sdk/node_modules/iconv-lite": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz", - "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==", + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.3.tgz", + "integrity": "sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==", "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" @@ -5595,12 +6275,6 @@ "url": "https://opencollective.com/express" } }, - "node_modules/@modelcontextprotocol/sdk/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "license": "MIT" - }, "node_modules/@modelcontextprotocol/sdk/node_modules/raw-body": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz", @@ -5626,9 +6300,9 @@ } }, "node_modules/@msgpackr-extract/msgpackr-extract-darwin-arm64": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-3.0.3.tgz", - "integrity": "sha512-QZHtlVgbAdy2zAqNA9Gu1UpIuI8Xvsd1v8ic6B2pZmeFnFcMWiPLfWXh7TVw4eGEZ/C9TH281KwhVoeQUKbyjw==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-3.0.4.tgz", + "integrity": "sha512-LCkGo6JDfaBhgST7UpPWgNgLINpcpabaHfyz5OBx75nUYxBsaEPxjnyNjWpeb/xBup/682QnBfRBy2/LvPutZQ==", "cpu": [ "arm64" ], @@ -5639,9 +6313,9 @@ ] }, "node_modules/@msgpackr-extract/msgpackr-extract-darwin-x64": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-x64/-/msgpackr-extract-darwin-x64-3.0.3.tgz", - "integrity": "sha512-mdzd3AVzYKuUmiWOQ8GNhl64/IoFGol569zNRdkLReh6LRLHOXxU4U8eq0JwaD8iFHdVGqSy4IjFL4reoWCDFw==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-x64/-/msgpackr-extract-darwin-x64-3.0.4.tgz", + "integrity": "sha512-zExlW9zUJKZH/tOtVMttwjKa4Xm/3KcNjnE3dPN92uCktwavMxpgCA3MoJK/DOnTWsQgo224OaST27/mPNAf+w==", "cpu": [ "x64" ], @@ -5652,9 +6326,9 @@ ] }, "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm/-/msgpackr-extract-linux-arm-3.0.3.tgz", - "integrity": "sha512-fg0uy/dG/nZEXfYilKoRe7yALaNmHoYeIoJuJ7KJ+YyU2bvY8vPv27f7UKhGRpY6euFYqEVhxCFZgAUNQBM3nw==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm/-/msgpackr-extract-linux-arm-3.0.4.tgz", + "integrity": "sha512-Tg3yX65f5GbtXLkrYEHE5oibZG9epyYWas7FogTTEJeDEF9JlXJzKgXaNhT3UXlTOeA+AfZpYZYZ0uPj7Cfquw==", "cpu": [ "arm" ], @@ -5665,9 +6339,9 @@ ] }, "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm64": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm64/-/msgpackr-extract-linux-arm64-3.0.3.tgz", - "integrity": "sha512-YxQL+ax0XqBJDZiKimS2XQaf+2wDGVa1enVRGzEvLLVFeqa5kx2bWbtcSXgsxjQB7nRqqIGFIcLteF/sHeVtQg==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm64/-/msgpackr-extract-linux-arm64-3.0.4.tgz", + "integrity": "sha512-dgX0P/9wGPJeHFBG+ZmhgE6bmtMt7NP5CRBGyyktpopdk/mW4POnrpQsSLtKI1dwpc+pPLuXHDh6vvskyQE/sw==", "cpu": [ "arm64" ], @@ -5678,9 +6352,9 @@ ] }, "node_modules/@msgpackr-extract/msgpackr-extract-linux-x64": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-x64/-/msgpackr-extract-linux-x64-3.0.3.tgz", - "integrity": "sha512-cvwNfbP07pKUfq1uH+S6KJ7dT9K8WOE4ZiAcsrSes+UY55E/0jLYc+vq+DO7jlmqRb5zAggExKm0H7O/CBaesg==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-x64/-/msgpackr-extract-linux-x64-3.0.4.tgz", + "integrity": "sha512-8TNXMEjJc3QEy7R/x1INhgiU+XakDAFUzBhaz7+Rbrs8NH5UQeHQxxmzsSBJGyV6I1jW79undiQm8tOI+D+8FQ==", "cpu": [ "x64" ], @@ -5691,9 +6365,9 @@ ] }, "node_modules/@msgpackr-extract/msgpackr-extract-win32-x64": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-3.0.3.tgz", - "integrity": "sha512-x0fWaQtYp4E6sktbsdAqnehxDgEc/VwM7uLsRCYWaiGu0ykYdZPiS8zCWdnjHwyiumousxfBm4SO31eXqwEZhQ==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-3.0.4.tgz", + "integrity": "sha512-CmCXPQrkbwExx3j946/PtHWHbYJiCRBRDl4BlkRQcJB/YOwQxJRTpoo7aTsortjgoJ1x7opzTSxn7C+ASSLVjQ==", "cpu": [ "x64" ], @@ -5839,6 +6513,9 @@ "cpu": [ "arm64" ], + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -5855,6 +6532,9 @@ "cpu": [ "arm64" ], + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -5871,6 +6551,9 @@ "cpu": [ "ppc64" ], + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -5887,6 +6570,9 @@ "cpu": [ "riscv64" ], + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -5903,6 +6589,9 @@ "cpu": [ "s390x" ], + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -5919,6 +6608,9 @@ "cpu": [ "x64" ], + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -5935,6 +6627,9 @@ "cpu": [ "x64" ], + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -6026,9 +6721,9 @@ } }, "node_modules/@ngtools/webpack": { - "version": "20.3.22", - "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-20.3.22.tgz", - "integrity": "sha512-EgOiRjYpNG5Mu/WAhMwQrAB1BBwWrApbYm2hTU9KjaxOZvtWHjeFfsiULgd1T76GpiF4t3Iw1GtNljzgD6fT/A==", + "version": "20.3.35", + "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-20.3.35.tgz", + "integrity": "sha512-W+PN63N1XZMP1zcm3nc36hxirKVmc9VPxaCLG2yCZlP6rHT8/eWUkKI/hufePzEIqW2mVa/ZyAvxr1kh2g4ndA==", "license": "MIT", "engines": { "node": "^20.19.0 || ^22.12.0 || >=24.0.0", @@ -6083,9 +6778,10 @@ } }, "node_modules/@npmcli/agent": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@npmcli/agent/-/agent-4.0.0.tgz", - "integrity": "sha512-kAQTcEN9E8ERLVg5AsGwLNoFb+oEG6engbqAU2P43gD4JEIkNGMHdVQ096FsOAAYpZPB0RSt0zgInKIAS1l5QA==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@npmcli/agent/-/agent-4.0.2.tgz", + "integrity": "sha512-EUEuWAxnL07Sp5/iC/1X6Xj+XThUvnbei9zfRWZdEXa7lss9RTHMhAHBeg+MZ5To9s/gGaSI+UwZTPdYMvKSeg==", + "license": "ISC", "dependencies": { "agent-base": "^7.1.0", "http-proxy-agent": "^7.0.0", @@ -6101,6 +6797,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-5.0.0.tgz", "integrity": "sha512-7OsC1gNORBEawOa5+j2pXN9vsicaIOH5cPXxoR6fJOmH6/EXpJB2CajXOu1fPRFun2m1lktEFX11+P89hqO/og==", + "license": "ISC", "dependencies": { "semver": "^7.3.5" }, @@ -6109,16 +6806,17 @@ } }, "node_modules/@npmcli/git": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-7.0.1.tgz", - "integrity": "sha512-+XTFxK2jJF/EJJ5SoAzXk3qwIDfvFc5/g+bD274LZ7uY7LE8sTfG6Z8rOanPl2ZEvZWqNvmEdtXC25cE54VcoA==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-7.0.2.tgz", + "integrity": "sha512-oeolHDjExNAJAnlYP2qzNjMX/Xi9bmu78C9dIGr4xjobrSKbuMYCph8lTzn4vnW3NjIqVmw/f8BCfouqyJXlRg==", + "license": "ISC", "dependencies": { + "@gar/promise-retry": "^1.0.0", "@npmcli/promise-spawn": "^9.0.0", "ini": "^6.0.0", "lru-cache": "^11.2.1", "npm-pick-manifest": "^11.0.1", "proc-log": "^6.0.0", - "promise-retry": "^2.0.1", "semver": "^7.3.5", "which": "^6.0.0" }, @@ -6130,32 +6828,36 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/ini/-/ini-6.0.0.tgz", "integrity": "sha512-IBTdIkzZNOpqm7q3dRqJvMaldXjDHWkEDfrwGEQTs5eaQMWV+djAhR+wahyNNMAa+qpbDUhBMVt4ZKNwpPm7xQ==", + "license": "ISC", "engines": { "node": "^20.17.0 || >=22.9.0" } }, "node_modules/@npmcli/git/node_modules/isexe": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", - "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-4.0.0.tgz", + "integrity": "sha512-FFUtZMpoZ8RqHS3XeXEmHWLA4thH+ZxCv2lOiPIn1Xc7CxrqhWzNSDzD+/chS/zbYezmiwWLdQC09JdQKmthOw==", + "license": "BlueOak-1.0.0", "engines": { - "node": ">=16" + "node": ">=20" } }, "node_modules/@npmcli/git/node_modules/proc-log": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-6.1.0.tgz", "integrity": "sha512-iG+GYldRf2BQ0UDUAd6JQ/RwzaQy6mXmsk/IzlYyal4A4SNFw54MeH4/tLkF4I5WoWG9SQwuqWzS99jaFQHBuQ==", + "license": "ISC", "engines": { "node": "^20.17.0 || >=22.9.0" } }, "node_modules/@npmcli/git/node_modules/which": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/which/-/which-6.0.0.tgz", - "integrity": "sha512-f+gEpIKMR9faW/JgAgPK1D7mekkFoqbmiwvNzuhsHetni20QSgzg9Vhn0g2JSJkkfehQnqdUAx7/e15qS1lPxg==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/which/-/which-6.0.1.tgz", + "integrity": "sha512-oGLe46MIrCRqX7ytPUf66EAYvdeMIZYn3WaocqqKZAxrBpkqHfL/qvTyJ/bTk5+AqHCjXmrv3CEWgy368zhRUg==", + "license": "ISC", "dependencies": { - "isexe": "^3.1.1" + "isexe": "^4.0.0" }, "bin": { "node-which": "bin/which.js" @@ -6168,6 +6870,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/@npmcli/installed-package-contents/-/installed-package-contents-4.0.0.tgz", "integrity": "sha512-yNyAdkBxB72gtZ4GrwXCM0ZUedo9nIbOMKfGjt6Cu6DXf0p8y1PViZAKDC8q8kv/fufx0WTjRBdSlyrvnP7hmA==", + "license": "ISC", "dependencies": { "npm-bundled": "^5.0.0", "npm-normalize-package-bin": "^5.0.0" @@ -6183,14 +6886,16 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/@npmcli/node-gyp/-/node-gyp-5.0.0.tgz", "integrity": "sha512-uuG5HZFXLfyFKqg8QypsmgLQW7smiRjVc45bqD/ofZZcR/uxEjgQU8qDPv0s9TEeMUiAAU/GC5bR6++UdTirIQ==", + "license": "ISC", "engines": { "node": "^20.17.0 || >=22.9.0" } }, "node_modules/@npmcli/package-json": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/@npmcli/package-json/-/package-json-7.0.4.tgz", - "integrity": "sha512-0wInJG3j/K40OJt/33ax47WfWMzZTm6OQxB9cDhTt5huCP2a9g2GnlsxmfN+PulItNPIpPrZ+kfwwUil7eHcZQ==", + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/@npmcli/package-json/-/package-json-7.0.5.tgz", + "integrity": "sha512-iVuTlG3ORq2iaVa1IWUxAO/jIp77tUKBhoMjuzYW2kL4MLN1bi/ofqkZ7D7OOwh8coAx1/S2ge0rMdGv8sLSOQ==", + "license": "ISC", "dependencies": { "@npmcli/git": "^7.0.0", "glob": "^13.0.0", @@ -6198,7 +6903,7 @@ "json-parse-even-better-errors": "^5.0.0", "proc-log": "^6.0.0", "semver": "^7.5.3", - "validate-npm-package-license": "^3.0.4" + "spdx-expression-parse": "^4.0.0" }, "engines": { "node": "^20.17.0 || >=22.9.0" @@ -6208,6 +6913,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-5.0.0.tgz", "integrity": "sha512-ZF1nxZ28VhQouRWhUcVlUIN3qwSgPuswK05s/HIaoetAoE/9tngVmCHjSxmSQPav1nd+lPtTL0YZ/2AFdR/iYQ==", + "license": "MIT", "engines": { "node": "^20.17.0 || >=22.9.0" } @@ -6216,6 +6922,7 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-6.1.0.tgz", "integrity": "sha512-iG+GYldRf2BQ0UDUAd6JQ/RwzaQy6mXmsk/IzlYyal4A4SNFw54MeH4/tLkF4I5WoWG9SQwuqWzS99jaFQHBuQ==", + "license": "ISC", "engines": { "node": "^20.17.0 || >=22.9.0" } @@ -6224,6 +6931,7 @@ "version": "9.0.1", "resolved": "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-9.0.1.tgz", "integrity": "sha512-OLUaoqBuyxeTqUvjA3FZFiXUfYC1alp3Sa99gW3EUDz3tZ3CbXDdcZ7qWKBzicrJleIgucoWamWH1saAmH/l2Q==", + "license": "ISC", "dependencies": { "which": "^6.0.0" }, @@ -6232,19 +6940,21 @@ } }, "node_modules/@npmcli/promise-spawn/node_modules/isexe": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", - "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-4.0.0.tgz", + "integrity": "sha512-FFUtZMpoZ8RqHS3XeXEmHWLA4thH+ZxCv2lOiPIn1Xc7CxrqhWzNSDzD+/chS/zbYezmiwWLdQC09JdQKmthOw==", + "license": "BlueOak-1.0.0", "engines": { - "node": ">=16" + "node": ">=20" } }, "node_modules/@npmcli/promise-spawn/node_modules/which": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/which/-/which-6.0.0.tgz", - "integrity": "sha512-f+gEpIKMR9faW/JgAgPK1D7mekkFoqbmiwvNzuhsHetni20QSgzg9Vhn0g2JSJkkfehQnqdUAx7/e15qS1lPxg==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/which/-/which-6.0.1.tgz", + "integrity": "sha512-oGLe46MIrCRqX7ytPUf66EAYvdeMIZYn3WaocqqKZAxrBpkqHfL/qvTyJ/bTk5+AqHCjXmrv3CEWgy368zhRUg==", + "license": "ISC", "dependencies": { - "isexe": "^3.1.1" + "isexe": "^4.0.0" }, "bin": { "node-which": "bin/which.js" @@ -6257,52 +6967,32 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/@npmcli/redact/-/redact-4.0.0.tgz", "integrity": "sha512-gOBg5YHMfZy+TfHArfVogwgfBeQnKbbGo3pSUyK/gSI0AVu+pEiDVcKlQb0D8Mg1LNRZILZ6XG8I5dJ4KuAd9Q==", + "license": "ISC", "engines": { "node": "^20.17.0 || >=22.9.0" } }, "node_modules/@npmcli/run-script": { - "version": "10.0.3", - "resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-10.0.3.tgz", - "integrity": "sha512-ER2N6itRkzWbbtVmZ9WKaWxVlKlOeBFF1/7xx+KA5J1xKa4JjUwBdb6tDpk0v1qA+d+VDwHI9qmLcXSWcmi+Rw==", + "version": "10.0.4", + "resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-10.0.4.tgz", + "integrity": "sha512-mGUWr1uMnf0le2TwfOZY4SFxZGXGfm4Jtay/nwAa2FLNAKXUoUwaGwBMNH36UHPtinWfTSJ3nqFQr0091CxVGg==", + "license": "ISC", "dependencies": { "@npmcli/node-gyp": "^5.0.0", "@npmcli/package-json": "^7.0.0", "@npmcli/promise-spawn": "^9.0.0", "node-gyp": "^12.1.0", - "proc-log": "^6.0.0", - "which": "^6.0.0" + "proc-log": "^6.0.0" }, "engines": { "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/@npmcli/run-script/node_modules/isexe": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", - "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", - "engines": { - "node": ">=16" - } - }, "node_modules/@npmcli/run-script/node_modules/proc-log": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-6.1.0.tgz", "integrity": "sha512-iG+GYldRf2BQ0UDUAd6JQ/RwzaQy6mXmsk/IzlYyal4A4SNFw54MeH4/tLkF4I5WoWG9SQwuqWzS99jaFQHBuQ==", - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/@npmcli/run-script/node_modules/which": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/which/-/which-6.0.0.tgz", - "integrity": "sha512-f+gEpIKMR9faW/JgAgPK1D7mekkFoqbmiwvNzuhsHetni20QSgzg9Vhn0g2JSJkkfehQnqdUAx7/e15qS1lPxg==", - "dependencies": { - "isexe": "^3.1.1" - }, - "bin": { - "node-which": "bin/which.js" - }, + "license": "ISC", "engines": { "node": "^20.17.0 || >=22.9.0" } @@ -6430,6 +7120,9 @@ "cpu": [ "arm" ], + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -6450,6 +7143,9 @@ "cpu": [ "arm" ], + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -6470,6 +7166,9 @@ "cpu": [ "arm64" ], + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -6490,6 +7189,9 @@ "cpu": [ "arm64" ], + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -6510,6 +7212,9 @@ "cpu": [ "x64" ], + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -6530,6 +7235,9 @@ "cpu": [ "x64" ], + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -6623,64 +7331,251 @@ "license": "MIT", "optional": true }, - "node_modules/@popperjs/core": { - "version": "2.11.8", - "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", - "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", - "peer": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/popperjs" + "node_modules/@peculiar/asn1-cms": { + "version": "2.9.4", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-cms/-/asn1-cms-2.9.4.tgz", + "integrity": "sha512-cben7oxmQsUGZqotus7yt0srYdncOT6RNWcTQ77T2RFOXejYVYkXadrfePdRcrVpO9K95IRLKKglG2k38jKXuw==", + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.9.4", + "@peculiar/asn1-x509": "^2.9.4", + "@peculiar/asn1-x509-attr": "^2.9.4", + "asn1js": "^3.0.10", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=14" } }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.59.0.tgz", - "integrity": "sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==", - "cpu": [ - "arm" - ], + "node_modules/@peculiar/asn1-csr": { + "version": "2.9.4", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-csr/-/asn1-csr-2.9.4.tgz", + "integrity": "sha512-xd4YN4vpRjkDAQWVfZZkeu12IEND7DOpkqaHSIHxZl1uggUNa9Ju0QxY2jHvDAS9pP0zhRBytg8ifsnGo3V0jw==", "license": "MIT", - "optional": true, - "os": [ - "android" - ] + "dependencies": { + "@peculiar/asn1-schema": "^2.9.4", + "@peculiar/asn1-x509": "^2.9.4", + "asn1js": "^3.0.10", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=14" + } }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.59.0.tgz", - "integrity": "sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==", - "cpu": [ - "arm64" - ], + "node_modules/@peculiar/asn1-ecc": { + "version": "2.9.4", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-ecc/-/asn1-ecc-2.9.4.tgz", + "integrity": "sha512-JJXefFshRAuVAjWQo/39bkg1ywc1VaiO44S8RRC+Ykvf/u2KDmYffoDb0ZBPCR5uJy4AGKQhl8mX+Q8ShcWaXQ==", "license": "MIT", - "optional": true, - "os": [ - "android" - ] + "dependencies": { + "@peculiar/asn1-schema": "^2.9.4", + "@peculiar/asn1-x509": "^2.9.4", + "asn1js": "^3.0.10", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=14" + } }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.59.0.tgz", - "integrity": "sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==", - "cpu": [ - "arm64" - ], + "node_modules/@peculiar/asn1-pfx": { + "version": "2.9.4", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-pfx/-/asn1-pfx-2.9.4.tgz", + "integrity": "sha512-khuGzHTzNzk4GDlIBEILyIs6Lce0yn0ZBdoI9v93kmNncfZRhD+AQ5ODFqdhvoE8cMJF/JMTQ8yA+t1D14kqCw==", "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] + "dependencies": { + "@peculiar/asn1-cms": "^2.9.4", + "@peculiar/asn1-pkcs8": "^2.9.4", + "@peculiar/asn1-rsa": "^2.9.4", + "@peculiar/asn1-schema": "^2.9.4", + "asn1js": "^3.0.10", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=14" + } }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.59.0.tgz", - "integrity": "sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==", - "cpu": [ - "x64" - ], + "node_modules/@peculiar/asn1-pkcs8": { + "version": "2.9.4", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-pkcs8/-/asn1-pkcs8-2.9.4.tgz", + "integrity": "sha512-duRdotlUx9eDZe6QrQpQKl61RbWykCHBCkKayP8V8XdEFwlKHZ8qGGDMyS6Pye7OX7nLFttTTpRkJeet78ckwQ==", "license": "MIT", - "optional": true, + "dependencies": { + "@peculiar/asn1-schema": "^2.9.4", + "@peculiar/asn1-x509": "^2.9.4", + "asn1js": "^3.0.10", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@peculiar/asn1-pkcs9": { + "version": "2.9.4", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-pkcs9/-/asn1-pkcs9-2.9.4.tgz", + "integrity": "sha512-kaL4cNxBpdQE2dKlyZBqz4ygCrwffO+8wfoxTEqM1Z8RadvCeELBRzcv0dzM8aY9azHMwODO5nxU65zXmhToOQ==", + "license": "MIT", + "dependencies": { + "@peculiar/asn1-cms": "^2.9.4", + "@peculiar/asn1-pfx": "^2.9.4", + "@peculiar/asn1-pkcs8": "^2.9.4", + "@peculiar/asn1-schema": "^2.9.4", + "@peculiar/asn1-x509": "^2.9.4", + "@peculiar/asn1-x509-attr": "^2.9.4", + "asn1js": "^3.0.10", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@peculiar/asn1-rsa": { + "version": "2.9.4", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-rsa/-/asn1-rsa-2.9.4.tgz", + "integrity": "sha512-pZ96eD1PptovcWQ/GSmuNFXd/7EQJNlKfDaNCyE2rx3W0v6QFelkzquVqRSRyyDXXCYD69ZXJDzZ8GhIiQzKoA==", + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.9.4", + "@peculiar/asn1-x509": "^2.9.4", + "asn1js": "^3.0.10", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@peculiar/asn1-schema": { + "version": "2.9.4", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-schema/-/asn1-schema-2.9.4.tgz", + "integrity": "sha512-GjzePcT9Iw8NzeOPf73iNS9xM+TBhd/FilAfP+RQGkTMQJTVWtytN3JHJACCjf/ABNau5S7mS3g+DcuxmRgYEg==", + "license": "MIT", + "dependencies": { + "@peculiar/utils": "^2.0.2", + "asn1js": "^3.0.10", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@peculiar/asn1-x509": { + "version": "2.9.4", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-x509/-/asn1-x509-2.9.4.tgz", + "integrity": "sha512-CxhBo/RdEbMMob7T31ZdQjGuoyRFLVwrDzTn25bihzBasRg9kRm/0IxIPvhgQtcK/9dNcO1XQL2fuPugwELL0Q==", + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.9.4", + "@peculiar/utils": "^2.0.2", + "asn1js": "^3.0.10", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@peculiar/asn1-x509-attr": { + "version": "2.9.4", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-x509-attr/-/asn1-x509-attr-2.9.4.tgz", + "integrity": "sha512-ehQXbpQaQYycgu8OrvigwSPTFfVRcu0ECNYCWw+yzBp02Lw5paRqzzhUpfOgO2K38+WfFZuEz/0RPtam5g0OMg==", + "license": "MIT", + "dependencies": { + "@peculiar/asn1-schema": "^2.9.4", + "@peculiar/asn1-x509": "^2.9.4", + "asn1js": "^3.0.10", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@peculiar/utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@peculiar/utils/-/utils-2.0.3.tgz", + "integrity": "sha512-+oL3HPFRIZ1St2K50lWCXiioIgSoxzz7R1J3uF6neO2yl1sgmpgY6XXJH4BdpoDkMWznQTeYF6oWNDZLCdQ4eQ==", + "license": "MIT", + "dependencies": { + "tslib": "^2.8.1" + } + }, + "node_modules/@peculiar/x509": { + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/@peculiar/x509/-/x509-1.14.3.tgz", + "integrity": "sha512-C2Xj8FZ0uHWeCXXqX5B4/gVFQmtSkiuOolzAgutjTfseNOHT3pUjljDZsTSxXFGgio54bCzVFqmEOUrIVk8RDA==", + "license": "MIT", + "dependencies": { + "@peculiar/asn1-cms": "^2.6.0", + "@peculiar/asn1-csr": "^2.6.0", + "@peculiar/asn1-ecc": "^2.6.0", + "@peculiar/asn1-pkcs9": "^2.6.0", + "@peculiar/asn1-rsa": "^2.6.0", + "@peculiar/asn1-schema": "^2.6.0", + "@peculiar/asn1-x509": "^2.6.0", + "pvtsutils": "^1.3.6", + "reflect-metadata": "^0.2.2", + "tslib": "^2.8.1", + "tsyringe": "^4.10.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@popperjs/core": { + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", + "peer": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.59.0.tgz", + "integrity": "sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.59.0.tgz", + "integrity": "sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.59.0.tgz", + "integrity": "sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.59.0.tgz", + "integrity": "sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, "os": [ "darwin" ] @@ -6718,6 +7613,9 @@ "cpu": [ "arm" ], + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -6731,6 +7629,9 @@ "cpu": [ "arm" ], + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -6744,6 +7645,9 @@ "cpu": [ "arm64" ], + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -6757,6 +7661,9 @@ "cpu": [ "arm64" ], + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -6770,6 +7677,9 @@ "cpu": [ "loong64" ], + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -6783,6 +7693,9 @@ "cpu": [ "loong64" ], + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -6796,6 +7709,9 @@ "cpu": [ "ppc64" ], + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -6809,6 +7725,9 @@ "cpu": [ "ppc64" ], + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -6822,6 +7741,9 @@ "cpu": [ "riscv64" ], + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -6835,6 +7757,9 @@ "cpu": [ "riscv64" ], + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -6848,6 +7773,9 @@ "cpu": [ "s390x" ], + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -6861,6 +7789,9 @@ "cpu": [ "x64" ], + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -6874,6 +7805,9 @@ "cpu": [ "x64" ], + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -6959,13 +7893,13 @@ ] }, "node_modules/@schematics/angular": { - "version": "20.3.22", - "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-20.3.22.tgz", - "integrity": "sha512-wXTdFaPIBnSSNj/m0kclvPCYQOc2EGTQN1+Q3j9RIghS9gKgPxI1unSfgieJldZWKzcl8+WdB2zUuDzE7tEshQ==", + "version": "20.3.35", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-20.3.35.tgz", + "integrity": "sha512-og7zaTVyUYAiXrVqax8+/Uh9K/FExRQqoMC/jQ5X+ZNgmR3MfM+a5aEKRGNZxkUPeJReXF48FCFkBxxt6aCSWQ==", "license": "MIT", "dependencies": { - "@angular-devkit/core": "20.3.22", - "@angular-devkit/schematics": "20.3.22", + "@angular-devkit/core": "20.3.35", + "@angular-devkit/schematics": "20.3.35", "jsonc-parser": "3.3.1" }, "engines": { @@ -6975,9 +7909,9 @@ } }, "node_modules/@schematics/angular/node_modules/@angular-devkit/core": { - "version": "20.3.22", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-20.3.22.tgz", - "integrity": "sha512-1vZnZTAjGcCM+86v2al+2eiROiSw0uAWeVllfHSQe0KsKOP1FE8UUUiWChhxVn7vIxypphlfGunkeeIn1C/ZFw==", + "version": "20.3.35", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-20.3.35.tgz", + "integrity": "sha512-RefMFJA7qRBxEDu3a6bVNK9o5vcHXxN8xKaCzENBrOIO6XamthoGMZIJrIT213KpHoEbLTcJjESqGFCpYmY6oA==", "license": "MIT", "dependencies": { "ajv": "8.18.0", @@ -7034,12 +7968,6 @@ } } }, - "node_modules/@schematics/angular/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "license": "MIT" - }, "node_modules/@schematics/angular/node_modules/picomatch": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", @@ -7065,6 +7993,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/@sigstore/bundle/-/bundle-4.0.0.tgz", "integrity": "sha512-NwCl5Y0V6Di0NexvkTqdoVfmjTaQwoLM236r89KEojGmq/jMls8S+zb7yOwAPdXvbwfKDlP+lmXgAL4vKSQT+A==", + "license": "Apache-2.0", "dependencies": { "@sigstore/protobuf-specs": "^0.5.0" }, @@ -7073,32 +8002,35 @@ } }, "node_modules/@sigstore/core": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@sigstore/core/-/core-3.1.0.tgz", - "integrity": "sha512-o5cw1QYhNQ9IroioJxpzexmPjfCe7gzafd2RY3qnMpxr4ZEja+Jad/U8sgFpaue6bOaF+z7RVkyKVV44FN+N8A==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@sigstore/core/-/core-3.2.1.tgz", + "integrity": "sha512-qRsxPnCrbC/puegGxKuynfnxgLiHqWStrSjxkoB4YKqq3Z3s4cyZyj42ZdWFAEblNP65C+rBH8EuREHIXoi83g==", + "license": "Apache-2.0", "engines": { "node": "^20.17.0 || >=22.9.0" } }, "node_modules/@sigstore/protobuf-specs": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@sigstore/protobuf-specs/-/protobuf-specs-0.5.0.tgz", - "integrity": "sha512-MM8XIwUjN2bwvCg1QvrMtbBmpcSHrkhFSCu1D11NyPvDQ25HEc4oG5/OcQfd/Tlf/OxmKWERDj0zGE23jQaMwA==", + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/@sigstore/protobuf-specs/-/protobuf-specs-0.5.2.tgz", + "integrity": "sha512-SQqvFMt4V78fdjcDdYX6HbiVSOR4QK3ZgwCa2KOsopAgPIHy1rU5UDUmzLl02r5oyyaYcYHR1hpwDRk/yUe+Mw==", + "license": "Apache-2.0", "engines": { "node": "^18.17.0 || >=20.5.0" } }, "node_modules/@sigstore/sign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@sigstore/sign/-/sign-4.1.0.tgz", - "integrity": "sha512-Vx1RmLxLGnSUqx/o5/VsCjkuN5L7y+vxEEwawvc7u+6WtX2W4GNa7b9HEjmcRWohw/d6BpATXmvOwc78m+Swdg==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@sigstore/sign/-/sign-4.1.1.tgz", + "integrity": "sha512-Hf4xglukg0XXQ2RiD5vSoLjdPe8OBUPA8XeVjUObheuDcWdYWrnH/BNmxZCzkAy68MzmNCxXLeurJvs6hcP2OQ==", + "license": "Apache-2.0", "dependencies": { + "@gar/promise-retry": "^1.0.2", "@sigstore/bundle": "^4.0.0", - "@sigstore/core": "^3.1.0", + "@sigstore/core": "^3.2.0", "@sigstore/protobuf-specs": "^0.5.0", - "make-fetch-happen": "^15.0.3", - "proc-log": "^6.1.0", - "promise-retry": "^2.0.1" + "make-fetch-happen": "^15.0.4", + "proc-log": "^6.1.0" }, "engines": { "node": "^20.17.0 || >=22.9.0" @@ -7108,14 +8040,16 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-6.1.0.tgz", "integrity": "sha512-iG+GYldRf2BQ0UDUAd6JQ/RwzaQy6mXmsk/IzlYyal4A4SNFw54MeH4/tLkF4I5WoWG9SQwuqWzS99jaFQHBuQ==", + "license": "ISC", "engines": { "node": "^20.17.0 || >=22.9.0" } }, "node_modules/@sigstore/tuf": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@sigstore/tuf/-/tuf-4.0.1.tgz", - "integrity": "sha512-OPZBg8y5Vc9yZjmWCHrlWPMBqW5yd8+wFNl+thMdtcWz3vjVSoJQutF8YkrzI0SLGnkuFof4HSsWUhXrf219Lw==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@sigstore/tuf/-/tuf-4.0.2.tgz", + "integrity": "sha512-TCAzTy0xzdP79EnxSjq9KQ3eaR7+FmudLC6eRKknVKZbV7ZNlGLClAAQb/HMNJ5n2OBNk2GT1tEmU0xuPr+SLQ==", + "license": "Apache-2.0", "dependencies": { "@sigstore/protobuf-specs": "^0.5.0", "tuf-js": "^4.1.0" @@ -7125,12 +8059,13 @@ } }, "node_modules/@sigstore/verify": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@sigstore/verify/-/verify-3.1.0.tgz", - "integrity": "sha512-mNe0Iigql08YupSOGv197YdHpPPr+EzDZmfCgMc7RPNaZTw5aLN01nBl6CHJOh3BGtnMIj83EeN4butBchc8Ag==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@sigstore/verify/-/verify-3.1.1.tgz", + "integrity": "sha512-qv7+G3J2cc6wwFj3yKvXOamzqhMwSk1ogPGmhpS8iXllcPrJaIIBA+4HbttlHVu1pqWTdmaCH/WE7UOC51kdoA==", + "license": "Apache-2.0", "dependencies": { "@sigstore/bundle": "^4.0.0", - "@sigstore/core": "^3.1.0", + "@sigstore/core": "^3.2.1", "@sigstore/protobuf-specs": "^0.5.0" }, "engines": { @@ -7188,40 +8123,45 @@ "devOptional": true }, "node_modules/@standard-schema/spec": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.0.0.tgz", - "integrity": "sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", + "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", "license": "MIT", "optional": true }, "node_modules/@tsconfig/node10": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", - "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", - "dev": true + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.13.tgz", + "integrity": "sha512-gcLdvR9HO1ZJBypsOGqaP6TFEzb6vIta0KSTLt9NAQ6pXQO3cRgSVyCN6pzYqI9DlJgY71XKO0dpDhCf08b3pg==", + "dev": true, + "license": "MIT" }, "node_modules/@tsconfig/node12": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@tsconfig/node14": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@tsconfig/node16": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", - "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", - "dev": true + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true, + "license": "MIT" }, "node_modules/@tufjs/canonical-json": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@tufjs/canonical-json/-/canonical-json-2.0.0.tgz", "integrity": "sha512-yVtV8zsdo8qFHe+/3kw81dSLyF7D576A5cCFCi4X7B39tWT7SekaEFUnvnWJHz+9qO7qJTah1JbrDjWKqFtdWA==", + "license": "MIT", "engines": { "node": "^16.14.0 || >=18.0.0" } @@ -7230,6 +8170,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/@tufjs/models/-/models-4.1.0.tgz", "integrity": "sha512-Y8cK9aggNRsqJVaKUlEYs4s7CvQ1b1ta2DVPyAimb0I2qhzjNk+A+mxvll/klL0RlfuIUei8BF7YWiua4kQqww==", + "license": "MIT", "dependencies": { "@tufjs/canonical-json": "2.0.0", "minimatch": "^10.1.1" @@ -7248,24 +8189,24 @@ } }, "node_modules/@tufjs/models/node_modules/brace-expansion": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", - "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", + "version": "5.0.9", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.9.tgz", + "integrity": "sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==", "license": "MIT", "dependencies": { "balanced-match": "^4.0.2" }, "engines": { - "node": "18 || 20 || >=22" + "node": "20 || >=22" } }, "node_modules/@tufjs/models/node_modules/minimatch": { - "version": "10.2.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", - "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", + "version": "10.2.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.6.tgz", + "integrity": "sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==", "license": "BlueOak-1.0.0", "dependencies": { - "brace-expansion": "^5.0.2" + "brace-expansion": "^5.0.8" }, "engines": { "node": "18 || 20 || >=22" @@ -7372,12 +8313,6 @@ "@types/node": "*" } }, - "node_modules/@types/cookie": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz", - "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==", - "devOptional": true - }, "node_modules/@types/cors": { "version": "2.8.17", "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.17.tgz", @@ -7479,15 +8414,6 @@ "undici-types": "~7.16.0" } }, - "node_modules/@types/node-forge": { - "version": "1.3.14", - "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.14.tgz", - "integrity": "sha512-mhVF2BnD4BO+jtOp7z1CdzaK4mbuK0LLQYAvdOLqHTavxFNq4zA1EmYkpnFjP8HOUzedfQkRnp0E2ulSAYSzAw==", - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@types/qrcode": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@types/qrcode/-/qrcode-1.5.0.tgz", @@ -7588,31 +8514,21 @@ "@types/node": "*" } }, - "node_modules/@types/yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==", - "optional": true, - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.46.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.46.2.tgz", - "integrity": "sha512-ZGBMToy857/NIPaaCucIUQgqueOiq7HeAKkhlvqVV4lm089zUFW6ikRySx2v+cAhKeUCPuWVHeimyk6Dw1iY3w==", + "version": "8.68.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.68.0.tgz", + "integrity": "sha512-WASHDpCm6qO5jj9g1a+8NiW5+GCkAyLReR56/4VruYmNgfUmqpxOfZ2Yfb8xGfJPWv5Qi6LSD8sXdces3vbp/Q==", "dev": true, "license": "MIT", "dependencies": { - "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.46.2", - "@typescript-eslint/type-utils": "8.46.2", - "@typescript-eslint/utils": "8.46.2", - "@typescript-eslint/visitor-keys": "8.46.2", - "graphemer": "^1.4.0", - "ignore": "^7.0.0", + "@eslint-community/regexpp": "^4.12.2", + "@typescript-eslint/scope-manager": "8.68.0", + "@typescript-eslint/type-utils": "8.68.0", + "@typescript-eslint/utils": "8.68.0", + "@typescript-eslint/visitor-keys": "8.68.0", + "ignore": "^7.0.5", "natural-compare": "^1.4.0", - "ts-api-utils": "^2.1.0" + "ts-api-utils": "^2.5.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -7622,23 +8538,23 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.46.2", - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <6.0.0" + "@typescript-eslint/parser": "^8.68.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/parser": { - "version": "8.46.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.46.2.tgz", - "integrity": "sha512-BnOroVl1SgrPLywqxyqdJ4l3S2MsKVLDVxZvjI1Eoe8ev2r3kGDo+PcMihNmDE+6/KjkTubSJnmqGZZjQSBq/g==", + "version": "8.68.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.68.0.tgz", + "integrity": "sha512-fHq2VC1kpyYfvEcbiMjOpySY4WS7voEp89yAThrHRX5sm9j2lzYppCb2umFMEed4fWcyeLjHxrz0mpjNBaBxMQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.46.2", - "@typescript-eslint/types": "8.46.2", - "@typescript-eslint/typescript-estree": "8.46.2", - "@typescript-eslint/visitor-keys": "8.46.2", - "debug": "^4.3.4" + "@typescript-eslint/scope-manager": "8.68.0", + "@typescript-eslint/types": "8.68.0", + "@typescript-eslint/typescript-estree": "8.68.0", + "@typescript-eslint/visitor-keys": "8.68.0", + "debug": "^4.4.3" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -7648,41 +8564,45 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <6.0.0" + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" } }, - "node_modules/@typescript-eslint/project-service": { - "version": "8.46.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.46.2.tgz", - "integrity": "sha512-PULOLZ9iqwI7hXcmL4fVfIsBi6AN9YxRc0frbvmg8f+4hQAjQ5GYNKK0DIArNo+rOKmR/iBYwkpBmnIwin4wBg==", + "node_modules/@typescript-eslint/parser/node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.46.2", - "@typescript-eslint/types": "^8.46.2", - "debug": "^4.3.4" + "ms": "^2.1.3" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "node": ">=6.0" }, - "peerDependencies": { - "typescript": ">=4.8.4 <6.0.0" + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "8.46.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.46.2.tgz", - "integrity": "sha512-LF4b/NmGvdWEHD2H4MsHD8ny6JpiVNDzrSZr3CsckEgCbAGZbYM4Cqxvi9L+WqDMT+51Ozy7lt2M+d0JLEuBqA==", + "node_modules/@typescript-eslint/parser/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@typescript-eslint/project-service": { + "version": "8.68.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.68.0.tgz", + "integrity": "sha512-5GQtWZCXFcFYux955pvoS02WLc49pXNlvIxocKjS0clvwo3in1RdlzVKyiqQH9vE5AKWFLTaUgeQkOrTS+0Qxw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.46.2", - "@typescript-eslint/visitor-keys": "8.46.2" + "@typescript-eslint/tsconfig-utils": "^8.68.0", + "@typescript-eslint/types": "^8.68.0", + "debug": "^4.4.3" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -7690,37 +8610,45 @@ "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" } }, - "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.46.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.46.2.tgz", - "integrity": "sha512-a7QH6fw4S57+F5y2FIxxSDyi5M4UfGF+Jl1bCGd7+L4KsaUY80GsiF/t0UoRFDHAguKlBaACWJRmdrc6Xfkkag==", + "node_modules/@typescript-eslint/project-service/node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "dev": true, "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "dependencies": { + "ms": "^2.1.3" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "engines": { + "node": ">=6.0" }, - "peerDependencies": { - "typescript": ">=4.8.4 <6.0.0" + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/@typescript-eslint/type-utils": { - "version": "8.46.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.46.2.tgz", - "integrity": "sha512-HbPM4LbaAAt/DjxXaG9yiS9brOOz6fabal4uvUmaUYe6l3K1phQDMQKBRUrr06BQkxkvIZVVHttqiybM9nJsLA==", + "node_modules/@typescript-eslint/project-service/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.68.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.68.0.tgz", + "integrity": "sha512-T5eXpcaJNg8bhjHJ8Rjp68Vq/QBteYtTKY8TZqVNPaUbuz0f6jI9t6aDkylwvalpAB9XTTFeFOjrjXAZ3YvmVA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.46.2", - "@typescript-eslint/typescript-estree": "8.46.2", - "@typescript-eslint/utils": "8.46.2", - "debug": "^4.3.4", - "ts-api-utils": "^2.1.0" + "@typescript-eslint/types": "8.68.0", + "@typescript-eslint/visitor-keys": "8.68.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -7728,16 +8656,12 @@ "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <6.0.0" } }, - "node_modules/@typescript-eslint/types": { - "version": "8.46.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.46.2.tgz", - "integrity": "sha512-lNCWCbq7rpg7qDsQrd3D6NyWYu+gkTENkG5IKYhUIcxSb59SQC/hEQ+MrG4sTgBVghTonNWq42bA/d4yYumldQ==", + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.68.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.68.0.tgz", + "integrity": "sha512-F7zrGQfiJHojPwi8vhxZQC1tWtJzvL74cK/nqri2lk8YUXvYaYwl263xOJ69jDWPUk1hmcdoayFwk9lX09npVw==", "dev": true, "license": "MIT", "engines": { @@ -7746,25 +8670,23 @@ "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" } }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.46.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.46.2.tgz", - "integrity": "sha512-f7rW7LJ2b7Uh2EiQ+7sza6RDZnajbNbemn54Ob6fRwQbgcIn+GWfyuHDHRYgRoZu1P4AayVScrRW+YfbTvPQoQ==", + "node_modules/@typescript-eslint/type-utils": { + "version": "8.68.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.68.0.tgz", + "integrity": "sha512-X77zqoY1EjeWGs/0JNxeaMfp5C5lIz4Tw8y66F1Ne8Faq6g424sBNYM6xBAqElfGZPLpWS+CZAp0DXyKDzWiHg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.46.2", - "@typescript-eslint/tsconfig-utils": "8.46.2", - "@typescript-eslint/types": "8.46.2", - "@typescript-eslint/visitor-keys": "8.46.2", - "debug": "^4.3.4", - "fast-glob": "^3.3.2", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^2.1.0" + "@typescript-eslint/types": "8.68.0", + "@typescript-eslint/typescript-estree": "8.68.0", + "@typescript-eslint/utils": "8.68.0", + "debug": "^4.4.3", + "ts-api-utils": "^2.5.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -7774,46 +8696,200 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "typescript": ">=4.8.4 <6.0.0" + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" } }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.3.tgz", - "integrity": "sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==", + "node_modules/@typescript-eslint/type-utils/node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@typescript-eslint/types": { + "version": "8.68.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.68.0.tgz", + "integrity": "sha512-9RnpsGJjrAllCMefGVVsImJM24YurhC0Q1h4UbvivtvOqXmR/vEJge2OoE++z9m6hyg8T1Q8t5SNT6tHSbrxcg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.68.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.68.0.tgz", + "integrity": "sha512-OKKsD0tYmoNiU5PW2zehO1yO56jYOm1ShYlxon/Z0SJNidAkdVg86eg9ruRuoXf8xfnuWZGbwDsStkoXbZtIIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.68.0", + "@typescript-eslint/tsconfig-utils": "8.68.0", + "@typescript-eslint/types": "8.68.0", + "@typescript-eslint/visitor-keys": "8.68.0", + "debug": "^4.4.3", + "minimatch": "^10.2.2", + "semver": "^7.7.3", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "5.0.9", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.9.tgz", + "integrity": "sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "dev": true, "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0" + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "9.0.9", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", - "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", + "version": "10.2.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.6.tgz", + "integrity": "sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==", "dev": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "dependencies": { - "brace-expansion": "^2.0.2" + "brace-expansion": "^5.0.8" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/picomatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz", + "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/tinyglobby": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, "node_modules/@typescript-eslint/utils": { - "version": "8.46.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.46.2.tgz", - "integrity": "sha512-sExxzucx0Tud5tE0XqR0lT0psBQvEpnpiul9XbGUB1QwpWJJAps1O/Z7hJxLGiZLBKMCutjTzDgmd1muEhBnVg==", + "version": "8.68.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.68.0.tgz", + "integrity": "sha512-PB5gJMMOg0Q5P1tsgWtEAqQacJXq0qEqRHDX/YJ4FaTMLfZPpHB3gjl2EJuiZyPABxmj4ZQYiY9m1bdAJ5y7tQ==", "dev": true, "license": "MIT", "dependencies": { - "@eslint-community/eslint-utils": "^4.7.0", - "@typescript-eslint/scope-manager": "8.46.2", - "@typescript-eslint/types": "8.46.2", - "@typescript-eslint/typescript-estree": "8.46.2" + "@eslint-community/eslint-utils": "^4.9.1", + "@typescript-eslint/scope-manager": "8.68.0", + "@typescript-eslint/types": "8.68.0", + "@typescript-eslint/typescript-estree": "8.68.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -7823,19 +8899,19 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <6.0.0" + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.46.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.46.2.tgz", - "integrity": "sha512-tUFMXI4gxzzMXt4xpGJEsBsTox0XbNQ1y94EwlD/CuZwFcQP79xfQqMhau9HsRc/J0cAPA/HZt1dZPtGn9V/7w==", + "version": "8.68.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.68.0.tgz", + "integrity": "sha512-YR65gGdGvTUAWLldC3xLOvOzamdGzB4A5/N8rehEaHs3Zvoe39BhgY+u0SPch1OvrVTfLcc55wsSgK2NcnTS/A==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.46.2", - "eslint-visitor-keys": "^4.2.1" + "@typescript-eslint/types": "8.68.0", + "eslint-visitor-keys": "^5.0.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -7846,13 +8922,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", - "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", "dev": true, "license": "Apache-2.0", "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^20.19.0 || ^22.13.0 || >=24" }, "funding": { "url": "https://opencollective.com/eslint" @@ -8223,6 +9299,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-4.0.0.tgz", "integrity": "sha512-a1wflyaL0tHtJSmLSOVybYhy22vRih4eduhhrkcjgrWGnRfrZtovJ2FRjxuTtkkj47O/baf0R86QU5OuYpz8fA==", + "license": "ISC", "engines": { "node": "^20.17.0 || >=22.9.0" } @@ -8261,6 +9338,19 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, + "node_modules/acorn-walk": { + "version": "8.3.5", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.5.tgz", + "integrity": "sha512-HEHNfbars9v4pgpW6SO1KSPkfoS0xVOM/9UzkJltjlsHZmJasxg8aXkuZa7SMf8vKGIBhpUsPluQSqhJFCqebw==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/adjust-sourcemap-loader": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-4.0.0.tgz", @@ -8282,30 +9372,16 @@ "node": ">= 14" } }, - "node_modules/aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "optional": true, - "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/ajv": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", - "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", - "dev": true, + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz", + "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==", "license": "MIT", "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" }, "funding": { "type": "github", @@ -8329,28 +9405,6 @@ } } }, - "node_modules/ajv-formats/node_modules/ajv": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", - "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ajv-formats/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "license": "MIT" - }, "node_modules/algoliasearch": { "version": "5.35.0", "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-5.35.0.tgz", @@ -8385,15 +9439,15 @@ } }, "node_modules/ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "optional": true, + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.3.0.tgz", + "integrity": "sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg==", + "license": "MIT", "dependencies": { - "type-fest": "^0.21.3" + "environment": "^1.0.0" }, "engines": { - "node": ">=8" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -8447,9 +9501,9 @@ } }, "node_modules/arch": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz", - "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/arch/-/arch-3.0.0.tgz", + "integrity": "sha512-AmIAC+Wtm2AU8lGfTtHsw0Y9Qtftx2YXEEtiBP10xFUtMOA+sHHx6OAddyL52mUKh1vsXQ6/w1mVDptZCyUt4Q==", "funding": [ { "type": "github", @@ -8464,13 +9518,15 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "optional": true }, "node_modules/arg": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/argparse": { "version": "2.0.1", @@ -8494,6 +9550,20 @@ "safer-buffer": "~2.1.0" } }, + "node_modules/asn1js": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/asn1js/-/asn1js-3.0.10.tgz", + "integrity": "sha512-S2s3aOytiKdFRdulw2qPE51MzjzVOisppcVv7jVFR+Kw0kxwvFrDcYA0h7Ndqbmj0HkMIXYWaoj7fli8kgx1eg==", + "license": "BSD-3-Clause", + "dependencies": { + "pvtsutils": "^1.3.6", + "pvutils": "^1.1.5", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", @@ -8513,20 +9583,12 @@ "node": "*" } }, - "node_modules/astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "optional": true, - "engines": { - "node": ">=8" - } - }, "node_modules/async-each-series": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/async-each-series/-/async-each-series-0.1.1.tgz", "integrity": "sha512-p4jj6Fws4Iy2m0iCmI2am2ZNZCgbdgE+P8F/8csmn2vx7ixXrO2zGcuNsD46X5uZSVecmkEy/M06X2vG8KD6dQ==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=0.8.0" } @@ -8601,22 +9663,54 @@ "optional": true }, "node_modules/axios": { - "version": "1.13.5", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.5.tgz", - "integrity": "sha512-cz4ur7Vb0xS4/KUN0tPWe44eqxrIu31me+fbang3ijiNscE129POzipJJA6zniq2C/Z6sJCjMimjS8Lc/GAs8Q==", + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.20.0.tgz", + "integrity": "sha512-r8aOh8j9cGKpgQAqpzrUHnSIc6a59Y3Xf/cv8sy1DrHCkZHzQGEuoq1tARk6qSyDdtQGSDgpb9kFlruzPvrgwg==", + "license": "MIT", + "optional": true, + "dependencies": { + "follow-redirects": "^1.16.0", + "form-data": "^4.0.6", + "https-proxy-agent": "^5.0.1", + "proxy-from-env": "^2.1.0" + } + }, + "node_modules/axios/node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/axios/node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "license": "MIT", "optional": true, "dependencies": { - "follow-redirects": "^1.15.11", - "form-data": "^4.0.5", - "proxy-from-env": "^1.1.0" + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" } }, "node_modules/axios/node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz", + "integrity": "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==", "license": "MIT", - "optional": true + "optional": true, + "engines": { + "node": ">=10" + } }, "node_modules/babel-loader": { "version": "10.0.0", @@ -8844,36 +9938,57 @@ "optional": true }, "node_modules/body-parser": { - "version": "1.20.4", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.4.tgz", - "integrity": "sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.3.0.tgz", + "integrity": "sha512-2cGmJupaNgg+QUwVLAucDuWuoMZ6EX9iHDRswZ5lsNYEmwPaRknMPCLZz07yTzVq/83p4o/wzbDZbBrTvGGTIw==", "license": "MIT", "dependencies": { - "bytes": "~3.1.2", - "content-type": "~1.0.5", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "~1.2.0", - "http-errors": "~2.0.1", - "iconv-lite": "~0.4.24", - "on-finished": "~2.4.1", - "qs": "~6.14.0", - "raw-body": "~2.5.3", - "type-is": "~1.6.18", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" + "bytes": "^3.1.2", + "content-type": "^2.0.0", + "debug": "^4.4.3", + "http-errors": "^2.0.1", + "iconv-lite": "^0.7.2", + "on-finished": "^2.4.1", + "qs": "^6.15.2", + "raw-body": "^3.0.2", + "type-is": "^2.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/body-parser/node_modules/content-type": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-2.1.0.tgz", + "integrity": "sha512-mj7UPXE0jaqaOsukNZRUEfEi2AcL7C/vwmwcHV0O97eO1E1pxBZuyjlZrx5seTaNBg1U6+o35wpa35Qfcc+7ag==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/body-parser/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "license": "MIT", "dependencies": { - "ms": "2.0.0" + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, "node_modules/body-parser/node_modules/http-errors": { @@ -8896,10 +10011,26 @@ "url": "https://opencollective.com/express" } }, + "node_modules/body-parser/node_modules/iconv-lite": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.3.tgz", + "integrity": "sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, "node_modules/body-parser/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "license": "MIT" }, "node_modules/body-parser/node_modules/on-finished": { @@ -8914,6 +10045,21 @@ "node": ">= 0.8" } }, + "node_modules/body-parser/node_modules/raw-body": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz", + "integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==", + "license": "MIT", + "dependencies": { + "bytes": "~3.1.2", + "http-errors": "~2.0.1", + "iconv-lite": "~0.7.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, "node_modules/body-parser/node_modules/statuses": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", @@ -8924,9 +10070,9 @@ } }, "node_modules/bonjour-service": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.3.0.tgz", - "integrity": "sha512-3YuAUiSkWykd+2Azjgyxei8OWf8thdn8AITIog2M4UICzoqfjlqr64WIjEXZllf/W6vK1goqleSR6brGomxQqA==", + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.4.4.tgz", + "integrity": "sha512-jCZcVv7eoc4QesRscwEZtSROBen+6LpKAmBIsQYQrsAeVHLyMXWX/t6eIV5KiRZYNUBl8eVqImEEMQ8L5+c/Kw==", "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", @@ -8959,9 +10105,9 @@ } }, "node_modules/brace-expansion": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", - "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", + "version": "1.1.18", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz", + "integrity": "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==", "devOptional": true, "license": "MIT", "dependencies": { @@ -8981,13 +10127,14 @@ } }, "node_modules/browser-sync": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/browser-sync/-/browser-sync-3.0.3.tgz", - "integrity": "sha512-91hoBHKk1C4pGeD+oE9Ld222k2GNQEAsI5AElqR8iLLWNrmZR2LPP8B0h8dpld9u7kro5IEUB3pUb0DJ3n1cRQ==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/browser-sync/-/browser-sync-3.0.4.tgz", + "integrity": "sha512-mcYOIy4BW6sWSEnTSBjQwWsnbx2btZX78ajTTjdNfyC/EqQVcIe0nQR6894RNAMtvlfAnLaH9L2ka97zpvgenA==", "devOptional": true, + "license": "Apache-2.0", "dependencies": { - "browser-sync-client": "^3.0.3", - "browser-sync-ui": "^3.0.3", + "browser-sync-client": "^3.0.4", + "browser-sync-ui": "^3.0.4", "bs-recipes": "1.3.4", "chalk": "4.1.2", "chokidar": "^3.5.1", @@ -8995,7 +10142,7 @@ "connect-history-api-fallback": "^1", "dev-ip": "^1.0.1", "easy-extender": "^2.3.4", - "eazy-logger": "^4.0.1", + "eazy-logger": "^4.1.0", "etag": "^1.8.1", "fresh": "^0.5.2", "fs-extra": "3.0.1", @@ -9023,10 +10170,11 @@ } }, "node_modules/browser-sync-client": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/browser-sync-client/-/browser-sync-client-3.0.3.tgz", - "integrity": "sha512-TOEXaMgYNjBYIcmX5zDlOdjEqCeCN/d7opf/fuyUD/hhGVCfP54iQIDhENCi012AqzYZm3BvuFl57vbwSTwkSQ==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/browser-sync-client/-/browser-sync-client-3.0.4.tgz", + "integrity": "sha512-+ew5ubXzGRKVjquBL3u6najS40TG7GxCdyBll0qSRc/n+JRV9gb/yDdRL1IAgRHqjnJTdqeBKKIQabjvjRSYRQ==", "devOptional": true, + "license": "ISC", "dependencies": { "etag": "1.8.1", "fresh": "0.5.2", @@ -9037,10 +10185,11 @@ } }, "node_modules/browser-sync-ui": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/browser-sync-ui/-/browser-sync-ui-3.0.3.tgz", - "integrity": "sha512-FcGWo5lP5VodPY6O/f4pXQy5FFh4JK0f2/fTBsp0Lx1NtyBWs/IfPPJbW8m1ujTW/2r07oUXKTF2LYZlCZktjw==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/browser-sync-ui/-/browser-sync-ui-3.0.4.tgz", + "integrity": "sha512-5Po3YARCZ/8yQHFzvrSjn8+hBUF7ZWac39SHsy8Tls+7tE62iq6pYWxpVU6aOOMAGD21RwFQhQeqmJPf70kHEQ==", "devOptional": true, + "license": "Apache-2.0", "dependencies": { "async-each-series": "0.1.1", "chalk": "4.1.2", @@ -9232,15 +10381,6 @@ "ieee754": "^1.1.13" } }, - "node_modules/buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", - "optional": true, - "engines": { - "node": "*" - } - }, "node_modules/buffer-from": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", @@ -9269,6 +10409,15 @@ "node": ">= 0.8" } }, + "node_modules/bytestreamjs": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bytestreamjs/-/bytestreamjs-2.0.1.tgz", + "integrity": "sha512-U1Z/ob71V/bXfVABvNr/Kumf5VyeQRBEm6Txb0PQ6S7V5GpBM3w4Cbqz/xPDicR5tN0uvDifng8C+5qECeGwyQ==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/cac": { "version": "6.7.14", "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", @@ -9280,9 +10429,10 @@ } }, "node_modules/cacache": { - "version": "20.0.3", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-20.0.3.tgz", - "integrity": "sha512-3pUp4e8hv07k1QlijZu6Kn7c9+ZpWWk4j3F8N3xPuCExULobqJydKYOTj1FTq58srkJsXvO7LbGAH4C0ZU3WGw==", + "version": "20.0.4", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-20.0.4.tgz", + "integrity": "sha512-M3Lab8NPYlZU2exsL3bMVvMrMqgwCnMWfdZbK28bn3pK6APT/Te/I8hjRPNu1uwORY9a1eEQoifXbKPQMfMTOA==", + "license": "ISC", "dependencies": { "@npmcli/fs": "^5.0.0", "fs-minipass": "^3.0.0", @@ -9293,28 +10443,17 @@ "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", "p-map": "^7.0.2", - "ssri": "^13.0.0", - "unique-filename": "^5.0.0" + "ssri": "^13.0.0" }, "engines": { "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/cacache/node_modules/p-map": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-7.0.4.tgz", - "integrity": "sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ==", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/cachedir": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.3.0.tgz", - "integrity": "sha512-A+Fezp4zxnit6FanDmv9EqXNAi3vt9DWp51/71UEhXukb7QUuvtv9344h91dyAxuTLoSYJFU299qzR3tzwPAhw==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.4.0.tgz", + "integrity": "sha512-9EtFOZR8g22CL7BWjJ9BUx1+A/djkofnyW3aOXZORNW2kxoUpx2h+uN2cOqwPmFhnpVmxg+KW2OjOSgChTEvsQ==", + "license": "MIT", "optional": true, "engines": { "node": ">=6" @@ -9490,10 +10629,54 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", + "license": "BlueOak-1.0.0", "engines": { "node": ">=18" } }, + "node_modules/chrome-remote-interface": { + "version": "0.33.3", + "resolved": "https://registry.npmjs.org/chrome-remote-interface/-/chrome-remote-interface-0.33.3.tgz", + "integrity": "sha512-zNnn0prUL86Teru6UCAZ1yU1XeXljHl3gj7OrfPcarEfU62OUU4IujDPdTDW3dAWwRqN3ZMG/Chhkh2gPL/wiw==", + "license": "MIT", + "optional": true, + "dependencies": { + "commander": "2.11.x", + "ws": "^7.2.0" + }, + "bin": { + "chrome-remote-interface": "bin/client.js" + } + }, + "node_modules/chrome-remote-interface/node_modules/commander": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", + "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", + "license": "MIT", + "optional": true + }, + "node_modules/chrome-remote-interface/node_modules/ws": { + "version": "7.5.13", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.13.tgz", + "integrity": "sha512-rsKI6xDBFVf4r/x8XyChGK04QR/XHroxs/jUcoWvtEZM8TPU/X/uIY9B1CsSzYws9ZJb/6bbBu7dPhFW00CAoA==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, "node_modules/chrome-trace-event": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", @@ -9518,25 +10701,19 @@ "node": ">=8" } }, - "node_modules/clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "optional": true, - "engines": { - "node": ">=6" - } - }, "node_modules/cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "optional": true, + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", + "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", + "license": "MIT", "dependencies": { - "restore-cursor": "^3.1.0" + "restore-cursor": "^5.0.0" }, "engines": { - "node": ">=8" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/cli-spinners": { @@ -9568,21 +10745,68 @@ } }, "node_modules/cli-truncate": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", - "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-5.2.0.tgz", + "integrity": "sha512-xRwvIOMGrfOAnM1JYtqQImuaNtDEv9v6oIYAs4LIHwTiKee8uwvIi363igssOC0O5U04i4AlENs79LQLu9tEMw==", + "license": "MIT", "optional": true, "dependencies": { - "slice-ansi": "^3.0.0", - "string-width": "^4.2.0" + "slice-ansi": "^8.0.0", + "string-width": "^8.2.0" }, "engines": { - "node": ">=8" + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate/node_modules/ansi-regex": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.3.0.tgz", + "integrity": "sha512-WpDfL7NO6j7tH88IDBNVdUJxDh9nmCteAVW9dsep846XdwF4naCBK+/tGLX3KJgcpgMRXCFlTM2hKGoK9FsdrQ==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/cli-truncate/node_modules/string-width": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.2.2.tgz", + "integrity": "sha512-GaPUh5gfdrYzqeVNZvUfT23vYYxXzKYidUcnMtJg/3rxRV63EFZy3k6xfKlmfeJD0176lnUV/Usr3XcwSvFzpg==", + "license": "MIT", + "optional": true, + "dependencies": { + "get-east-asian-width": "^1.5.0", + "strip-ansi": "^7.1.2" + }, + "engines": { + "node": ">=20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/cli-truncate/node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "license": "MIT", + "optional": true, + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, "node_modules/cli-width": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", @@ -9765,6 +10989,7 @@ "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz", "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==", "devOptional": true, + "license": "MIT", "engines": { "node": ">=0.8" } @@ -9812,9 +11037,9 @@ } }, "node_modules/content-disposition": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.1.tgz", - "integrity": "sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.1.0.tgz", + "integrity": "sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g==", "license": "MIT", "engines": { "node": ">=18" @@ -9828,6 +11053,7 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -9961,7 +11187,8 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/cross-spawn": { "version": "7.0.6", @@ -10067,41 +11294,39 @@ } }, "node_modules/cypress": { - "version": "15.9.0", - "resolved": "https://registry.npmjs.org/cypress/-/cypress-15.9.0.tgz", - "integrity": "sha512-Ks6Bdilz3TtkLZtTQyqYaqtL/WT3X3APKaSLhTV96TmTyudzSjc6EJsJCHmBb7DxO+3R12q3Jkbjgm/iPgmwfg==", + "version": "15.21.1", + "resolved": "https://registry.npmjs.org/cypress/-/cypress-15.21.1.tgz", + "integrity": "sha512-ogHpHMj0XNlZA5MGzjg8SWHf0eMw9lTwVQRKjpcT1GzNTxNUjwnHA8YCG6nOJ8ThU+XZaUxJgpMYZnJ//8aDaw==", "hasInstallScript": true, + "license": "MIT", "optional": true, "dependencies": { - "@cypress/request": "^3.0.10", + "@cypress/request": "^4.0.0", "@cypress/xvfb": "^1.2.4", "@types/sinonjs__fake-timers": "8.1.1", "@types/sizzle": "^2.3.2", "@types/tmp": "^0.2.3", - "arch": "^2.2.0", + "arch": "^3.0.0", "blob-util": "^2.0.2", "bluebird": "^3.7.2", "buffer": "^5.7.1", - "cachedir": "^2.3.0", + "cachedir": "^2.4.0", "chalk": "^4.1.0", + "chrome-remote-interface": "0.33.3", "ci-info": "^4.1.0", - "cli-cursor": "^3.1.0", "cli-table3": "0.6.1", "commander": "^6.2.1", "common-tags": "^1.8.0", "dayjs": "^1.10.4", "debug": "^4.3.4", - "enquirer": "^2.3.6", "eventemitter2": "6.4.7", "execa": "4.1.0", "executable": "^4.1.1", - "extract-zip": "2.0.1", - "figures": "^3.2.0", "fs-extra": "^9.1.0", "hasha": "5.2.2", "is-installed-globally": "~0.4.0", - "listr2": "^3.8.3", - "lodash": "^4.17.21", + "listr2": "^9.0.5", + "lodash": "^4.17.23", "log-symbols": "^4.0.0", "minimist": "^1.2.8", "ospath": "^1.2.2", @@ -10110,11 +11335,11 @@ "proxy-from-env": "1.0.0", "request-progress": "^3.0.0", "supports-color": "^8.1.1", - "systeminformation": "^5.27.14", + "systeminformation": "^5.31.1", "tmp": "~0.2.4", "tree-kill": "1.2.2", "untildify": "^4.0.0", - "yauzl": "^2.10.0" + "yauzl": "^3.3.1" }, "bin": { "cypress": "bin/cypress" @@ -10220,16 +11445,6 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/cypress/node_modules/tmp": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.5.tgz", - "integrity": "sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=14.14" - } - }, "node_modules/dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", @@ -10329,9 +11544,9 @@ "license": "MIT" }, "node_modules/default-browser": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.5.0.tgz", - "integrity": "sha512-H9LMLr5zwIbSxrmvikGuI/5KGhZ8E2zH3stkMgM5LpOWDutGM2JZaj460Udnf1a+946zc7YBgrqEWwbk7zHvGw==", + "version": "5.5.1", + "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.5.1.tgz", + "integrity": "sha512-m1pAzaJgZ/gssEqlOhJkPJp8Xly7QyW6xcrkUa2KKcDeDSEMP7X8xipU3snUcfisTQx0w1AGae+9UtJSfVnXGw==", "license": "MIT", "dependencies": { "bundle-name": "^4.1.0", @@ -10619,27 +11834,6 @@ "node": ">= 0.8" } }, - "node_modules/encoding": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", - "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", - "optional": true, - "dependencies": { - "iconv-lite": "^0.6.2" - } - }, - "node_modules/encoding/node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "optional": true, - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/end-of-stream": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", @@ -10650,39 +11844,66 @@ } }, "node_modules/engine.io": { - "version": "6.6.2", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.6.2.tgz", - "integrity": "sha512-gmNvsYi9C8iErnZdVcJnvCpSKbWTt1E8+JZo8b+daLninywUWi5NQ5STSHZ9rFjFO7imNcvb8Pc5pe/wMR5xEw==", + "version": "6.6.9", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.6.9.tgz", + "integrity": "sha512-clKkw4C7nJ22mGgoVcCg6V/W/TxdNyIOTr89k2ONZu81qqkddPFDF0LXcbAwhzPD8DjkiRCjzuiO6Y+fkpD4vg==", "devOptional": true, + "license": "MIT", "dependencies": { - "@types/cookie": "^0.4.1", "@types/cors": "^2.8.12", "@types/node": ">=10.0.0", + "@types/ws": "^8.5.12", "accepts": "~1.3.4", "base64id": "2.0.0", "cookie": "~0.7.2", "cors": "~2.8.5", - "debug": "~4.3.1", + "debug": "~4.4.1", "engine.io-parser": "~5.2.1", - "ws": "~8.17.1" + "ws": "~8.21.0" }, "engines": { "node": ">=10.2.0" } }, "node_modules/engine.io-client": { - "version": "6.6.1", - "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.6.1.tgz", - "integrity": "sha512-aYuoak7I+R83M/BBPIOs2to51BmFIpC1wZe6zZzMrT2llVsHy5cvcmdsJgP2Qz6smHu+sD9oexiSUAVd8OfBPw==", + "version": "6.6.6", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.6.6.tgz", + "integrity": "sha512-iY6QdftLQ9pyiPoX082bpf/u1UewnOaJrtJIF9T0++QB34lZrj0uP+Q/bj8AlUsAxqhnkTV2BS8SBZSxOmoV5Q==", "devOptional": true, + "license": "MIT", "dependencies": { "@socket.io/component-emitter": "~3.1.0", - "debug": "~4.3.1", + "debug": "~4.4.1", "engine.io-parser": "~5.2.1", - "ws": "~8.17.1", + "ws": "~8.21.0", "xmlhttprequest-ssl": "~2.1.1" } }, + "node_modules/engine.io-client/node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/engine.io-client/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "devOptional": true, + "license": "MIT" + }, "node_modules/engine.io-parser": { "version": "5.2.3", "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz", @@ -10692,30 +11913,41 @@ "node": ">=10.0.0" } }, - "node_modules/enhanced-resolve": { - "version": "5.19.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.19.0.tgz", - "integrity": "sha512-phv3E1Xl4tQOShqSte26C7Fl84EwUdZsyOuSSk9qtAGyyQs2s3jJzComh+Abf4g187lUUAvH+H26omrqia2aGg==", + "node_modules/engine.io/node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "devOptional": true, + "license": "MIT", "dependencies": { - "graceful-fs": "^4.2.4", - "tapable": "^2.3.0" + "ms": "^2.1.3" }, "engines": { - "node": ">=10.13.0" + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/enquirer": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", - "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", - "license": "MIT", - "optional": true, + "node_modules/engine.io/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/enhanced-resolve": { + "version": "5.19.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.19.0.tgz", + "integrity": "sha512-phv3E1Xl4tQOShqSte26C7Fl84EwUdZsyOuSSk9qtAGyyQs2s3jJzComh+Abf4g187lUUAvH+H26omrqia2aGg==", "dependencies": { - "ansi-colors": "^4.1.1", - "strip-ansi": "^6.0.1" + "graceful-fs": "^4.2.4", + "tapable": "^2.3.0" }, "engines": { - "node": ">=8.6" + "node": ">=10.13.0" } }, "node_modules/entities": { @@ -10750,11 +11982,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/err-code": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", - "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==" - }, "node_modules/errno": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", @@ -10824,9 +12051,9 @@ } }, "node_modules/esbuild": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.9.tgz", - "integrity": "sha512-CRbODhYyQx3qp7ZEwzxOk4JBqmD/seJrzPa/cGjY1VtIn5E09Oi9/dB4JwctnfZ8Q8iT7rioVv5k/FNT/uf54g==", + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.2.tgz", + "integrity": "sha512-HKVLS8dvII+xoKW9kmqxbRKrnWEXfJJr/FZhhJmiqIB0e053QNYFqOBouTMO/k5sID4MvCiUCvv8b9M4h32wIA==", "hasInstallScript": true, "license": "MIT", "bin": { @@ -10836,38 +12063,38 @@ "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.9", - "@esbuild/android-arm": "0.25.9", - "@esbuild/android-arm64": "0.25.9", - "@esbuild/android-x64": "0.25.9", - "@esbuild/darwin-arm64": "0.25.9", - "@esbuild/darwin-x64": "0.25.9", - "@esbuild/freebsd-arm64": "0.25.9", - "@esbuild/freebsd-x64": "0.25.9", - "@esbuild/linux-arm": "0.25.9", - "@esbuild/linux-arm64": "0.25.9", - "@esbuild/linux-ia32": "0.25.9", - "@esbuild/linux-loong64": "0.25.9", - "@esbuild/linux-mips64el": "0.25.9", - "@esbuild/linux-ppc64": "0.25.9", - "@esbuild/linux-riscv64": "0.25.9", - "@esbuild/linux-s390x": "0.25.9", - "@esbuild/linux-x64": "0.25.9", - "@esbuild/netbsd-arm64": "0.25.9", - "@esbuild/netbsd-x64": "0.25.9", - "@esbuild/openbsd-arm64": "0.25.9", - "@esbuild/openbsd-x64": "0.25.9", - "@esbuild/openharmony-arm64": "0.25.9", - "@esbuild/sunos-x64": "0.25.9", - "@esbuild/win32-arm64": "0.25.9", - "@esbuild/win32-ia32": "0.25.9", - "@esbuild/win32-x64": "0.25.9" + "@esbuild/aix-ppc64": "0.28.2", + "@esbuild/android-arm": "0.28.2", + "@esbuild/android-arm64": "0.28.2", + "@esbuild/android-x64": "0.28.2", + "@esbuild/darwin-arm64": "0.28.2", + "@esbuild/darwin-x64": "0.28.2", + "@esbuild/freebsd-arm64": "0.28.2", + "@esbuild/freebsd-x64": "0.28.2", + "@esbuild/linux-arm": "0.28.2", + "@esbuild/linux-arm64": "0.28.2", + "@esbuild/linux-ia32": "0.28.2", + "@esbuild/linux-loong64": "0.28.2", + "@esbuild/linux-mips64el": "0.28.2", + "@esbuild/linux-ppc64": "0.28.2", + "@esbuild/linux-riscv64": "0.28.2", + "@esbuild/linux-s390x": "0.28.2", + "@esbuild/linux-x64": "0.28.2", + "@esbuild/netbsd-arm64": "0.28.2", + "@esbuild/netbsd-x64": "0.28.2", + "@esbuild/openbsd-arm64": "0.28.2", + "@esbuild/openbsd-x64": "0.28.2", + "@esbuild/openharmony-arm64": "0.28.2", + "@esbuild/sunos-x64": "0.28.2", + "@esbuild/win32-arm64": "0.28.2", + "@esbuild/win32-ia32": "0.28.2", + "@esbuild/win32-x64": "0.28.2" } }, "node_modules/esbuild-wasm": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/esbuild-wasm/-/esbuild-wasm-0.25.9.tgz", - "integrity": "sha512-Jpv5tCSwQg18aCqCRD3oHIX/prBhXMDapIoG//A+6+dV0e7KQMGFg85ihJ5T1EeMjbZjON3TqFy0VrGAnIHLDA==", + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/esbuild-wasm/-/esbuild-wasm-0.28.1.tgz", + "integrity": "sha512-p/GD4E8oYRjg3kjdKrnMb0s4PzXgJF42e0MF4H0+ACyK/kIlFRp3e0fzOleIG+wBBm6MM3XQrbpe7soEA+vJIA==", "license": "MIT", "bin": { "esbuild": "bin/esbuild" @@ -10891,34 +12118,39 @@ "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" }, "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "optional": true, + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", "engines": { - "node": ">=0.8.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/eslint": { - "version": "9.39.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.0.tgz", - "integrity": "sha512-iy2GE3MHrYTL5lrCtMZ0X1KLEKKUjmK0kzwcnefhR66txcEmXZD2YWgR5GNdcEwkNx3a0siYkSvl0vIC+Svjmg==", + "version": "9.39.5", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.5.tgz", + "integrity": "sha512-DgZS62aPLXKlnxILS/AYCoRvHaZeXceIzlXPkkGGzJWSow1aEk0lbTlxUSlyjC8jcaKxAdOnTDz+o1JFSBsyjw==", + "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", - "@eslint/config-array": "^0.21.1", + "@eslint/config-array": "^0.21.2", "@eslint/config-helpers": "^0.4.2", "@eslint/core": "^0.17.0", - "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "9.39.0", + "@eslint/eslintrc": "^3.3.6", + "@eslint/js": "9.39.5", "@eslint/plugin-kit": "^0.4.1", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", - "ajv": "^6.12.4", + "ajv": "^6.14.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", @@ -10937,7 +12169,7 @@ "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", + "minimatch": "^3.1.5", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, @@ -10984,17 +12216,21 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint/node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "node_modules/eslint/node_modules/ajv": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", "dev": true, "license": "MIT", - "engines": { - "node": ">=10" + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, "node_modules/eslint/node_modules/eslint-scope": { @@ -11077,6 +12313,13 @@ "node": ">= 4" } }, + "node_modules/eslint/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, "node_modules/eslint/node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -11141,9 +12384,9 @@ } }, "node_modules/esquery": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", - "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", + "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -11272,9 +12515,9 @@ } }, "node_modules/eventsource-parser": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.6.tgz", - "integrity": "sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.1.1.tgz", + "integrity": "sha512-EKN1vKAMcZ8MlYMpaNuxN6R9yakzH6uajHcHVTqWJzvu5pWw9DyhbP35HH8MVBQ+dZjAfDxk+A8NiR9KWaXiyQ==", "license": "MIT", "engines": { "node": ">=18.0.0" @@ -11337,7 +12580,8 @@ "node_modules/exponential-backoff": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.3.tgz", - "integrity": "sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA==" + "integrity": "sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA==", + "license": "Apache-2.0" }, "node_modules/express": { "version": "5.2.1", @@ -11383,12 +12627,13 @@ } }, "node_modules/express-rate-limit": { - "version": "8.3.1", - "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.3.1.tgz", - "integrity": "sha512-D1dKN+cmyPWuvB+G2SREQDzPY1agpBIcTa9sJxOPMCNeH3gwzhqJRDWCXW3gg0y//+LQ/8j52JbMROWyrKdMdw==", + "version": "8.6.2", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.6.2.tgz", + "integrity": "sha512-YH4ru+eOJxQABscKFfRCy9R7x9QFGdezclVMwwgFFndzS2Xnm0uo6B0ABZsLhcpeptGv2qvuJVWlQr9gQZoC3A==", "license": "MIT", "dependencies": { - "ip-address": "10.1.0" + "debug": "^4.4.3", + "ip-address": "^10.2.0" }, "engines": { "node": ">= 16" @@ -11400,6 +12645,29 @@ "express": ">= 4.11" } }, + "node_modules/express-rate-limit/node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/express-rate-limit/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, "node_modules/express/node_modules/accepts": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", @@ -11413,30 +12681,6 @@ "node": ">= 0.6" } }, - "node_modules/express/node_modules/body-parser": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.2.tgz", - "integrity": "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==", - "license": "MIT", - "dependencies": { - "bytes": "^3.1.2", - "content-type": "^1.0.5", - "debug": "^4.4.3", - "http-errors": "^2.0.0", - "iconv-lite": "^0.7.0", - "on-finished": "^2.4.1", - "qs": "^6.14.1", - "raw-body": "^3.0.1", - "type-is": "^2.0.1" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, "node_modules/express/node_modules/debug": { "version": "4.4.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", @@ -11492,31 +12736,6 @@ "url": "https://opencollective.com/express" } }, - "node_modules/express/node_modules/iconv-lite": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz", - "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==", - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/express/node_modules/media-typer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", - "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, "node_modules/express/node_modules/mime-db": { "version": "1.54.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", @@ -11549,12 +12768,32 @@ "license": "MIT" }, "node_modules/express/node_modules/negotiator": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", - "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.1.0.tgz", + "integrity": "sha512-NMPBRMJgiQHjbd8phG3Vebdx4kZ1H121rbl5IkMqeOsahptB9BKo/d7oJ3zTXqTgagn2bWlNSXkh0QUGM31RYg==", "license": "MIT", + "dependencies": { + "content-type": "^2.1.0" + }, "engines": { - "node": ">= 0.6" + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/express/node_modules/negotiator/node_modules/content-type": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-2.1.0.tgz", + "integrity": "sha512-mj7UPXE0jaqaOsukNZRUEfEi2AcL7C/vwmwcHV0O97eO1E1pxBZuyjlZrx5seTaNBg1U6+o35wpa35Qfcc+7ag==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/express/node_modules/on-finished": { @@ -11569,21 +12808,6 @@ "node": ">= 0.8" } }, - "node_modules/express/node_modules/raw-body": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz", - "integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==", - "license": "MIT", - "dependencies": { - "bytes": "~3.1.2", - "http-errors": "~2.0.1", - "iconv-lite": "~0.7.0", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.10" - } - }, "node_modules/express/node_modules/send": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz", @@ -11638,61 +12862,13 @@ "node": ">= 0.8" } }, - "node_modules/express/node_modules/type-is": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", - "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", - "license": "MIT", - "dependencies": { - "content-type": "^1.0.5", - "media-typer": "^1.1.0", - "mime-types": "^3.0.0" - }, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "license": "MIT", "optional": true }, - "node_modules/extract-zip": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", - "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", - "optional": true, - "dependencies": { - "debug": "^4.1.1", - "get-stream": "^5.1.0", - "yauzl": "^2.10.0" - }, - "bin": { - "extract-zip": "cli.js" - }, - "engines": { - "node": ">= 10.17.0" - }, - "optionalDependencies": { - "@types/yauzl": "^2.9.1" - } - }, - "node_modules/extract-zip/node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "optional": true, - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", @@ -11728,7 +12904,8 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fast-levenshtein": { "version": "2.0.6", @@ -11738,9 +12915,9 @@ "license": "MIT" }, "node_modules/fast-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", - "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.6.tgz", + "integrity": "sha512-7Ical1vFEMr0onbVzEDIreM22I4khW+fzyQPwvAFWBp1iwdshSZRsL4jjRvPG9JP1uiqMHRto+YU6R2/CzDz5Q==", "funding": [ { "type": "github", @@ -11773,30 +12950,6 @@ "node": ">=0.8.0" } }, - "node_modules/fd-slicer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", - "optional": true, - "dependencies": { - "pend": "~1.2.0" - } - }, - "node_modules/figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", - "optional": true, - "dependencies": { - "escape-string-regexp": "^1.0.5" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/file-entry-cache": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", @@ -11931,22 +13084,23 @@ } }, "node_modules/flatted": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", - "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.4.tgz", + "integrity": "sha512-5+ybhBZANEJxaH3X5evAFatUxLfEHSr7n6kYJ+1Qd0mUqr4eu9gIf6GDbWHf8RJijHrjjO8G+la14SlL2SeS1Q==", "dev": true, "license": "ISC" }, "node_modules/follow-redirects": { - "version": "1.15.11", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", - "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.0.tgz", + "integrity": "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==", "funding": [ { "type": "individual", "url": "https://github.com/sponsors/RubenVerborgh" } ], + "license": "MIT", "engines": { "node": ">=4.0" }, @@ -11967,16 +13121,17 @@ } }, "node_modules/form-data": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", - "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.6.tgz", + "integrity": "sha512-vKatAh4SlVfgbv+YtmhiRjhEMJsYpsG1Y2rMQtR+SVSbytsSD1YGzDIcrAJmdFec88u/+VoGmxnl+80gL1tRCQ==", + "license": "MIT", "optional": true, "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", - "hasown": "^2.0.2", - "mime-types": "^2.1.12" + "hasown": "^2.0.4", + "mime-types": "^2.1.35" }, "engines": { "node": ">= 6" @@ -12022,6 +13177,7 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz", "integrity": "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==", + "license": "ISC", "dependencies": { "minipass": "^7.0.3" }, @@ -12034,6 +13190,7 @@ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "hasInstallScript": true, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -12067,9 +13224,9 @@ } }, "node_modules/get-east-asian-width": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.4.0.tgz", - "integrity": "sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.6.0.tgz", + "integrity": "sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==", "license": "MIT", "engines": { "node": ">=18" @@ -12145,16 +13302,17 @@ } }, "node_modules/glob": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.0.tgz", - "integrity": "sha512-tvZgpqk6fz4BaNZ66ZsRaZnbHvP/jG3uKJvAZOwEVUL4RTA5nJeeLYfyN9/VA8NX/V3IBG+hkeuGpKjvELkVhA==", + "version": "13.0.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz", + "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==", + "license": "BlueOak-1.0.0", "dependencies": { - "minimatch": "^10.1.1", - "minipass": "^7.1.2", - "path-scurry": "^2.0.0" + "minimatch": "^10.2.2", + "minipass": "^7.1.3", + "path-scurry": "^2.0.2" }, "engines": { - "node": "20 || >=22" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -12202,24 +13360,24 @@ } }, "node_modules/glob/node_modules/brace-expansion": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", - "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", + "version": "5.0.9", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.9.tgz", + "integrity": "sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==", "license": "MIT", "dependencies": { "balanced-match": "^4.0.2" }, "engines": { - "node": "18 || 20 || >=22" + "node": "20 || >=22" } }, "node_modules/glob/node_modules/minimatch": { - "version": "10.2.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", - "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", + "version": "10.2.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.6.tgz", + "integrity": "sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==", "license": "BlueOak-1.0.0", "dependencies": { - "brace-expansion": "^5.0.2" + "brace-expansion": "^5.0.8" }, "engines": { "node": "18 || 20 || >=22" @@ -12290,13 +13448,6 @@ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "license": "ISC" }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true, - "license": "MIT" - }, "node_modules/handle-thing": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", @@ -12366,9 +13517,10 @@ } }, "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", + "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==", + "license": "MIT", "dependencies": { "function-bind": "^1.1.2" }, @@ -12377,18 +13529,18 @@ } }, "node_modules/hono": { - "version": "4.12.8", - "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.8.tgz", - "integrity": "sha512-VJCEvtrezO1IAR+kqEYnxUOoStaQPGrCmX3j4wDTNOcD1uRPFpGlwQUIW8niPuvHXaTUxeOUl5MMDGrl+tmO9A==", + "version": "4.13.5", + "resolved": "https://registry.npmjs.org/hono/-/hono-4.13.5.tgz", + "integrity": "sha512-O6+/eCYRkzzzy0rPWwKLiGBR1nFuUPZynnwjxN1MBA62NNqbT0wQEzQyK2gSO5yDIDB336sXQleAhOHrzlYyKw==", "license": "MIT", "engines": { "node": ">=16.9.0" } }, "node_modules/hosted-git-info": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-9.0.2.tgz", - "integrity": "sha512-M422h7o/BR3rmCQ8UHi7cyyMqKltdP9Uo+J2fXK+RSAY+wTcKOIRyhTuKv4qn+DJf3g+PL890AzId5KZpX+CBg==", + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-9.0.3.tgz", + "integrity": "sha512-Hc+ghLoSt6QaYZUv0WBiIvmMDZuZZ7oaDvdH8MbfOO4lOsxdXLEvuC6ePoGs9H1X9oCLyq6+NVN0MKqD+ydxyg==", "license": "ISC", "dependencies": { "lru-cache": "^11.1.0" @@ -12486,7 +13638,8 @@ "node_modules/http-cache-semantics": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", - "integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==" + "integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==", + "license": "BSD-2-Clause" }, "node_modules/http-deceiver": { "version": "1.2.7", @@ -12540,6 +13693,7 @@ "version": "7.0.2", "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "license": "MIT", "dependencies": { "agent-base": "^7.1.0", "debug": "^4.3.4" @@ -12549,9 +13703,9 @@ } }, "node_modules/http-proxy-middleware": { - "version": "2.0.9", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.9.tgz", - "integrity": "sha512-c1IyJYLYppU574+YI7R4QyX2ystMtVXZwIdzazUIPIJsHuWNd+mho2j+bKoHftndicGj9yh+xjd+l0yj7VeT1Q==", + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.10.tgz", + "integrity": "sha512-RKzRWNPxUZqbuk3BC5mGVJbBnWgr+diEnjJexIOytFbBzDy88Fbh/YvBr3DsNrl1jYAfjWfpATEv0NO35FDuPQ==", "license": "MIT", "dependencies": { "@types/http-proxy": "^1.17.8", @@ -12662,9 +13816,9 @@ "optional": true }, "node_modules/ignore": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", - "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.6.tgz", + "integrity": "sha512-BAg6QkE8W+TuQLrrw0Ugr7HegXduRuuj8/ti2kSOc+jz1dmx8/WNcjr6XGnq5YpDWxFwwaavqD0+jIUOKelTsw==", "dev": true, "license": "MIT", "engines": { @@ -12675,6 +13829,7 @@ "version": "8.0.0", "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-8.0.0.tgz", "integrity": "sha512-FCeMZT4NiRQGh+YkeKMtWrOmBgWjHjMJ26WQWrRQyoyzqevdaGSakUaJW5xQYmjLlUVk2qUnCjYVBax9EKKg8A==", + "license": "ISC", "dependencies": { "minimatch": "^10.0.3" }, @@ -12692,24 +13847,24 @@ } }, "node_modules/ignore-walk/node_modules/brace-expansion": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", - "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", + "version": "5.0.9", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.9.tgz", + "integrity": "sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==", "license": "MIT", "dependencies": { "balanced-match": "^4.0.2" }, "engines": { - "node": "18 || 20 || >=22" + "node": "20 || >=22" } }, "node_modules/ignore-walk/node_modules/minimatch": { - "version": "10.2.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", - "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", + "version": "10.2.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.6.tgz", + "integrity": "sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==", "license": "BlueOak-1.0.0", "dependencies": { - "brace-expansion": "^5.0.2" + "brace-expansion": "^5.0.8" }, "engines": { "node": "18 || 20 || >=22" @@ -12732,9 +13887,9 @@ } }, "node_modules/immutable": { - "version": "3.8.3", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.8.3.tgz", - "integrity": "sha512-AUY/VyX0E5XlibOmWt10uabJzam1zlYjwiEgQSDc5+UIkFNaF9WM0JxXKaNMGf+F/ffUF+7kRKXM9A7C0xXqMg==", + "version": "3.8.4", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.8.4.tgz", + "integrity": "sha512-ZQv17KolYrYmsDoDB8N67zhIKsNi9mGYlk96y/yuxyAqJB2hLzSGSM7k/sB0/ZvO4kx27U9+fBeD/XlLGh/uXQ==", "devOptional": true, "license": "MIT", "engines": { @@ -12767,20 +13922,13 @@ "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", "engines": { "node": ">=0.8.19" } }, - "node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "optional": true, - "engines": { - "node": ">=8" - } - }, "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", @@ -12795,9 +13943,10 @@ } }, "node_modules/ip-address": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.1.0.tgz", - "integrity": "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.5.0.tgz", + "integrity": "sha512-R5SnVLJmgYYvf2F2ZgwSBnelz5G4q5AxIC277GDfUaNbrZKNANcBC7RHqYYePlszf4kBolVkJauG0ZjHHFh55g==", + "license": "MIT", "engines": { "node": ">= 12" } @@ -12931,9 +14080,9 @@ } }, "node_modules/is-network-error": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/is-network-error/-/is-network-error-1.3.1.tgz", - "integrity": "sha512-6QCxa49rQbmUWLfk0nuGqzql9U8uaV2H6279bRErPBHe/109hCzsLUBUHfbEtvLIHBd6hyXbgedBSHevm43Edw==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/is-network-error/-/is-network-error-1.3.2.tgz", + "integrity": "sha512-PhBY86zaxNZUuWP6h13Vu5oFe0XY6/UlKzQnYFELzGVHygP3MxmvTfYSG7GN3aIab/iWudSMgjSnG9Dq+nHrgA==", "license": "MIT", "engines": { "node": ">=16" @@ -13144,9 +14293,9 @@ } }, "node_modules/joi": { - "version": "18.0.1", - "resolved": "https://registry.npmjs.org/joi/-/joi-18.0.1.tgz", - "integrity": "sha512-IiQpRyypSnLisQf3PwuN2eIHAsAIGZIrLZkd4zdvIar2bDyhM91ubRjy8a3eYablXsh9BeI/c7dmPYHca5qtoA==", + "version": "18.2.5", + "resolved": "https://registry.npmjs.org/joi/-/joi-18.2.5.tgz", + "integrity": "sha512-+gEA7rLfaNWx9JzawWPrPetSZwT16NUqHtECDgjyAJreXcs4TM7tx2Pa+VVJJK0YHM83ybrVdaT6UekHH50FJQ==", "license": "BSD-3-Clause", "optional": true, "dependencies": { @@ -13156,16 +14305,16 @@ "@hapi/pinpoint": "^2.0.1", "@hapi/tlds": "^1.1.1", "@hapi/topo": "^6.0.2", - "@standard-schema/spec": "^1.0.0" + "@standard-schema/spec": "^1.1.0" }, "engines": { "node": ">= 20" } }, "node_modules/jose": { - "version": "6.1.3", - "resolved": "https://registry.npmjs.org/jose/-/jose-6.1.3.tgz", - "integrity": "sha512-0TpaTfihd4QMNwrz/ob2Bp7X04yuxJkjRGi4aKmOqwhov54i6u79oCv7T+C7lo70MKH6BesI3vscD1yb/yzKXQ==", + "version": "6.2.10", + "resolved": "https://registry.npmjs.org/jose/-/jose-6.2.10.tgz", + "integrity": "sha512-iiW7J9qRFlGxvCOIBDBDxFePQSn7ZMAnrYGhrrOo6siO/MIqwfyilLR27pkfDgUk+raLuzADS8A3S/KLBisc0g==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/panva" @@ -13184,9 +14333,19 @@ "license": "MIT" }, "node_modules/js-yaml": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", - "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.2.tgz", + "integrity": "sha512-SFNOvSJ+Dgf/9An904Yx+CgSlIPCkIpao4qo51lpee25TIRejdH3rhR4EZMGoNx3/TP3O+wzWuiTFl4sqbltzA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/puzrin" + }, + { + "type": "github", + "url": "https://github.com/sponsors/nodeca" + } + ], "license": "MIT", "dependencies": { "argparse": "^2.0.1" @@ -13308,10 +14467,10 @@ "optional": true }, "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT" }, "node_modules/json-schema-typed": { "version": "8.0.2", @@ -13368,7 +14527,8 @@ "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", "engines": [ "node >= 0.2.0" - ] + ], + "license": "MIT" }, "node_modules/jsprim": { "version": "2.0.2", @@ -13420,13 +14580,13 @@ } }, "node_modules/launch-editor": { - "version": "2.13.2", - "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.13.2.tgz", - "integrity": "sha512-4VVDnbOpLXy/s8rdRCSXb+zfMeFR0WlJWpET1iA9CQdlZDfwyLjUuGQzXU4VeOoey6AicSAluWan7Etga6Kcmg==", + "version": "2.14.1", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.14.1.tgz", + "integrity": "sha512-QWBrQsMpH7gPr965dsKD/3cKWiNoTjpATQf++Xq63N6sKRGMwlVXz41O1IZTMfZQgBctD/K5Zt06+/I6pP6+HA==", "license": "MIT", "dependencies": { "picocolors": "^1.1.1", - "shell-quote": "^1.8.3" + "shell-quote": "^1.8.4" } }, "node_modules/lazy-ass": { @@ -13545,44 +14705,110 @@ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" }, "node_modules/listr2": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.14.0.tgz", - "integrity": "sha512-TyWI8G99GX9GjE54cJ+RrNMcIFBfwMPxc3XTFiAYGN4s10hWROGtOg7+O6u6LE3mNkyld7RSLE6nrKBvTfcs3g==", - "optional": true, - "dependencies": { - "cli-truncate": "^2.1.0", - "colorette": "^2.0.16", - "log-update": "^4.0.0", - "p-map": "^4.0.0", - "rfdc": "^1.3.0", - "rxjs": "^7.5.1", - "through": "^2.3.8", - "wrap-ansi": "^7.0.0" + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-9.0.5.tgz", + "integrity": "sha512-ME4Fb83LgEgwNw96RKNvKV4VTLuXfoKudAmm2lP8Kk87KaMK0/Xrx/aAkMWmT8mDb+3MlFDspfbCs7adjRxA2g==", + "license": "MIT", + "optional": true, + "dependencies": { + "cli-truncate": "^5.0.0", + "colorette": "^2.0.20", + "eventemitter3": "^5.0.1", + "log-update": "^6.1.0", + "rfdc": "^1.4.1", + "wrap-ansi": "^9.0.0" }, "engines": { - "node": ">=10.0.0" + "node": ">=20.0.0" + } + }, + "node_modules/listr2/node_modules/ansi-regex": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.3.0.tgz", + "integrity": "sha512-WpDfL7NO6j7tH88IDBNVdUJxDh9nmCteAVW9dsep846XdwF4naCBK+/tGLX3KJgcpgMRXCFlTM2hKGoK9FsdrQ==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=12" }, - "peerDependencies": { - "enquirer": ">= 2.3.0 < 3" + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/listr2/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=12" }, - "peerDependenciesMeta": { - "enquirer": { - "optional": true - } + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/listr2/node_modules/emoji-regex": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "license": "MIT", + "optional": true + }, + "node_modules/listr2/node_modules/eventemitter3": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz", + "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==", + "license": "MIT", + "optional": true + }, + "node_modules/listr2/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/listr2/node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "license": "MIT", + "optional": true, + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, "node_modules/listr2/node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", + "license": "MIT", "optional": true, "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" }, "engines": { - "node": ">=10" + "node": ">=18" }, "funding": { "url": "https://github.com/chalk/wrap-ansi?sponsor=1" @@ -13652,10 +14878,11 @@ } }, "node_modules/lodash": { - "version": "4.17.23", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz", - "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==", - "devOptional": true + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", + "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", + "devOptional": true, + "license": "MIT" }, "node_modules/lodash.debounce": { "version": "4.0.8", @@ -13705,40 +14932,134 @@ } }, "node_modules/log-update": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", - "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", - "optional": true, + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.1.0.tgz", + "integrity": "sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==", + "license": "MIT", "dependencies": { - "ansi-escapes": "^4.3.0", - "cli-cursor": "^3.1.0", - "slice-ansi": "^4.0.0", - "wrap-ansi": "^6.2.0" + "ansi-escapes": "^7.0.0", + "cli-cursor": "^5.0.0", + "slice-ansi": "^7.1.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" }, "engines": { - "node": ">=10" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/ansi-regex": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.3.0.tgz", + "integrity": "sha512-WpDfL7NO6j7tH88IDBNVdUJxDh9nmCteAVW9dsep846XdwF4naCBK+/tGLX3KJgcpgMRXCFlTM2hKGoK9FsdrQ==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/log-update/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/log-update/node_modules/emoji-regex": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "license": "MIT" + }, + "node_modules/log-update/node_modules/is-fullwidth-code-point": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.1.0.tgz", + "integrity": "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==", + "license": "MIT", + "dependencies": { + "get-east-asian-width": "^1.3.1" + }, + "engines": { + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/log-update/node_modules/slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", - "optional": true, + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.2.tgz", + "integrity": "sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w==", + "license": "MIT", "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" + "ansi-styles": "^6.2.1", + "is-fullwidth-code-point": "^5.0.0" }, "engines": { - "node": ">=10" + "node": ">=18" }, "funding": { "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, + "node_modules/log-update/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/log-update/node_modules/wrap-ansi": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/loupe": { "version": "2.3.7", "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", @@ -13804,14 +15125,18 @@ "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/make-fetch-happen": { - "version": "15.0.3", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-15.0.3.tgz", - "integrity": "sha512-iyyEpDty1mwW3dGlYXAJqC/azFn5PPvgKVwXayOGBSmKLxhKZ9fg4qIan2ePpp1vJIwfFiO34LAPZgq9SZW9Aw==", + "version": "15.0.6", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-15.0.6.tgz", + "integrity": "sha512-Je0fLJ0F5atA7F+eIlLzk+Wkcl57JDf4kf+EW8xiP5E31xOQxkIxTbgf1Oi1Lw9tRI9UEMRdI5Vz2xTzoNU1Jw==", + "license": "ISC", "dependencies": { + "@gar/promise-retry": "^1.0.0", "@npmcli/agent": "^4.0.0", + "@npmcli/redact": "^4.0.0", "cacache": "^20.0.1", "http-cache-semantics": "^4.1.1", "minipass": "^7.0.2", @@ -13820,25 +15145,46 @@ "minipass-pipeline": "^1.2.4", "negotiator": "^1.0.0", "proc-log": "^6.0.0", - "promise-retry": "^2.0.1", "ssri": "^13.0.0" }, "engines": { "node": "^20.17.0 || >=22.9.0" } }, + "node_modules/make-fetch-happen/node_modules/content-type": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-2.1.0.tgz", + "integrity": "sha512-mj7UPXE0jaqaOsukNZRUEfEi2AcL7C/vwmwcHV0O97eO1E1pxBZuyjlZrx5seTaNBg1U6+o35wpa35Qfcc+7ag==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, "node_modules/make-fetch-happen/node_modules/negotiator": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", - "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.1.0.tgz", + "integrity": "sha512-NMPBRMJgiQHjbd8phG3Vebdx4kZ1H121rbl5IkMqeOsahptB9BKo/d7oJ3zTXqTgagn2bWlNSXkh0QUGM31RYg==", + "license": "MIT", + "dependencies": { + "content-type": "^2.1.0" + }, "engines": { - "node": ">= 0.6" + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/make-fetch-happen/node_modules/proc-log": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-6.1.0.tgz", "integrity": "sha512-iG+GYldRf2BQ0UDUAd6JQ/RwzaQy6mXmsk/IzlYyal4A4SNFw54MeH4/tLkF4I5WoWG9SQwuqWzS99jaFQHBuQ==", + "license": "ISC", "engines": { "node": "^20.17.0 || >=22.9.0" } @@ -13865,28 +15211,32 @@ "license": "CC0-1.0" }, "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.1.tgz", + "integrity": "sha512-yz3xRaG20c6/BOzvYoDaGtPmGscs7YivItZEEqe6GbwNfHuxu9YNmvnEkMzKldAGY4/80pRcQRZSEnhquk9XuQ==", "license": "MIT", "engines": { - "node": ">= 0.6" - } + "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } }, "node_modules/memfs": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.57.1.tgz", - "integrity": "sha512-WvzrWPwMQT+PtbX2Et64R4qXKK0fj/8pO85MrUCzymX3twwCiJCdvntW3HdhG1teLJcHDDLIKx5+c3HckWYZtQ==", + "version": "4.68.1", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.68.1.tgz", + "integrity": "sha512-OD+IDRUvIxu3QHL+nFm9gdyugInD27FDJ+sl4B5QgomPHXMlbw+GP918P8VNKu2FkNlVeqBkpzkwROpamVifRw==", "license": "Apache-2.0", "dependencies": { - "@jsonjoy.com/fs-core": "4.57.1", - "@jsonjoy.com/fs-fsa": "4.57.1", - "@jsonjoy.com/fs-node": "4.57.1", - "@jsonjoy.com/fs-node-builtins": "4.57.1", - "@jsonjoy.com/fs-node-to-fsa": "4.57.1", - "@jsonjoy.com/fs-node-utils": "4.57.1", - "@jsonjoy.com/fs-print": "4.57.1", - "@jsonjoy.com/fs-snapshot": "4.57.1", + "@jsonjoy.com/fs-core": "4.68.1", + "@jsonjoy.com/fs-fsa": "4.68.1", + "@jsonjoy.com/fs-node": "4.68.1", + "@jsonjoy.com/fs-node-builtins": "4.68.1", + "@jsonjoy.com/fs-node-to-fsa": "4.68.1", + "@jsonjoy.com/fs-node-utils": "4.68.1", + "@jsonjoy.com/fs-print": "4.68.1", + "@jsonjoy.com/fs-snapshot": "4.68.1", "@jsonjoy.com/json-pack": "^1.11.0", "@jsonjoy.com/util": "^1.9.0", "glob-to-regex.js": "^1.0.1", @@ -13897,9 +15247,6 @@ "funding": { "type": "github", "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" } }, "node_modules/merge-descriptors": { @@ -14037,9 +15384,10 @@ } }, "node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", + "license": "BlueOak-1.0.0", "engines": { "node": ">=16 || 14 >=14.17" } @@ -14048,6 +15396,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-2.0.1.tgz", "integrity": "sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==", + "license": "ISC", "dependencies": { "minipass": "^7.0.3" }, @@ -14056,25 +15405,44 @@ } }, "node_modules/minipass-fetch": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-5.0.0.tgz", - "integrity": "sha512-fiCdUALipqgPWrOVTz9fw0XhcazULXOSU6ie40DDbX1F49p1dBrSRBuswndTx1x3vEb/g0FT7vC4c4C2u/mh3A==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-5.0.2.tgz", + "integrity": "sha512-2d0q2a8eCi2IRg/IGubCNRJoYbA1+YPXAzQVRFmB45gdGZafyivnZ5YSEfo3JikbjGxOdntGFvBQGqaSMXlAFQ==", + "license": "MIT", "dependencies": { "minipass": "^7.0.3", - "minipass-sized": "^1.0.3", + "minipass-sized": "^2.0.0", "minizlib": "^3.0.1" }, "engines": { "node": "^20.17.0 || >=22.9.0" }, "optionalDependencies": { - "encoding": "^0.1.13" + "iconv-lite": "^0.7.2" + } + }, + "node_modules/minipass-fetch/node_modules/iconv-lite": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.3.tgz", + "integrity": "sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/minipass-flush": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", - "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.7.tgz", + "integrity": "sha512-TbqTz9cUwWyHS2Dy89P3ocAGUGxKjjLuR9z8w4WUTGAVgEj17/4nhgo2Du56i0Fm3Pm30g4iA8Lcqctc76jCzA==", + "license": "BlueOak-1.0.0", "dependencies": { "minipass": "^3.0.0" }, @@ -14086,6 +15454,7 @@ "version": "3.3.6", "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "license": "ISC", "dependencies": { "yallist": "^4.0.0" }, @@ -14096,12 +15465,14 @@ "node_modules/minipass-flush/node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "license": "ISC" }, "node_modules/minipass-pipeline": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", + "license": "ISC", "dependencies": { "minipass": "^3.0.0" }, @@ -14113,6 +15484,7 @@ "version": "3.3.6", "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "license": "ISC", "dependencies": { "yallist": "^4.0.0" }, @@ -14123,39 +15495,26 @@ "node_modules/minipass-pipeline/node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "license": "ISC" }, "node_modules/minipass-sized": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", - "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minipass-sized/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-2.0.0.tgz", + "integrity": "sha512-zSsHhto5BcUVM2m1LurnXY6M//cGhVaegT71OfOXoprxT6o780GZd792ea6FfrQkuU4usHZIUczAQMRUE2plzA==", + "license": "ISC", "dependencies": { - "yallist": "^4.0.0" + "minipass": "^7.1.2" }, "engines": { "node": ">=8" } }, - "node_modules/minipass-sized/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, "node_modules/minizlib": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz", "integrity": "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==", + "license": "MIT", "dependencies": { "minipass": "^7.1.2" }, @@ -14167,7 +15526,8 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/mitt/-/mitt-1.2.0.tgz", "integrity": "sha512-r6lj77KlwqLhIUku9UWYes7KJtsczvolZkzp8hbaDPPaE24OmWl5s539Mytlj22siEQKosZ26qCBgda2PKwoJw==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, "node_modules/mock-socket": { "version": "9.3.1", @@ -14193,9 +15553,9 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/msgpackr": { - "version": "1.11.9", - "resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.11.9.tgz", - "integrity": "sha512-FkoAAyyA6HM8wL882EcEyFZ9s7hVADSwG9xrVx3dxxNQAtgADTrJoEWivID82Iv1zWDsv/OtbrrcZAzGzOMdNw==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.12.1.tgz", + "integrity": "sha512-4EUH9tQHnMmEgzW/MdAP0KIfa1T9AF+htl0ffe2n5vb2EKn9y2co8ccpgWko6S52Jy1PQZKwRnx5/KkYjtd9MQ==", "license": "MIT", "optional": true, "optionalDependencies": { @@ -14203,9 +15563,9 @@ } }, "node_modules/msgpackr-extract": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/msgpackr-extract/-/msgpackr-extract-3.0.3.tgz", - "integrity": "sha512-P0efT1C9jIdVRefqjzOQ9Xml57zpOXnIuS+csaB4MdZbTdmGDLo8XhzBG1N7aO11gKDDkJvBLULeFTo46wwreA==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/msgpackr-extract/-/msgpackr-extract-3.0.4.tgz", + "integrity": "sha512-4kmO/MdyUIkLIvTPr8VHLil4AtoKIoniWPIEk5+CDy0xnWC84azhSFmuJ7PxZdsYtiP5kEeQsORAVIeMgxT+Hw==", "hasInstallScript": true, "license": "MIT", "optional": true, @@ -14216,12 +15576,12 @@ "download-msgpackr-prebuilds": "bin/download-prebuilds.js" }, "optionalDependencies": { - "@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.3", - "@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.3", - "@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.3", - "@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.3", - "@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.3", - "@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.3" + "@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.4", + "@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.4", + "@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.4", + "@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.4", + "@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.4", + "@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.4" } }, "node_modules/multicast-dns": { @@ -14247,9 +15607,9 @@ } }, "node_modules/nanoid": { - "version": "3.3.11", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", - "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "version": "3.3.18", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.18.tgz", + "integrity": "sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w==", "funding": [ { "type": "github", @@ -14402,29 +15762,21 @@ "license": "MIT", "optional": true }, - "node_modules/node-forge": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.4.0.tgz", - "integrity": "sha512-LarFH0+6VfriEhqMMcLX2F7SwSXeWwnEAJEsYm5QKWchiVYVvJyV9v7UDvUv+w5HO23ZpQTXDv/GxdDdMyOuoQ==", - "license": "(BSD-3-Clause OR GPL-2.0)", - "engines": { - "node": ">= 6.13.0" - } - }, "node_modules/node-gyp": { - "version": "12.2.0", - "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-12.2.0.tgz", - "integrity": "sha512-q23WdzrQv48KozXlr0U1v9dwO/k59NHeSzn6loGcasyf0UnSrtzs8kRxM+mfwJSf0DkX0s43hcqgnSO4/VNthQ==", + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-12.4.0.tgz", + "integrity": "sha512-OMcPNvqTCFUnNaBlmdgq+lfNqY7gTiSmNRDjY3uAXRyudeKZEZxu3CLtjMQrx4zZxCX2b/mpNqTtwuCJgXhHkw==", + "license": "MIT", "dependencies": { "env-paths": "^2.2.0", "exponential-backoff": "^3.1.1", "graceful-fs": "^4.2.6", - "make-fetch-happen": "^15.0.0", "nopt": "^9.0.0", "proc-log": "^6.0.0", "semver": "^7.3.5", "tar": "^7.5.4", "tinyglobby": "^0.2.12", + "undici": "^6.25.0", "which": "^6.0.0" }, "bin": { @@ -14450,27 +15802,39 @@ } }, "node_modules/node-gyp/node_modules/isexe": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", - "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-4.0.0.tgz", + "integrity": "sha512-FFUtZMpoZ8RqHS3XeXEmHWLA4thH+ZxCv2lOiPIn1Xc7CxrqhWzNSDzD+/chS/zbYezmiwWLdQC09JdQKmthOw==", + "license": "BlueOak-1.0.0", "engines": { - "node": ">=16" + "node": ">=20" } }, "node_modules/node-gyp/node_modules/proc-log": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-6.1.0.tgz", "integrity": "sha512-iG+GYldRf2BQ0UDUAd6JQ/RwzaQy6mXmsk/IzlYyal4A4SNFw54MeH4/tLkF4I5WoWG9SQwuqWzS99jaFQHBuQ==", + "license": "ISC", "engines": { "node": "^20.17.0 || >=22.9.0" } }, + "node_modules/node-gyp/node_modules/undici": { + "version": "6.28.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.28.0.tgz", + "integrity": "sha512-LIY910g9TI13YS95lrMFrs8Rm/u/irgHeTWoKCoteeJ04CUJ92eEfj0rVn+7VKMPBpUPiUoBKfhNyLI23EE/KA==", + "license": "MIT", + "engines": { + "node": ">=18.17" + } + }, "node_modules/node-gyp/node_modules/which": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/which/-/which-6.0.0.tgz", - "integrity": "sha512-f+gEpIKMR9faW/JgAgPK1D7mekkFoqbmiwvNzuhsHetni20QSgzg9Vhn0g2JSJkkfehQnqdUAx7/e15qS1lPxg==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/which/-/which-6.0.1.tgz", + "integrity": "sha512-oGLe46MIrCRqX7ytPUf66EAYvdeMIZYn3WaocqqKZAxrBpkqHfL/qvTyJ/bTk5+AqHCjXmrv3CEWgy368zhRUg==", + "license": "ISC", "dependencies": { - "isexe": "^3.1.1" + "isexe": "^4.0.0" }, "bin": { "node-which": "bin/which.js" @@ -14489,6 +15853,7 @@ "version": "9.0.0", "resolved": "https://registry.npmjs.org/nopt/-/nopt-9.0.0.tgz", "integrity": "sha512-Zhq3a+yFKrYwSBluL4H9XP3m3y5uvQkB/09CwDruCiRmR/UJYnn9W4R48ry0uGC70aeTPKLynBtscP9efFFcPw==", + "license": "ISC", "dependencies": { "abbrev": "^4.0.0" }, @@ -14520,6 +15885,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-5.0.0.tgz", "integrity": "sha512-JLSpbzh6UUXIEoqPsYBvVNVmyrjVZ1fzEFbqxKkTJQkWBO3xFzFT+KDnSKQWwOQNbuWRwt5LSD6HOTLGIWzfrw==", + "license": "ISC", "dependencies": { "npm-normalize-package-bin": "^5.0.0" }, @@ -14531,6 +15897,7 @@ "version": "8.0.0", "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-8.0.0.tgz", "integrity": "sha512-ScAUdMpyzkbpxoNekQ3tNRdFI8SJ86wgKZSQZdUxT+bj0wVFpsEMWnkXP0twVe1gJyNF5apBWDJhhIbgrIViRA==", + "license": "BSD-2-Clause", "dependencies": { "semver": "^7.1.1" }, @@ -14542,6 +15909,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-5.0.0.tgz", "integrity": "sha512-CJi3OS4JLsNMmr2u07OJlhcrPxCeOeP/4xq67aWNai6TNWWbTrlNDgl8NcFKVlcBKp18GPj+EzbNIgrBfZhsag==", + "license": "ISC", "engines": { "node": "^20.17.0 || >=22.9.0" } @@ -14562,9 +15930,10 @@ } }, "node_modules/npm-packlist": { - "version": "10.0.3", - "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-10.0.3.tgz", - "integrity": "sha512-zPukTwJMOu5X5uvm0fztwS5Zxyvmk38H/LfidkOMt3gbZVCyro2cD/ETzwzVPcWZA3JOyPznfUN/nkyFiyUbxg==", + "version": "10.0.4", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-10.0.4.tgz", + "integrity": "sha512-uMW73iajD8hiH4ZBxEV3HC+eTnppIqwakjOYuvgddnalIw2lJguKviK1pcUJDlIWm1wSJkchpDZDSVVsZEYRng==", + "license": "ISC", "dependencies": { "ignore-walk": "^8.0.0", "proc-log": "^6.0.0" @@ -14577,6 +15946,7 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-6.1.0.tgz", "integrity": "sha512-iG+GYldRf2BQ0UDUAd6JQ/RwzaQy6mXmsk/IzlYyal4A4SNFw54MeH4/tLkF4I5WoWG9SQwuqWzS99jaFQHBuQ==", + "license": "ISC", "engines": { "node": "^20.17.0 || >=22.9.0" } @@ -14585,6 +15955,7 @@ "version": "11.0.3", "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-11.0.3.tgz", "integrity": "sha512-buzyCfeoGY/PxKqmBqn1IUJrZnUi1VVJTdSSRPGI60tJdUhUoSQFhs0zycJokDdOznQentgrpf8LayEHyyYlqQ==", + "license": "ISC", "dependencies": { "npm-install-checks": "^8.0.0", "npm-normalize-package-bin": "^5.0.0", @@ -14599,6 +15970,7 @@ "version": "19.1.1", "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-19.1.1.tgz", "integrity": "sha512-TakBap6OM1w0H73VZVDf44iFXsOS3h+L4wVMXmbWOQroZgFhMch0juN6XSzBNlD965yIKvWg2dfu7NSiaYLxtw==", + "license": "ISC", "dependencies": { "@npmcli/redact": "^4.0.0", "jsonparse": "^1.3.1", @@ -14617,6 +15989,7 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-6.1.0.tgz", "integrity": "sha512-iG+GYldRf2BQ0UDUAd6JQ/RwzaQy6mXmsk/IzlYyal4A4SNFw54MeH4/tLkF4I5WoWG9SQwuqWzS99jaFQHBuQ==", + "license": "ISC", "engines": { "node": "^20.17.0 || >=22.9.0" } @@ -14819,21 +16192,6 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/ora/node_modules/cli-cursor": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", - "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", - "license": "MIT", - "dependencies": { - "restore-cursor": "^5.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/ora/node_modules/emoji-regex": { "version": "10.6.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", @@ -14880,49 +16238,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ora/node_modules/onetime": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", - "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", - "license": "MIT", - "dependencies": { - "mimic-function": "^5.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ora/node_modules/restore-cursor": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", - "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", - "license": "MIT", - "dependencies": { - "onetime": "^7.0.0", - "signal-exit": "^4.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ora/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "license": "ISC", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/ora/node_modules/string-width": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", @@ -15008,15 +16323,12 @@ } }, "node_modules/p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "optional": true, - "dependencies": { - "aggregate-error": "^3.0.0" - }, + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-7.0.6.tgz", + "integrity": "sha512-I4Prw6ivkd6p8PiYR1tXASOAOBzIJwu0TB7fqaX0c/8c3QAehNYmX57EijyGGGBt3c/BIowGwV03RVBtXvHEVg==", + "license": "MIT", "engines": { - "node": ">=10" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -15039,15 +16351,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/p-retry/node_modules/retry": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", - "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, "node_modules/p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", @@ -15057,10 +16360,12 @@ } }, "node_modules/pacote": { - "version": "21.0.4", - "resolved": "https://registry.npmjs.org/pacote/-/pacote-21.0.4.tgz", - "integrity": "sha512-RplP/pDW0NNNDh3pnaoIWYPvNenS7UqMbXyvMqJczosiFWTeGGwJC2NQBLqKf4rGLFfwCOnntw1aEp9Jiqm1MA==", + "version": "21.5.1", + "resolved": "https://registry.npmjs.org/pacote/-/pacote-21.5.1.tgz", + "integrity": "sha512-KvcJ9iy3crysCsgqc4+PknH/w6jkrp8JN36mpZBPwNaDRwTfMZD37YzRazNstiZUOhuF5pno9f78n9mEJBavwg==", + "license": "ISC", "dependencies": { + "@gar/promise-retry": "^1.0.0", "@npmcli/git": "^7.0.0", "@npmcli/installed-package-contents": "^4.0.0", "@npmcli/package-json": "^7.0.0", @@ -15074,7 +16379,6 @@ "npm-pick-manifest": "^11.0.1", "npm-registry-fetch": "^19.0.0", "proc-log": "^6.0.0", - "promise-retry": "^2.0.1", "sigstore": "^4.0.0", "ssri": "^13.0.0", "tar": "^7.4.3" @@ -15090,6 +16394,7 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-6.1.0.tgz", "integrity": "sha512-iG+GYldRf2BQ0UDUAd6JQ/RwzaQy6mXmsk/IzlYyal4A4SNFw54MeH4/tLkF4I5WoWG9SQwuqWzS99jaFQHBuQ==", + "license": "ISC", "engines": { "node": "^20.17.0 || >=22.9.0" } @@ -15223,24 +16528,25 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, "node_modules/path-scurry": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.1.tgz", - "integrity": "sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz", + "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==", + "license": "BlueOak-1.0.0", "dependencies": { "lru-cache": "^11.0.0", "minipass": "^7.1.2" }, "engines": { - "node": "20 || >=22" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/path-to-regexp": { - "version": "8.4.1", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.4.1.tgz", - "integrity": "sha512-fvU78fIjZ+SBM9YwCknCvKOUKkLVqtWDVctl0s7xIqfmfb38t2TT4ZU2gHm+Z8xGwgW+QWEU3oQSAzIbo89Ggw==", + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.4.2.tgz", + "integrity": "sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==", "license": "MIT", "funding": { "type": "opencollective", @@ -15276,6 +16582,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", + "license": "MIT", "optional": true }, "node_modules/performance-now": { @@ -15313,9 +16620,9 @@ } }, "node_modules/piscina": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/piscina/-/piscina-5.1.3.tgz", - "integrity": "sha512-0u3N7H4+hbr40KjuVn2uNhOcthu/9usKhnw5vT3J7ply79v3D3M8naI00el9Klcy16x557VsEkkUQaHCWFXC/g==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/piscina/-/piscina-5.2.0.tgz", + "integrity": "sha512-DszUCKeVN/5G5QKo6jAVHL8fmKnkJvQ0ACiVgY7YGCq3TUB2oznAOayvZPIAdEThvhczkXR+qm3IHsNXpFCYfA==", "license": "MIT", "engines": { "node": ">=20.x" @@ -15333,6 +16640,35 @@ "node": ">=16.20.0" } }, + "node_modules/pkijs": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/pkijs/-/pkijs-3.4.0.tgz", + "integrity": "sha512-emEcLuomt2j03vxD54giVB4SxTjnsqkU692xZOZXHDVoYyypEm+b3jpiTcc+Cf+myooc+/Ly0z01jqeNHVgJGw==", + "license": "BSD-3-Clause", + "dependencies": { + "@noble/hashes": "1.4.0", + "asn1js": "^3.0.6", + "bytestreamjs": "^2.0.1", + "pvtsutils": "^1.3.6", + "pvutils": "^1.1.3", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/pkijs/node_modules/@noble/hashes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", + "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", + "license": "MIT", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/pngjs": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-5.0.0.tgz", @@ -15376,9 +16712,9 @@ } }, "node_modules/postcss": { - "version": "8.5.6", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", - "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "version": "8.5.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.23.tgz", + "integrity": "sha512-g50586zr4bZmwFiTlflMu8E0bDTb5I5gertgwAKmsdUlTQIhZtunzUlD1WSzwcVWPoAVpsrA6vlfCD7oXvRwgg==", "funding": [ { "type": "opencollective", @@ -15395,7 +16731,7 @@ ], "license": "MIT", "dependencies": { - "nanoid": "^3.3.11", + "nanoid": "^3.3.16", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" }, @@ -15528,10 +16864,11 @@ } }, "node_modules/prettier": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.0.tgz", - "integrity": "sha512-zBf5eHpwHOGPC47h0zrPyNn+eAEIdEzfywMoYn2XPi0P44Zp0tSq64rq0xAREh4auw2cJZHo9QUob+NqCQky4g==", + "version": "3.9.6", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.9.6.tgz", + "integrity": "sha512-OpN0zzVdiaiAhxpuuj5efpIS4sY9j7bY6uR5mnj5yPzGkdkjNKSJeUThPb60Jw29QuAZgA4o+/iB49kFiaBX6g==", "dev": true, + "license": "MIT", "bin": { "prettier": "bin/prettier.cjs" }, @@ -15578,18 +16915,6 @@ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "license": "MIT" }, - "node_modules/promise-retry": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", - "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", - "dependencies": { - "err-code": "^2.0.2", - "retry": "^0.12.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -15651,6 +16976,24 @@ "node": ">=6" } }, + "node_modules/pvtsutils": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/pvtsutils/-/pvtsutils-1.3.6.tgz", + "integrity": "sha512-PLgQXQ6H2FWCaeRak8vvk1GW462lMxB5s3Jm673N82zI4vqtVUPuZdffdZbPDFRoU8kAhItWFtPCWiPpp4/EDg==", + "license": "MIT", + "dependencies": { + "tslib": "^2.8.1" + } + }, + "node_modules/pvutils": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pvutils/-/pvutils-1.2.0.tgz", + "integrity": "sha512-BbubeCEyTuQjVMakvJQ/Sxbc93F2pwmbsxONT/ZRrwU7Ua38d8unYTwXpTVLAKJ4BDuH9IGztCjQcd/N/39Dvg==", + "license": "MIT", + "engines": { + "node": ">=16.0.0" + } + }, "node_modules/qrcode": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/qrcode/-/qrcode-1.5.1.tgz", @@ -15690,11 +17033,13 @@ } }, "node_modules/qs": { - "version": "6.14.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.2.tgz", - "integrity": "sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q==", + "version": "6.15.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.3.tgz", + "integrity": "sha512-O9gl3zCl5h5blw1KGUzQKhA5oUXSl8rwUIM5o0S3nCXMliSvy5Dzx7/DJcI+SwgICv+IneSZwhBh1oSyEHA71A==", + "license": "BSD-3-Clause", "dependencies": { - "side-channel": "^1.1.0" + "es-define-property": "^1.0.1", + "side-channel": "^1.1.1" }, "engines": { "node": ">=0.6" @@ -15963,22 +17308,53 @@ "devOptional": true }, "node_modules/restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "optional": true, + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", + "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", + "license": "MIT", "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" + "onetime": "^7.0.0", + "signal-exit": "^4.1.0" }, "engines": { - "node": ">=8" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/restore-cursor/node_modules/onetime": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", + "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", + "license": "MIT", + "dependencies": { + "mimic-function": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/restore-cursor/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "license": "MIT", "engines": { "node": ">= 4" } @@ -16230,9 +17606,9 @@ } }, "node_modules/sass/node_modules/immutable": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.5.tgz", - "integrity": "sha512-t7xcm2siw+hlUM68I+UEOK+z84RzmN59as9DZ7P1l0994DKUWV7UXBMQZVxaoMSRQ+PBZbHCOoBt7a2wxOMt+A==", + "version": "5.1.9", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.9.tgz", + "integrity": "sha512-m8nVez3rwrgmWxtLMt1ZYXB2Lv7OKYn/disyxAlSDYAlKSlFoPPfIAmAM/M5xqL4m4C/wAPw7S2/CNaUii1Hxg==", "license": "MIT" }, "node_modules/sass/node_modules/readdirp": { @@ -16287,22 +17663,6 @@ "url": "https://opencollective.com/webpack" } }, - "node_modules/schema-utils/node_modules/ajv": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", - "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, "node_modules/schema-utils/node_modules/ajv-keywords": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", @@ -16315,12 +17675,6 @@ "ajv": "^8.8.2" } }, - "node_modules/schema-utils/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "license": "MIT" - }, "node_modules/select": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz", @@ -16333,16 +17687,16 @@ "license": "MIT" }, "node_modules/selfsigned": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz", - "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-5.5.0.tgz", + "integrity": "sha512-ftnu3TW4+3eBfLRFnDEkzGxSF/10BJBkaLJuBHZX0kiPS7bRdlpZGu6YGt4KngMkdTwJE6MbjavFpqHvqVt+Ew==", "license": "MIT", "dependencies": { - "@types/node-forge": "^1.3.0", - "node-forge": "^1" + "@peculiar/x509": "^1.14.2", + "pkijs": "^3.3.3" }, "engines": { - "node": ">=10" + "node": ">=18" } }, "node_modules/semver": { @@ -16525,7 +17879,8 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/server-destroy/-/server-destroy-1.0.1.tgz", "integrity": "sha512-rb+9B5YBIEzYcD6x2VKidaa+cqYBJQKnU4oe4E3ANwRRN56yk/ua1YCJT1n21NTS8w6CcOclAKNP3PhdCXKYtQ==", - "devOptional": true + "devOptional": true, + "license": "ISC" }, "node_modules/set-blocking": { "version": "2.0.0", @@ -16569,9 +17924,9 @@ } }, "node_modules/shell-quote": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.3.tgz", - "integrity": "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.10.0.tgz", + "integrity": "sha512-w1aiOKwKuRgtwAReIIj89puqg+I7GvX4IbLrvmhXbzQsj1+Zwi4VO3+fa6ZF91TWSjIxoEkKnMeHcLEODK5ZXA==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -16581,14 +17936,14 @@ } }, "node_modules/side-channel": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", - "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.1.tgz", + "integrity": "sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0", - "object-inspect": "^1.13.3", - "side-channel-list": "^1.0.0", + "object-inspect": "^1.13.4", + "side-channel-list": "^1.0.1", "side-channel-map": "^1.0.1", "side-channel-weakmap": "^1.0.2" }, @@ -16600,13 +17955,13 @@ } }, "node_modules/side-channel-list": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", - "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz", + "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0", - "object-inspect": "^1.13.3" + "object-inspect": "^1.13.4" }, "engines": { "node": ">= 0.4" @@ -16666,16 +18021,17 @@ "optional": true }, "node_modules/sigstore": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/sigstore/-/sigstore-4.1.0.tgz", - "integrity": "sha512-/fUgUhYghuLzVT/gaJoeVehLCgZiUxPCPMcyVNY0lIf/cTCz58K/WTI7PefDarXxp9nUKpEwg1yyz3eSBMTtgA==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/sigstore/-/sigstore-4.1.1.tgz", + "integrity": "sha512-endqECJkfhozrXMK5ngu/UAA0xVcVEFdnHJCElGaExypjW+HK5i6zu3NteLoaX/iFbRUbC3+DjttQs0GARr+5w==", + "license": "Apache-2.0", "dependencies": { "@sigstore/bundle": "^4.0.0", - "@sigstore/core": "^3.1.0", + "@sigstore/core": "^3.2.1", "@sigstore/protobuf-specs": "^0.5.0", - "@sigstore/sign": "^4.1.0", - "@sigstore/tuf": "^4.0.1", - "@sigstore/verify": "^3.1.0" + "@sigstore/sign": "^4.1.1", + "@sigstore/tuf": "^4.0.2", + "@sigstore/verify": "^3.1.1" }, "engines": { "node": "^20.17.0 || >=22.9.0" @@ -16720,23 +18076,56 @@ } }, "node_modules/slice-ansi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", - "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-8.0.0.tgz", + "integrity": "sha512-stxByr12oeeOyY2BlviTNQlYV5xOj47GirPr4yA1hE9JCtxfQN0+tVbkxwCtYDQWhEKWFHsEK48ORg5jrouCAg==", + "license": "MIT", "optional": true, "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" + "ansi-styles": "^6.2.3", + "is-fullwidth-code-point": "^5.1.0" }, "engines": { - "node": ">=8" + "node": ">=20" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/is-fullwidth-code-point": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.1.0.tgz", + "integrity": "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "get-east-asian-width": "^1.3.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/smart-buffer": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "license": "MIT", "engines": { "node": ">= 6.0.0", "npm": ">= 3.0.0" @@ -16761,23 +18150,50 @@ } }, "node_modules/socket.io-adapter": { - "version": "2.5.5", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.5.tgz", - "integrity": "sha512-eLDQas5dzPgOWCk9GuuJC2lBqItuhKI4uxGgo9aIV7MYbk2h9Q6uULEh8WBzThoI7l+qU9Ast9fVUmkqPP9wYg==", + "version": "2.5.8", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.8.tgz", + "integrity": "sha512-6Oy52pbg+kvdCVvjcN+FnY7BvxZ7cIHNScbvztT/It5d0vbwoJoVZmF2gjJmnV0/4WlXRfG15zc45ySk9Ah8bw==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "debug": "~4.4.1", + "ws": "~8.21.0" + } + }, + "node_modules/socket.io-adapter/node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "devOptional": true, + "license": "MIT", "dependencies": { - "debug": "~4.3.4", - "ws": "~8.17.1" + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, + "node_modules/socket.io-adapter/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "devOptional": true, + "license": "MIT" + }, "node_modules/socket.io-client": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.8.0.tgz", - "integrity": "sha512-C0jdhD5yQahMws9alf/yvtsMGTaIDBnZ8Rb5HU56svyq0l5LIrGzIDZZD5pHQlmzxLuU91Gz+VpQMKgCTNYtkw==", + "version": "4.8.3", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.8.3.tgz", + "integrity": "sha512-uP0bpjWrjQmUt5DTHq9RuoCBdFJF10cdX9X+a368j/Ft0wmaVgxlrjvK3kjvgCODOMMOz9lcaRzxmso0bTWZ/g==", "devOptional": true, + "license": "MIT", "dependencies": { "@socket.io/component-emitter": "~3.1.0", - "debug": "~4.3.2", + "debug": "~4.4.1", "engine.io-client": "~6.6.1", "socket.io-parser": "~4.2.4" }, @@ -16785,10 +18201,35 @@ "node": ">=10.0.0" } }, + "node_modules/socket.io-client/node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/socket.io-client/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "devOptional": true, + "license": "MIT" + }, "node_modules/socket.io-parser": { - "version": "4.2.6", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.6.tgz", - "integrity": "sha512-asJqbVBDsBCJx0pTqw3WfesSY0iRX+2xzWEWzrpcH7L6fLzrhyF8WPI8UaeM4YCuDfpwA/cgsdugMsmtz8EJeg==", + "version": "4.2.7", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.7.tgz", + "integrity": "sha512-IH/iSeO9T6gz1KkFleGDWkG9N3dl4jXVYUtMhIqH10Md0ttMer8nUNWiP1DKuNrybD2xBrixLJdCC9J6ECoYkg==", "devOptional": true, "license": "MIT", "dependencies": { @@ -16836,11 +18277,12 @@ } }, "node_modules/socks": { - "version": "2.8.7", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.7.tgz", - "integrity": "sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==", + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.9.tgz", + "integrity": "sha512-LJhUYUvItdQ0LkJTmPeaEObWXAqFyfmP85x0tch/ez9cahmhlBBLbIqDFnvBnUJGagb0JbIQrkBs1wJ+yRYpEw==", + "license": "MIT", "dependencies": { - "ip-address": "^10.0.1", + "ip-address": "^10.1.1", "smart-buffer": "^4.2.0" }, "engines": { @@ -16852,6 +18294,7 @@ "version": "8.0.5", "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz", "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==", + "license": "MIT", "dependencies": { "agent-base": "^7.1.2", "debug": "^4.3.4", @@ -16918,33 +18361,27 @@ "source-map": "^0.6.0" } }, - "node_modules/spdx-correct": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", - "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", - "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, "node_modules/spdx-exceptions": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", - "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==" + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "license": "CC-BY-3.0" }, "node_modules/spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-4.0.0.tgz", + "integrity": "sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==", + "license": "MIT", "dependencies": { "spdx-exceptions": "^2.1.0", "spdx-license-ids": "^3.0.0" } }, "node_modules/spdx-license-ids": { - "version": "3.0.22", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.22.tgz", - "integrity": "sha512-4PRT4nh1EImPbt2jASOKHX7PB7I+e4IWNLvkKFDxNhJlfjbYlleYQh285Z/3mPTHSAK/AvdMmw5BNNuYH8ShgQ==" + "version": "3.0.23", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.23.tgz", + "integrity": "sha512-CWLcCCH7VLu13TgOH+r8p1O/Znwhqv/dbb6lqWy67G+pT1kHmeD/+V36AVb/vq8QMIQwVShJ6Ssl5FPh0fuSdw==", + "license": "CC0-1.0" }, "node_modules/spdy": { "version": "4.0.2", @@ -17015,9 +18452,10 @@ } }, "node_modules/ssri": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-13.0.0.tgz", - "integrity": "sha512-yizwGBpbCn4YomB2lzhZqrHLJoqFGXihNbib3ozhqF/cIp5ue+xSmOQrjNasEE62hFxsCcg/V/z23t4n8jMEng==", + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-13.0.1.tgz", + "integrity": "sha512-QUiRf1+u9wPTL/76GTYlKttDEBWV1ga9ZXW8BG6kfdeyyM8LGPix9gROyg9V2+P0xNyF3X2Go526xKFdMZrHSQ==", + "license": "ISC", "dependencies": { "minipass": "^7.0.3" }, @@ -17120,6 +18558,7 @@ "resolved": "https://registry.npmjs.org/stream-throttle/-/stream-throttle-0.1.3.tgz", "integrity": "sha512-889+B9vN9dq7/vLbGyuHeZ6/ctf5sNuGWsDy89uNxkFTAgzy0eK7+w5fL3KLNRTkLle7EgZGvHUphZW0Q26MnQ==", "devOptional": true, + "license": "BSD-3-Clause", "dependencies": { "commander": "^2.2.0", "limiter": "^1.0.5" @@ -17238,9 +18677,10 @@ "license": "MIT" }, "node_modules/systeminformation": { - "version": "5.31.1", - "resolved": "https://registry.npmjs.org/systeminformation/-/systeminformation-5.31.1.tgz", - "integrity": "sha512-6pRwxoGeV/roJYpsfcP6tN9mep6pPeCtXbUOCdVa0nme05Brwcwdge/fVNhIZn2wuUitAKZm4IYa7QjnRIa9zA==", + "version": "5.33.4", + "resolved": "https://registry.npmjs.org/systeminformation/-/systeminformation-5.33.4.tgz", + "integrity": "sha512-poXpX8M9NBll1NDMW1ho6qRFkjrlttfm8E/YtPmn5x0TQ1z8LoJUHg9kwr/sRDmCjktqfnFRxqsoUNpaRakeMQ==", + "license": "MIT", "optional": true, "os": [ "darwin", @@ -17256,7 +18696,7 @@ "systeminformation": "lib/cli.js" }, "engines": { - "node": ">=8.0.0" + "node": ">=10.0.0" }, "funding": { "type": "Buy me a coffee", @@ -17276,9 +18716,9 @@ } }, "node_modules/tar": { - "version": "7.5.12", - "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.12.tgz", - "integrity": "sha512-9TsuLcdhOn4XztcQqhNyq1KOwOOED/3k58JAvtULiYqbO8B/0IBAAIE1hj0Svmm58k27TmcigyDI0deMlgG3uw==", + "version": "7.5.22", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.22.tgz", + "integrity": "sha512-MFO/QzvtAOmJbkhOaCTvbGcFN9L9b+JunIsDwaKljSOdcLMea3NJ1k9Usz/rjdfSXTq4dfzfeS7W4p4YOAAHeA==", "license": "BlueOak-1.0.0", "dependencies": { "@isaacs/fs-minipass": "^4.0.0", @@ -17341,19 +18781,10 @@ } } }, - "node_modules/terser-webpack-plugin/node_modules/@jridgewell/trace-mapping": { - "version": "0.3.31", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", - "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, "node_modules/thingies": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/thingies/-/thingies-2.6.0.tgz", - "integrity": "sha512-rMHRjmlFLM1R96UYPvpmnc3LYtdFrT33JIB7L9hetGue1qAPfn1N2LJeEjxUSidu1Iku+haLZXDuEXUHNGO/lg==", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/thingies/-/thingies-2.6.1.tgz", + "integrity": "sha512-cV/CMGTK3M4MlnJ/0At6ismOw/A0EEniDNScajjz/Br3c1sqE72YD01rGpPTKwd27wAxI5Pr+6+0w8yofzFRYw==", "license": "MIT", "engines": { "node": ">=10.18" @@ -17498,6 +18929,16 @@ "license": "MIT", "optional": true }, + "node_modules/tmp": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.7.tgz", + "integrity": "sha512-e0votIpp4Uo2AJYSzVHV6xCcawuiez3DzqDAbrTc3YxBkplN6e+dM13ZeIcZnDg/QpSuU2zfZ3rzwY8ukEnaXw==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14.14" + } + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -17568,9 +19009,9 @@ } }, "node_modules/ts-api-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", - "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz", + "integrity": "sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==", "dev": true, "license": "MIT", "engines": { @@ -17581,10 +19022,11 @@ } }, "node_modules/ts-node": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", - "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", "dev": true, + "license": "MIT", "dependencies": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", @@ -17623,25 +19065,35 @@ } } }, - "node_modules/ts-node/node_modules/acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "license": "0BSD" }, + "node_modules/tsyringe": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/tsyringe/-/tsyringe-4.10.0.tgz", + "integrity": "sha512-axr3IdNuVIxnaK5XGEUFTu3YmAQ6lllgrvqfEoR16g/HGnYY/6We4oWENtAnzK6/LpJ2ur9PAb80RBt7/U4ugw==", + "license": "MIT", + "dependencies": { + "tslib": "^1.9.3" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/tsyringe/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "license": "0BSD" + }, "node_modules/tuf-js": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/tuf-js/-/tuf-js-4.1.0.tgz", "integrity": "sha512-50QV99kCKH5P/Vs4E2Gzp7BopNV+KzTXqWeaxrfu5IQJBOULRsTIS9seSsOVT8ZnGXzCyx55nYWAi4qJzpZKEQ==", + "license": "MIT", "dependencies": { "@tufjs/models": "4.1.0", "debug": "^4.4.3", @@ -17655,6 +19107,7 @@ "version": "4.4.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", "dependencies": { "ms": "^2.1.3" }, @@ -17670,7 +19123,8 @@ "node_modules/tuf-js/node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" }, "node_modules/tunnel-agent": { "version": "0.6.0", @@ -17714,31 +19168,62 @@ "node": ">=4" } }, - "node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "optional": true, + "node_modules/type-is": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.1.0.tgz", + "integrity": "sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA==", + "license": "MIT", + "dependencies": { + "content-type": "^2.0.0", + "media-typer": "^1.1.0", + "mime-types": "^3.0.0" + }, "engines": { - "node": ">=10" + "node": ">= 18" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "node_modules/type-is/node_modules/content-type": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-2.1.0.tgz", + "integrity": "sha512-mj7UPXE0jaqaOsukNZRUEfEi2AcL7C/vwmwcHV0O97eO1E1pxBZuyjlZrx5seTaNBg1U6+o35wpa35Qfcc+7ag==", "license": "MIT", - "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" + "engines": { + "node": ">=18" }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/type-is/node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, + "node_modules/type-is/node_modules/mime-types": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, "node_modules/typed-assert": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/typed-assert/-/typed-assert-1.0.9.tgz", @@ -17813,28 +19298,6 @@ "node": ">=4" } }, - "node_modules/unique-filename": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-5.0.0.tgz", - "integrity": "sha512-2RaJTAvAb4owyjllTfXzFClJ7WsGxlykkPvCr9pA//LD9goVq+m4PPAeBgNodGZ7nSrntT/auWpJ6Y5IFXcfjg==", - "dependencies": { - "unique-slug": "^6.0.0" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/unique-slug": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-6.0.0.tgz", - "integrity": "sha512-4Lup7Ezn8W3d52/xBhZBVdx323ckxa7DEvd9kPQHppTkLoJXw6ltrBCyj5pnrxj0qKDxYMJ56CoxNuFCscdTiw==", - "dependencies": { - "imurmurhash": "^0.1.4" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, "node_modules/universalify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", @@ -17891,10 +19354,11 @@ } }, "node_modules/uri-js": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.0.tgz", - "integrity": "sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "punycode": "^2.1.0" } @@ -17916,6 +19380,8 @@ "version": "8.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "deprecated": "uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028).", + "license": "MIT", "bin": { "uuid": "dist/bin/uuid" } @@ -17924,16 +19390,8 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true - }, - "node_modules/validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dependencies": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } + "dev": true, + "license": "MIT" }, "node_modules/validate-npm-package-name": { "version": "6.0.2", @@ -17968,12 +19426,12 @@ } }, "node_modules/vite": { - "version": "7.1.11", - "resolved": "https://registry.npmjs.org/vite/-/vite-7.1.11.tgz", - "integrity": "sha512-uzcxnSDVjAopEUjljkWh8EIrg6tlzrjFUfMcR1EVsRDGwf/ccef0qQPRyOrROwhrTDaApueq+ja+KLPlzR/zdg==", + "version": "7.3.6", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.6.tgz", + "integrity": "sha512-4XP60spRGjSZFf1qYH+dJIkK2znL3zQfl9KkOV9MkkRR/3Dls0dxaBsQPTloEc5BLXWPL9vsOxopxyKoMmDueg==", "license": "MIT", "dependencies": { - "esbuild": "^0.25.0", + "esbuild": "^0.27.0 || ^0.28.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", @@ -18477,14 +19935,14 @@ } }, "node_modules/webpack-dev-server": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-5.2.2.tgz", - "integrity": "sha512-QcQ72gh8a+7JO63TAx/6XZf/CWhgMzu5m0QirvPfGvptOusAxG12w2+aua1Jkjr7hzaWDnJ2n6JFeexMHI+Zjg==", + "version": "5.2.6", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-5.2.6.tgz", + "integrity": "sha512-HNLRmamRvVavZQ+avceZifmv8hmdUjg43t6MI4SqJDwFdW7RPQwH5vzGhDRZSX59SgfbeHhLnq3g+uooWo7pVw==", "license": "MIT", "dependencies": { "@types/bonjour": "^3.5.13", "@types/connect-history-api-fallback": "^1.5.4", - "@types/express": "^4.17.21", + "@types/express": "^4.17.25", "@types/express-serve-static-core": "^4.17.21", "@types/serve-index": "^1.9.4", "@types/serve-static": "^1.15.5", @@ -18494,17 +19952,17 @@ "bonjour-service": "^1.2.1", "chokidar": "^3.6.0", "colorette": "^2.0.10", - "compression": "^1.7.4", + "compression": "^1.8.1", "connect-history-api-fallback": "^2.0.0", - "express": "^4.21.2", + "express": "^4.22.1", "graceful-fs": "^4.2.6", "http-proxy-middleware": "^2.0.9", "ipaddr.js": "^2.1.0", - "launch-editor": "^2.6.1", + "launch-editor": "^2.14.1", "open": "^10.0.3", "p-retry": "^6.2.0", "schema-utils": "^4.2.0", - "selfsigned": "^2.4.1", + "selfsigned": "^5.5.0", "serve-index": "^1.9.1", "sockjs": "^0.3.24", "spdy": "^4.0.2", @@ -18533,15 +19991,39 @@ } } }, - "node_modules/webpack-dev-server/node_modules/connect-history-api-fallback": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", - "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==", + "node_modules/webpack-dev-server/node_modules/body-parser": { + "version": "1.20.6", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.6.tgz", + "integrity": "sha512-p5tAzS57i5MV9fZFDj9LeIiTZEufbSe2eDozP+ElheSUq1m74CRq1jI4mYNDdVs9vQztXFLuk/Gd6BWTdwRJ5g==", "license": "MIT", - "engines": { - "node": ">=0.8" - } - }, + "dependencies": { + "bytes": "~3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "~1.2.0", + "http-errors": "~2.0.1", + "iconv-lite": "~0.4.24", + "on-finished": "~2.4.1", + "qs": "~6.15.1", + "raw-body": "~2.5.3", + "type-is": "~1.6.18", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/webpack-dev-server/node_modules/connect-history-api-fallback": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", + "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==", + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, "node_modules/webpack-dev-server/node_modules/content-disposition": { "version": "0.5.4", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", @@ -18579,14 +20061,14 @@ } }, "node_modules/webpack-dev-server/node_modules/express": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.22.1.tgz", - "integrity": "sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==", + "version": "4.22.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.22.2.tgz", + "integrity": "sha512-IuL+Elrou2ZvCFHs18/CIzy2Nzvo25nZ1/D2eIZlz7c+QUayAcYoiM2BthCjs+EBHVpjYjcuLDAiCWgeIX3X1Q==", "license": "MIT", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "~1.20.3", + "body-parser": "~1.20.5", "content-disposition": "~0.5.4", "content-type": "~1.0.4", "cookie": "~0.7.1", @@ -18605,7 +20087,7 @@ "parseurl": "~1.3.3", "path-to-regexp": "~0.1.12", "proxy-addr": "~2.0.7", - "qs": "~6.14.0", + "qs": "~6.15.1", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", "send": "~0.19.0", @@ -18642,12530 +20124,375 @@ "node": ">= 0.8" } }, - "node_modules/webpack-dev-server/node_modules/ipaddr.js": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.3.0.tgz", - "integrity": "sha512-Zv/pA+ciVFbCSBBjGfaKUya/CcGmUHzTydLMaTwrUUEM2DIEO3iZvueGxmacvmN50fGpGVKeTXpb2LcYQxeVdg==", - "license": "MIT", - "engines": { - "node": ">= 10" - } - }, - "node_modules/webpack-dev-server/node_modules/merge-descriptors": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", - "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/webpack-dev-server/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "license": "MIT" - }, - "node_modules/webpack-dev-server/node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "node_modules/webpack-dev-server/node_modules/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", "license": "MIT", "dependencies": { - "ee-first": "1.1.1" + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" }, "engines": { "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/webpack-dev-server/node_modules/path-to-regexp": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.13.tgz", - "integrity": "sha512-A/AGNMFN3c8bOlvV9RreMdrv7jsmF9XIfDeCd87+I8RNg6s78BhJxMu69NEMHBSJFxKidViTEdruRwEk/WIKqA==", - "license": "MIT" - }, - "node_modules/webpack-dev-server/node_modules/statuses": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", - "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/webpack-dev-server/node_modules/ws": { - "version": "8.20.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.20.0.tgz", - "integrity": "sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==", - "license": "MIT", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/webpack-merge": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-6.0.1.tgz", - "integrity": "sha512-hXXvrjtx2PLYx4qruKl+kyRSLc52V+cCvMxRjmKwoA+CBbbF5GfIBtR6kCvl0fYGqTUPKB+1ktVmTHqMOzgCBg==", - "license": "MIT", - "dependencies": { - "clone-deep": "^4.0.1", - "flat": "^5.0.2", - "wildcard": "^2.0.1" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/webpack-sources": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.3.tgz", - "integrity": "sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==", - "license": "MIT", - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/webpack-subresource-integrity": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/webpack-subresource-integrity/-/webpack-subresource-integrity-5.1.0.tgz", - "integrity": "sha512-sacXoX+xd8r4WKsy9MvH/q/vBtEHr86cpImXwyg74pFIpERKt6FmB8cXpeuh0ZLgclOlHI4Wcll7+R5L02xk9Q==", - "dependencies": { - "typed-assert": "^1.0.8" - }, - "engines": { - "node": ">= 12" - }, - "peerDependencies": { - "html-webpack-plugin": ">= 5.0.0-beta.1 < 6", - "webpack": "^5.12.0" - }, - "peerDependenciesMeta": { - "html-webpack-plugin": { - "optional": true - } - } - }, - "node_modules/webpack/node_modules/acorn-import-phases": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz", - "integrity": "sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==", - "license": "MIT", - "engines": { - "node": ">=10.13.0" - }, - "peerDependencies": { - "acorn": "^8.14.0" - } - }, - "node_modules/webpack/node_modules/watchpack": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.5.1.tgz", - "integrity": "sha512-Zn5uXdcFNIA1+1Ei5McRd+iRzfhENPCe7LeABkJtNulSxjma+l7ltNx55BWZkRlwRnpOgHqxnjyaDgJnNXnqzg==", - "dependencies": { - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.1.2" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/websocket-driver": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", - "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", - "license": "Apache-2.0", - "dependencies": { - "http-parser-js": ">=0.5.1", - "safe-buffer": ">=5.1.0", - "websocket-extensions": ">=0.1.1" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/websocket-extensions": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", - "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", - "license": "Apache-2.0", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/whatwg-mimetype": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-5.0.0.tgz", - "integrity": "sha512-sXcNcHOC51uPGF0P/D4NVtrkjSU2fNsm9iog4ZvZJsL3rjoDAzXZhkm2MWt1y+PUdggKAYVoMAIYcs78wJ51Cw==", - "devOptional": true, - "license": "MIT", - "engines": { - "node": ">=20" - } - }, - "node_modules/whatwg-url": { - "version": "17.1.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-17.1.0.tgz", - "integrity": "sha512-3GeworPmc2ZfEEHP7lEbUfBX/L75wdEsi0rLNhXcXxnoN5jyq0SL5gCy06SGW2cyTIZdTvWIDQNQoza++vKeaw==", - "devOptional": true, - "license": "MIT", - "dependencies": { - "@exodus/bytes": "^1.15.1", - "tr46": "^6.0.0", - "webidl-conversions": "^8.0.1" - }, - "engines": { - "node": "^22.14.0 || >=24.0.0" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" - }, - "node_modules/why-is-node-running": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", - "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", - "devOptional": true, - "license": "MIT", - "dependencies": { - "siginfo": "^2.0.0", - "stackback": "0.0.2" - }, - "bin": { - "why-is-node-running": "cli.js" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wildcard": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", - "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", - "license": "MIT" - }, - "node_modules/word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "node_modules/ws": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", - "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", - "devOptional": true, - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/wsl-utils": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/wsl-utils/-/wsl-utils-0.1.0.tgz", - "integrity": "sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==", - "license": "MIT", - "dependencies": { - "is-wsl": "^3.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/xhr2": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/xhr2/-/xhr2-0.2.1.tgz", - "integrity": "sha512-sID0rrVCqkVNUn8t6xuv9+6FViXjUVXq8H5rWOH2rz9fDNQEd4g0EA2XlcEdJXRz5BMEn4O1pJFdT+z4YHhoWw==", - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "node_modules/xml-name-validator": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", - "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==", - "devOptional": true, - "license": "Apache-2.0", - "engines": { - "node": ">=18" - } - }, - "node_modules/xmlchars": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", - "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", - "devOptional": true, - "license": "MIT" - }, - "node_modules/xmlhttprequest-ssl": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.1.1.tgz", - "integrity": "sha512-ptjR8YSJIXoA3Mbv5po7RtSYHO6mZr8s7i5VGmEk7QY2pQWyT1o0N+W1gKbOyJPUCGXGnuw0wqe8f0L6Y0ny7g==", - "devOptional": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/y18n": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", - "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==" - }, - "node_modules/yallist": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", - "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", - "engines": { - "node": ">=18" - } - }, - "node_modules/yargs": { - "version": "18.0.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-18.0.0.tgz", - "integrity": "sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg==", - "license": "MIT", - "dependencies": { - "cliui": "^9.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "string-width": "^7.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^22.0.0" - }, - "engines": { - "node": "^20.19.0 || ^22.12.0 || >=23" - } - }, - "node_modules/yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/yargs/node_modules/ansi-regex": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", - "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/yargs/node_modules/ansi-styles": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", - "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/yargs/node_modules/cliui": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-9.0.1.tgz", - "integrity": "sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==", - "license": "ISC", - "dependencies": { - "string-width": "^7.2.0", - "strip-ansi": "^7.1.0", - "wrap-ansi": "^9.0.0" - }, - "engines": { - "node": ">=20" - } - }, - "node_modules/yargs/node_modules/emoji-regex": { - "version": "10.6.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", - "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", - "license": "MIT" - }, - "node_modules/yargs/node_modules/string-width": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", - "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", - "license": "MIT", - "dependencies": { - "emoji-regex": "^10.3.0", - "get-east-asian-width": "^1.0.0", - "strip-ansi": "^7.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/yargs/node_modules/strip-ansi": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", - "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.2.2" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/yargs/node_modules/wrap-ansi": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", - "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.2.1", - "string-width": "^7.0.0", - "strip-ansi": "^7.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/yargs/node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs/node_modules/yargs-parser": { - "version": "22.0.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-22.0.0.tgz", - "integrity": "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==", - "license": "ISC", - "engines": { - "node": "^20.19.0 || ^22.12.0 || >=23" - } - }, - "node_modules/yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", - "optional": true, - "dependencies": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" - } - }, - "node_modules/yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/yoctocolors-cjs": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/yoctocolors-cjs/-/yoctocolors-cjs-2.1.3.tgz", - "integrity": "sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/zod": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/zod/-/zod-4.1.13.tgz", - "integrity": "sha512-AvvthqfqrAhNH9dnfmrfKzX5upOdjUVJYFqNSlkmGf64gRaTzlPwz99IHYnVs28qYAybvAlBV+H7pn0saFY4Ig==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } - }, - "node_modules/zod-to-json-schema": { - "version": "3.25.1", - "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.25.1.tgz", - "integrity": "sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA==", - "license": "ISC", - "peerDependencies": { - "zod": "^3.25 || ^4" - } - }, - "node_modules/zone.js": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.15.1.tgz", - "integrity": "sha512-XE96n56IQpJM7NAoXswY3XRLcWFW83xe0BiAOeMD7K5k5xecOeul3Qcpx6GqEeeHNkW5DWL5zOyTbEfB4eti8w==", - "license": "MIT" - }, - "node_modules/zrender": { - "version": "5.4.4", - "resolved": "https://registry.npmjs.org/zrender/-/zrender-5.4.4.tgz", - "integrity": "sha512-0VxCNJ7AGOMCWeHVyTrGzUgrK4asT4ml9PEkeGirAkKNYXYzoPJCLvmyfdoOXcjTHPs10OZVMfD1Rwg16AZyYw==", - "license": "BSD-3-Clause", - "dependencies": { - "tslib": "2.3.0" - } - }, - "node_modules/zrender/node_modules/tslib": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", - "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==", - "license": "0BSD" - } - }, - "dependencies": { - "@algolia/abtesting": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@algolia/abtesting/-/abtesting-1.1.0.tgz", - "integrity": "sha512-sEyWjw28a/9iluA37KLGu8vjxEIlb60uxznfTUmXImy7H5NvbpSO6yYgmgH5KiD7j+zTUUihiST0jEP12IoXow==", - "requires": { - "@algolia/client-common": "5.35.0", - "@algolia/requester-browser-xhr": "5.35.0", - "@algolia/requester-fetch": "5.35.0", - "@algolia/requester-node-http": "5.35.0" - } - }, - "@algolia/client-abtesting": { - "version": "5.35.0", - "resolved": "https://registry.npmjs.org/@algolia/client-abtesting/-/client-abtesting-5.35.0.tgz", - "integrity": "sha512-uUdHxbfHdoppDVflCHMxRlj49/IllPwwQ2cQ8DLC4LXr3kY96AHBpW0dMyi6ygkn2MtFCc6BxXCzr668ZRhLBQ==", - "requires": { - "@algolia/client-common": "5.35.0", - "@algolia/requester-browser-xhr": "5.35.0", - "@algolia/requester-fetch": "5.35.0", - "@algolia/requester-node-http": "5.35.0" - } - }, - "@algolia/client-analytics": { - "version": "5.35.0", - "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-5.35.0.tgz", - "integrity": "sha512-SunAgwa9CamLcRCPnPHx1V2uxdQwJGqb1crYrRWktWUdld0+B2KyakNEeVn5lln4VyeNtW17Ia7V7qBWyM/Skw==", - "requires": { - "@algolia/client-common": "5.35.0", - "@algolia/requester-browser-xhr": "5.35.0", - "@algolia/requester-fetch": "5.35.0", - "@algolia/requester-node-http": "5.35.0" - } - }, - "@algolia/client-common": { - "version": "5.35.0", - "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.35.0.tgz", - "integrity": "sha512-ipE0IuvHu/bg7TjT2s+187kz/E3h5ssfTtjpg1LbWMgxlgiaZIgTTbyynM7NfpSJSKsgQvCQxWjGUO51WSCu7w==" - }, - "@algolia/client-insights": { - "version": "5.35.0", - "resolved": "https://registry.npmjs.org/@algolia/client-insights/-/client-insights-5.35.0.tgz", - "integrity": "sha512-UNbCXcBpqtzUucxExwTSfAe8gknAJ485NfPN6o1ziHm6nnxx97piIbcBQ3edw823Tej2Wxu1C0xBY06KgeZ7gA==", - "requires": { - "@algolia/client-common": "5.35.0", - "@algolia/requester-browser-xhr": "5.35.0", - "@algolia/requester-fetch": "5.35.0", - "@algolia/requester-node-http": "5.35.0" - } - }, - "@algolia/client-personalization": { - "version": "5.35.0", - "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-5.35.0.tgz", - "integrity": "sha512-/KWjttZ6UCStt4QnWoDAJ12cKlQ+fkpMtyPmBgSS2WThJQdSV/4UWcqCUqGH7YLbwlj3JjNirCu3Y7uRTClxvA==", - "requires": { - "@algolia/client-common": "5.35.0", - "@algolia/requester-browser-xhr": "5.35.0", - "@algolia/requester-fetch": "5.35.0", - "@algolia/requester-node-http": "5.35.0" - } - }, - "@algolia/client-query-suggestions": { - "version": "5.35.0", - "resolved": "https://registry.npmjs.org/@algolia/client-query-suggestions/-/client-query-suggestions-5.35.0.tgz", - "integrity": "sha512-8oCuJCFf/71IYyvQQC+iu4kgViTODbXDk3m7yMctEncRSRV+u2RtDVlpGGfPlJQOrAY7OONwJlSHkmbbm2Kp/w==", - "requires": { - "@algolia/client-common": "5.35.0", - "@algolia/requester-browser-xhr": "5.35.0", - "@algolia/requester-fetch": "5.35.0", - "@algolia/requester-node-http": "5.35.0" - } - }, - "@algolia/client-search": { - "version": "5.35.0", - "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.35.0.tgz", - "integrity": "sha512-FfmdHTrXhIduWyyuko1YTcGLuicVbhUyRjO3HbXE4aP655yKZgdTIfMhZ/V5VY9bHuxv/fGEh3Od1Lvv2ODNTg==", - "requires": { - "@algolia/client-common": "5.35.0", - "@algolia/requester-browser-xhr": "5.35.0", - "@algolia/requester-fetch": "5.35.0", - "@algolia/requester-node-http": "5.35.0" - } - }, - "@algolia/ingestion": { - "version": "1.35.0", - "resolved": "https://registry.npmjs.org/@algolia/ingestion/-/ingestion-1.35.0.tgz", - "integrity": "sha512-gPzACem9IL1Co8mM1LKMhzn1aSJmp+Vp434An4C0OBY4uEJRcqsLN3uLBlY+bYvFg8C8ImwM9YRiKczJXRk0XA==", - "requires": { - "@algolia/client-common": "5.35.0", - "@algolia/requester-browser-xhr": "5.35.0", - "@algolia/requester-fetch": "5.35.0", - "@algolia/requester-node-http": "5.35.0" - } - }, - "@algolia/monitoring": { - "version": "1.35.0", - "resolved": "https://registry.npmjs.org/@algolia/monitoring/-/monitoring-1.35.0.tgz", - "integrity": "sha512-w9MGFLB6ashI8BGcQoVt7iLgDIJNCn4OIu0Q0giE3M2ItNrssvb8C0xuwJQyTy1OFZnemG0EB1OvXhIHOvQwWw==", - "requires": { - "@algolia/client-common": "5.35.0", - "@algolia/requester-browser-xhr": "5.35.0", - "@algolia/requester-fetch": "5.35.0", - "@algolia/requester-node-http": "5.35.0" - } - }, - "@algolia/recommend": { - "version": "5.35.0", - "resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-5.35.0.tgz", - "integrity": "sha512-AhrVgaaXAb8Ue0u2nuRWwugt0dL5UmRgS9LXe0Hhz493a8KFeZVUE56RGIV3hAa6tHzmAV7eIoqcWTQvxzlJeQ==", - "requires": { - "@algolia/client-common": "5.35.0", - "@algolia/requester-browser-xhr": "5.35.0", - "@algolia/requester-fetch": "5.35.0", - "@algolia/requester-node-http": "5.35.0" - } - }, - "@algolia/requester-browser-xhr": { - "version": "5.35.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.35.0.tgz", - "integrity": "sha512-diY415KLJZ6x1Kbwl9u96Jsz0OstE3asjXtJ9pmk1d+5gPuQ5jQyEsgC+WmEXzlec3iuVszm8AzNYYaqw6B+Zw==", - "requires": { - "@algolia/client-common": "5.35.0" - } - }, - "@algolia/requester-fetch": { - "version": "5.35.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-fetch/-/requester-fetch-5.35.0.tgz", - "integrity": "sha512-uydqnSmpAjrgo8bqhE9N1wgcB98psTRRQXcjc4izwMB7yRl9C8uuAQ/5YqRj04U0mMQ+fdu2fcNF6m9+Z1BzDQ==", - "requires": { - "@algolia/client-common": "5.35.0" - } - }, - "@algolia/requester-node-http": { - "version": "5.35.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.35.0.tgz", - "integrity": "sha512-RgLX78ojYOrThJHrIiPzT4HW3yfQa0D7K+MQ81rhxqaNyNBu4F1r+72LNHYH/Z+y9I1Mrjrd/c/Ue5zfDgAEjQ==", - "requires": { - "@algolia/client-common": "5.35.0" - } - }, - "@ampproject/remapping": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", - "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", - "requires": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "dependencies": { - "@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "requires": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - } - } - }, - "@angular-devkit/architect": { - "version": "0.2003.22", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.2003.22.tgz", - "integrity": "sha512-gxVOslVweD+Co6gpRVlByHus/3HVAnsl99MobS9PBh8vh2g6bJ011PBgl0TKsP/pqBGawZOkJXYrRPeMKnobYA==", - "requires": { - "@angular-devkit/core": "20.3.22", - "rxjs": "7.8.2" - }, - "dependencies": { - "@angular-devkit/core": { - "version": "20.3.22", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-20.3.22.tgz", - "integrity": "sha512-1vZnZTAjGcCM+86v2al+2eiROiSw0uAWeVllfHSQe0KsKOP1FE8UUUiWChhxVn7vIxypphlfGunkeeIn1C/ZFw==", - "requires": { - "ajv": "8.18.0", - "ajv-formats": "3.0.1", - "jsonc-parser": "3.3.1", - "picomatch": "4.0.4", - "rxjs": "7.8.2", - "source-map": "0.7.6" - } - }, - "ajv": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", - "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", - "requires": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - } - }, - "ajv-formats": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", - "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", - "requires": { - "ajv": "^8.0.0" - } - }, - "json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" - }, - "picomatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==" - }, - "source-map": { - "version": "0.7.6", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", - "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==" - } - } - }, - "@angular-devkit/build-angular": { - "version": "20.3.22", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-20.3.22.tgz", - "integrity": "sha512-PnKIRue/j30sWLWC9q2T3WwE5+GJekDX/zCXTYgjW6u0y/kt+7G/sR0uxXGkX2NwSVGnIz0ucVOBsbSl9PKd6A==", - "requires": { - "@ampproject/remapping": "2.3.0", - "@angular-devkit/architect": "0.2003.22", - "@angular-devkit/build-webpack": "0.2003.22", - "@angular-devkit/core": "20.3.22", - "@angular/build": "20.3.22", - "@babel/core": "7.28.3", - "@babel/generator": "7.28.3", - "@babel/helper-annotate-as-pure": "7.27.3", - "@babel/helper-split-export-declaration": "7.24.7", - "@babel/plugin-transform-async-generator-functions": "7.28.0", - "@babel/plugin-transform-async-to-generator": "7.27.1", - "@babel/plugin-transform-runtime": "7.28.3", - "@babel/preset-env": "7.28.3", - "@babel/runtime": "7.28.3", - "@discoveryjs/json-ext": "0.6.3", - "@ngtools/webpack": "20.3.22", - "ansi-colors": "4.1.3", - "autoprefixer": "10.4.21", - "babel-loader": "10.0.0", - "browserslist": "^4.21.5", - "copy-webpack-plugin": "14.0.0", - "css-loader": "7.1.2", - "esbuild": "0.25.9", - "esbuild-wasm": "0.25.9", - "fast-glob": "3.3.3", - "http-proxy-middleware": "3.0.5", - "istanbul-lib-instrument": "6.0.3", - "jsonc-parser": "3.3.1", - "karma-source-map-support": "1.4.0", - "less": "4.4.0", - "less-loader": "12.3.0", - "license-webpack-plugin": "4.0.2", - "loader-utils": "3.3.1", - "mini-css-extract-plugin": "2.9.4", - "open": "10.2.0", - "ora": "8.2.0", - "picomatch": "4.0.4", - "piscina": "5.1.3", - "postcss": "8.5.6", - "postcss-loader": "8.1.1", - "resolve-url-loader": "5.0.0", - "rxjs": "7.8.2", - "sass": "1.90.0", - "sass-loader": "16.0.5", - "semver": "7.7.2", - "source-map-loader": "5.0.0", - "source-map-support": "0.5.21", - "terser": "5.43.1", - "tree-kill": "1.2.2", - "tslib": "2.8.1", - "webpack": "5.105.0", - "webpack-dev-middleware": "7.4.2", - "webpack-dev-server": "5.2.2", - "webpack-merge": "6.0.1", - "webpack-subresource-integrity": "5.1.0" - }, - "dependencies": { - "@angular-devkit/core": { - "version": "20.3.22", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-20.3.22.tgz", - "integrity": "sha512-1vZnZTAjGcCM+86v2al+2eiROiSw0uAWeVllfHSQe0KsKOP1FE8UUUiWChhxVn7vIxypphlfGunkeeIn1C/ZFw==", - "requires": { - "ajv": "8.18.0", - "ajv-formats": "3.0.1", - "jsonc-parser": "3.3.1", - "picomatch": "4.0.4", - "rxjs": "7.8.2", - "source-map": "0.7.6" - } - }, - "ajv": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", - "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", - "requires": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - } - }, - "ajv-formats": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", - "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", - "requires": { - "ajv": "^8.0.0" - } - }, - "debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "requires": { - "ms": "^2.1.3" - } - }, - "http-proxy-middleware": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-3.0.5.tgz", - "integrity": "sha512-GLZZm1X38BPY4lkXA01jhwxvDoOkkXqjgVyUzVxiEK4iuRu03PZoYHhHRwxnfhQMDuaxi3vVri0YgSro/1oWqg==", - "requires": { - "@types/http-proxy": "^1.17.15", - "debug": "^4.3.6", - "http-proxy": "^1.18.1", - "is-glob": "^4.0.3", - "is-plain-object": "^5.0.0", - "micromatch": "^4.0.8" - } - }, - "is-plain-object": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==" - }, - "json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" - }, - "loader-utils": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.3.1.tgz", - "integrity": "sha512-FMJTLMXfCLMLfJxcX9PFqX5qD88Z5MRGaZCVzfuqeZSPsyiBzs+pahDQjbIWz2QIzPZz0NX9Zy4FX3lmK6YHIg==" - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "picomatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==" - }, - "semver": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", - "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==" - }, - "source-map": { - "version": "0.7.6", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", - "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==" - }, - "terser": { - "version": "5.43.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.43.1.tgz", - "integrity": "sha512-+6erLbBm0+LROX2sPXlUYx/ux5PyE9K/a92Wrt6oA+WDAoFTdpHE5tCYCI5PNzq2y8df4rA+QgHLJuR4jNymsg==", - "requires": { - "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.14.0", - "commander": "^2.20.0", - "source-map-support": "~0.5.20" - } - } - } - }, - "@angular-devkit/build-webpack": { - "version": "0.2003.22", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.2003.22.tgz", - "integrity": "sha512-ad4iW5CDGDYFXR9ZpdY8O2n4mx+tJtjx4mfC9Z+0ikwA4ir2IW2BOUhWvJ6IDq3f7kulFxP8S4zWN9r7jsZw3A==", - "requires": { - "@angular-devkit/architect": "0.2003.22", - "rxjs": "7.8.2" - } - }, - "@angular-devkit/schematics": { - "version": "20.3.22", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-20.3.22.tgz", - "integrity": "sha512-gN2XSXRn3eErGEJlH0iSfQZZ7NdxVZNdjSxuVEGBEFhe3cVeC21LzM3GTWW6xwtBb4pxHglFyc7BUFiYtZiYtg==", - "requires": { - "@angular-devkit/core": "20.3.22", - "jsonc-parser": "3.3.1", - "magic-string": "0.30.17", - "ora": "8.2.0", - "rxjs": "7.8.2" - }, - "dependencies": { - "@angular-devkit/core": { - "version": "20.3.22", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-20.3.22.tgz", - "integrity": "sha512-1vZnZTAjGcCM+86v2al+2eiROiSw0uAWeVllfHSQe0KsKOP1FE8UUUiWChhxVn7vIxypphlfGunkeeIn1C/ZFw==", - "requires": { - "ajv": "8.18.0", - "ajv-formats": "3.0.1", - "jsonc-parser": "3.3.1", - "picomatch": "4.0.4", - "rxjs": "7.8.2", - "source-map": "0.7.6" - } - }, - "ajv": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", - "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", - "requires": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - } - }, - "ajv-formats": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", - "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", - "requires": { - "ajv": "^8.0.0" - } - }, - "json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" - }, - "picomatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==" - }, - "source-map": { - "version": "0.7.6", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", - "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==" - } - } - }, - "@angular/animations": { - "version": "20.3.18", - "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-20.3.18.tgz", - "integrity": "sha512-XFxgSyjfs0SRD2vQVFJljmM4z9nTvUoI8TRqSre/+l8D2FgzD5pG67Aj2BgDgpSFAUkIcI37G48ijK7a3ZZ3WA==", - "requires": { - "tslib": "^2.3.0" - } - }, - "@angular/build": { - "version": "20.3.22", - "resolved": "https://registry.npmjs.org/@angular/build/-/build-20.3.22.tgz", - "integrity": "sha512-sxjVZU6AZHXyKRHJUMawXOj4qMf3vm8XK6wUejr01UKj6BqW2YWaQO26RpRJssXD2ITTqn6+UBwL7pEwe2a4Jg==", - "requires": { - "@ampproject/remapping": "2.3.0", - "@angular-devkit/architect": "0.2003.22", - "@babel/core": "7.28.3", - "@babel/helper-annotate-as-pure": "7.27.3", - "@babel/helper-split-export-declaration": "7.24.7", - "@inquirer/confirm": "5.1.14", - "@vitejs/plugin-basic-ssl": "2.1.0", - "beasties": "0.3.5", - "browserslist": "^4.23.0", - "esbuild": "0.25.9", - "https-proxy-agent": "7.0.6", - "istanbul-lib-instrument": "6.0.3", - "jsonc-parser": "3.3.1", - "listr2": "9.0.1", - "lmdb": "3.4.2", - "magic-string": "0.30.17", - "mrmime": "2.0.1", - "parse5-html-rewriting-stream": "8.0.0", - "picomatch": "4.0.4", - "piscina": "5.1.3", - "rollup": "4.59.0", - "sass": "1.90.0", - "semver": "7.7.2", - "source-map-support": "0.5.21", - "tinyglobby": "0.2.14", - "vite": "7.1.11", - "watchpack": "2.4.4" - }, - "dependencies": { - "ansi-escapes": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.3.0.tgz", - "integrity": "sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg==", - "requires": { - "environment": "^1.0.0" - } - }, - "ansi-regex": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", - "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==" - }, - "ansi-styles": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", - "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==" - }, - "cli-cursor": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", - "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", - "requires": { - "restore-cursor": "^5.0.0" - } - }, - "cli-truncate": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-4.0.0.tgz", - "integrity": "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==", - "requires": { - "slice-ansi": "^5.0.0", - "string-width": "^7.0.0" - } - }, - "emoji-regex": { - "version": "10.6.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", - "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==" - }, - "eventemitter3": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz", - "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==" - }, - "is-fullwidth-code-point": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", - "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==" - }, - "listr2": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-9.0.1.tgz", - "integrity": "sha512-SL0JY3DaxylDuo/MecFeiC+7pedM0zia33zl0vcjgwcq1q1FWWF1To9EIauPbl8GbMCU0R2e0uJ8bZunhYKD2g==", - "requires": { - "cli-truncate": "^4.0.0", - "colorette": "^2.0.20", - "eventemitter3": "^5.0.1", - "log-update": "^6.1.0", - "rfdc": "^1.4.1", - "wrap-ansi": "^9.0.0" - } - }, - "log-update": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.1.0.tgz", - "integrity": "sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==", - "requires": { - "ansi-escapes": "^7.0.0", - "cli-cursor": "^5.0.0", - "slice-ansi": "^7.1.0", - "strip-ansi": "^7.1.0", - "wrap-ansi": "^9.0.0" - }, - "dependencies": { - "is-fullwidth-code-point": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.1.0.tgz", - "integrity": "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==", - "requires": { - "get-east-asian-width": "^1.3.1" - } - }, - "slice-ansi": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.2.tgz", - "integrity": "sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w==", - "requires": { - "ansi-styles": "^6.2.1", - "is-fullwidth-code-point": "^5.0.0" - } - } - } - }, - "onetime": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", - "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", - "requires": { - "mimic-function": "^5.0.0" - } - }, - "picomatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==" - }, - "restore-cursor": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", - "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", - "requires": { - "onetime": "^7.0.0", - "signal-exit": "^4.1.0" - } - }, - "semver": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", - "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==" - }, - "signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==" - }, - "slice-ansi": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", - "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", - "requires": { - "ansi-styles": "^6.0.0", - "is-fullwidth-code-point": "^4.0.0" - } - }, - "string-width": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", - "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", - "requires": { - "emoji-regex": "^10.3.0", - "get-east-asian-width": "^1.0.0", - "strip-ansi": "^7.1.0" - } - }, - "strip-ansi": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", - "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", - "requires": { - "ansi-regex": "^6.2.2" - } - }, - "wrap-ansi": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", - "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", - "requires": { - "ansi-styles": "^6.2.1", - "string-width": "^7.0.0", - "strip-ansi": "^7.1.0" - } - } - } - }, - "@angular/cli": { - "version": "20.3.22", - "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-20.3.22.tgz", - "integrity": "sha512-0uyQPF0gGuzioWJKNyOzWSQrrC5GiidR+8gz1lODoJTnJZZdsP5n3nvccbcRmhy55B1WByHvQBE+6eDBbh06/g==", - "requires": { - "@angular-devkit/architect": "0.2003.22", - "@angular-devkit/core": "20.3.22", - "@angular-devkit/schematics": "20.3.22", - "@inquirer/prompts": "7.8.2", - "@listr2/prompt-adapter-inquirer": "3.0.1", - "@modelcontextprotocol/sdk": "1.26.0", - "@schematics/angular": "20.3.22", - "@yarnpkg/lockfile": "1.1.0", - "algoliasearch": "5.35.0", - "ini": "5.0.0", - "jsonc-parser": "3.3.1", - "listr2": "9.0.1", - "npm-package-arg": "13.0.0", - "pacote": "21.0.4", - "resolve": "1.22.10", - "semver": "7.7.2", - "yargs": "18.0.0", - "zod": "4.1.13" - }, - "dependencies": { - "@angular-devkit/core": { - "version": "20.3.22", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-20.3.22.tgz", - "integrity": "sha512-1vZnZTAjGcCM+86v2al+2eiROiSw0uAWeVllfHSQe0KsKOP1FE8UUUiWChhxVn7vIxypphlfGunkeeIn1C/ZFw==", - "requires": { - "ajv": "8.18.0", - "ajv-formats": "3.0.1", - "jsonc-parser": "3.3.1", - "picomatch": "4.0.4", - "rxjs": "7.8.2", - "source-map": "0.7.6" - } - }, - "@listr2/prompt-adapter-inquirer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@listr2/prompt-adapter-inquirer/-/prompt-adapter-inquirer-3.0.1.tgz", - "integrity": "sha512-3XFmGwm3u6ioREG+ynAQB7FoxfajgQnMhIu8wC5eo/Lsih4aKDg0VuIMGaOsYn7hJSJagSeaD4K8yfpkEoDEmA==", - "requires": { - "@inquirer/type": "^3.0.7" - } - }, - "ajv": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", - "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", - "requires": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - } - }, - "ajv-formats": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", - "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", - "requires": { - "ajv": "^8.0.0" - } - }, - "ansi-escapes": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.3.0.tgz", - "integrity": "sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg==", - "requires": { - "environment": "^1.0.0" - } - }, - "ansi-regex": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", - "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==" - }, - "ansi-styles": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", - "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==" - }, - "cli-cursor": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", - "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", - "requires": { - "restore-cursor": "^5.0.0" - } - }, - "cli-truncate": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-4.0.0.tgz", - "integrity": "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==", - "requires": { - "slice-ansi": "^5.0.0", - "string-width": "^7.0.0" - } - }, - "emoji-regex": { - "version": "10.6.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", - "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==" - }, - "eventemitter3": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz", - "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==" - }, - "is-fullwidth-code-point": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", - "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==" - }, - "json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" - }, - "listr2": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-9.0.1.tgz", - "integrity": "sha512-SL0JY3DaxylDuo/MecFeiC+7pedM0zia33zl0vcjgwcq1q1FWWF1To9EIauPbl8GbMCU0R2e0uJ8bZunhYKD2g==", - "requires": { - "cli-truncate": "^4.0.0", - "colorette": "^2.0.20", - "eventemitter3": "^5.0.1", - "log-update": "^6.1.0", - "rfdc": "^1.4.1", - "wrap-ansi": "^9.0.0" - } - }, - "log-update": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.1.0.tgz", - "integrity": "sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==", - "requires": { - "ansi-escapes": "^7.0.0", - "cli-cursor": "^5.0.0", - "slice-ansi": "^7.1.0", - "strip-ansi": "^7.1.0", - "wrap-ansi": "^9.0.0" - }, - "dependencies": { - "is-fullwidth-code-point": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.1.0.tgz", - "integrity": "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==", - "requires": { - "get-east-asian-width": "^1.3.1" - } - }, - "slice-ansi": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.2.tgz", - "integrity": "sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w==", - "requires": { - "ansi-styles": "^6.2.1", - "is-fullwidth-code-point": "^5.0.0" - } - } - } - }, - "onetime": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", - "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", - "requires": { - "mimic-function": "^5.0.0" - } - }, - "picomatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==" - }, - "restore-cursor": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", - "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", - "requires": { - "onetime": "^7.0.0", - "signal-exit": "^4.1.0" - } - }, - "semver": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", - "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==" - }, - "signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==" - }, - "slice-ansi": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", - "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", - "requires": { - "ansi-styles": "^6.0.0", - "is-fullwidth-code-point": "^4.0.0" - } - }, - "source-map": { - "version": "0.7.6", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", - "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==" - }, - "string-width": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", - "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", - "requires": { - "emoji-regex": "^10.3.0", - "get-east-asian-width": "^1.0.0", - "strip-ansi": "^7.1.0" - } - }, - "strip-ansi": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", - "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", - "requires": { - "ansi-regex": "^6.2.2" - } - }, - "wrap-ansi": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", - "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", - "requires": { - "ansi-styles": "^6.2.1", - "string-width": "^7.0.0", - "strip-ansi": "^7.1.0" - } - } - } - }, - "@angular/common": { - "version": "20.3.18", - "resolved": "https://registry.npmjs.org/@angular/common/-/common-20.3.18.tgz", - "integrity": "sha512-M62oQbSTRmnGavIVCwimoadg/PDWadgNhactMm9fgH0eM9rx+iWBAYJk4VufO0bwOhysFpRZpJgXlFjOifz/Jw==", - "requires": { - "tslib": "^2.3.0" - } - }, - "@angular/compiler": { - "version": "20.3.18", - "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-20.3.18.tgz", - "integrity": "sha512-AaP/LCiDNcYmF135EEozjyR04NRBT38ZfBHQwjhgwiBBTejmvcpHwJaHSkraLpZqZzE4BQqqmgiQ1EJqxEwLVA==", - "requires": { - "tslib": "^2.3.0" - } - }, - "@angular/compiler-cli": { - "version": "20.3.18", - "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-20.3.18.tgz", - "integrity": "sha512-zsoEgLgnblmRbi47YwMghKirJ8IBKJ3+I8TxLBRIBrhx+KHFp+6oeDeLyu9H+djdyk88zexVd09wzR/YK73F0g==", - "requires": { - "@babel/core": "7.28.3", - "@jridgewell/sourcemap-codec": "^1.4.14", - "chokidar": "^4.0.0", - "convert-source-map": "^1.5.1", - "reflect-metadata": "^0.2.0", - "semver": "^7.0.0", - "tslib": "^2.3.0", - "yargs": "^18.0.0" - }, - "dependencies": { - "chokidar": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", - "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", - "requires": { - "readdirp": "^4.0.1" - } - }, - "readdirp": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", - "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==" - } - } - }, - "@angular/core": { - "version": "20.3.18", - "resolved": "https://registry.npmjs.org/@angular/core/-/core-20.3.18.tgz", - "integrity": "sha512-B+NQQngd/aDbcfW0zGLis3wTLDeHTeTYMl/mGKQH+HwdPaRCKI1wEtaXaOYVJXkP2FeThocPevB8gLwNlPQUUw==", - "requires": { - "tslib": "^2.3.0" - } - }, - "@angular/forms": { - "version": "20.3.18", - "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-20.3.18.tgz", - "integrity": "sha512-x6/99LfxolyZIFUL3Wr0OrtuXHEDwEz/rwx+WzE7NL+n35yO40t3kp0Sn5uMFwI94i91QZJmXHltMpZhrVLuYg==", - "requires": { - "tslib": "^2.3.0" - } - }, - "@angular/language-service": { - "version": "20.3.18", - "resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-20.3.18.tgz", - "integrity": "sha512-V1ZBqeTtZYH9H8/G1qCw6gafsJmhMIMFjLX0Hv2KpTpmfK9nxIHPEVnshr3xT+qKYJIrMV/cU5YOzInEapLpuQ==", - "dev": true - }, - "@angular/localize": { - "version": "20.3.18", - "resolved": "https://registry.npmjs.org/@angular/localize/-/localize-20.3.18.tgz", - "integrity": "sha512-Zx7LiyMjTvooPhy/r6RoyWzGECfWiA8jH4zwsa/xPF6RX8MD/hOi8vcS4UxTdLSWB4lM5ZtSifAnOfwcm/0CyQ==", - "requires": { - "@babel/core": "7.28.3", - "@types/babel__core": "7.20.5", - "tinyglobby": "^0.2.12", - "yargs": "^18.0.0" - } - }, - "@angular/platform-browser": { - "version": "20.3.18", - "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-20.3.18.tgz", - "integrity": "sha512-q6s5rEN1yYazpHYp+k4pboXRzMsRB9auzTRBEhyXSGYxqzrnn3qHN0DqgsLC9WAdyhCgnIEMFA8kRT+W277DqQ==", - "requires": { - "tslib": "^2.3.0" - } - }, - "@angular/platform-browser-dynamic": { - "version": "20.3.18", - "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-20.3.18.tgz", - "integrity": "sha512-NyTobOGYVzGmPmtI+3lxMzxi0TbLq4SRNQ2ENEJAt6k2JnMmHBm483ppLRAM47nGlDdiraW0IX93EtYYNkiK3g==", - "requires": { - "tslib": "^2.3.0" - } - }, - "@angular/platform-server": { - "version": "20.3.18", - "resolved": "https://registry.npmjs.org/@angular/platform-server/-/platform-server-20.3.18.tgz", - "integrity": "sha512-iw4QSmEWEKbyMT5u8QdhalNiPqRc7cRuo6lulU75pjXqVLwLb3Gq8it+Vo+LSKY6qI/bMO7olS7iyw09wXJ0OQ==", - "requires": { - "tslib": "^2.3.0", - "xhr2": "^0.2.0" - } - }, - "@angular/router": { - "version": "20.3.18", - "resolved": "https://registry.npmjs.org/@angular/router/-/router-20.3.18.tgz", - "integrity": "sha512-3CWejsEYr+ze+ktvWN/qHdyq5WLrj96QZpGYJyxh1pchIcpMPE9MmLpdjf0CUrWYB7g/85u0Geq/xsz72JrGng==", - "requires": { - "tslib": "^2.3.0" - } - }, - "@angular/ssr": { - "version": "20.3.22", - "resolved": "https://registry.npmjs.org/@angular/ssr/-/ssr-20.3.22.tgz", - "integrity": "sha512-QwddgNmlFyLTzpAmEgUTzxYg6Q+c6Y2ztyVLpDfp+Xzi/FTmpIe5PXYxcjSRKdhcPwJe/qjYBSxDqq6whJ52GA==", - "requires": { - "tslib": "^2.3.0" - } - }, - "@asamuzakjp/css-color": { - "version": "6.0.7", - "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-6.0.7.tgz", - "integrity": "sha512-vC/bk1Lz7Tn/EfU9/apOTBk80/8dyGyWMowPoV1tJ52muDGsDqt2HPT2klrFUiY60MQmQv9q8yIht15JnBgDGw==", - "devOptional": true, - "requires": { - "@csstools/css-calc": "^3.3.0", - "@csstools/css-color-parser": "^4.1.10", - "@csstools/css-parser-algorithms": "^4.0.0", - "@csstools/css-tokenizer": "^4.0.0", - "lru-cache": "^11.5.2" - } - }, - "@asamuzakjp/dom-selector": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/@asamuzakjp/dom-selector/-/dom-selector-8.3.2.tgz", - "integrity": "sha512-93Z1N+BQNXysodoicpOIyNh2drHfz/CTf9nnT0FEx72GJcIiwgydD7tGAr78j41LsYn3hlRn+LdGPuBLn1Bl8Q==", - "devOptional": true, - "requires": { - "bidi-js": "^1.0.3", - "css-tree": "^3.2.1", - "is-potential-custom-element-name": "^1.0.1", - "lru-cache": "^11.5.2" - } - }, - "@babel/code-frame": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", - "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", - "requires": { - "@babel/helper-validator-identifier": "^7.27.1", - "js-tokens": "^4.0.0", - "picocolors": "^1.1.1" - } - }, - "@babel/compat-data": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.5.tgz", - "integrity": "sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==" - }, - "@babel/core": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.3.tgz", - "integrity": "sha512-yDBHV9kQNcr2/sUr9jghVyz9C3Y5G2zUM2H2lo+9mKv4sFgbA8s8Z9t8D1jiTkGoO/NoIfKMyKWr4s6CN23ZwQ==", - "requires": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.28.3", - "@babel/helper-compilation-targets": "^7.27.2", - "@babel/helper-module-transforms": "^7.28.3", - "@babel/helpers": "^7.28.3", - "@babel/parser": "^7.28.3", - "@babel/template": "^7.27.2", - "@babel/traverse": "^7.28.3", - "@babel/types": "^7.28.2", - "convert-source-map": "^2.0.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" - }, - "dependencies": { - "convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==" - }, - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" - } - } - }, - "@babel/generator": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.3.tgz", - "integrity": "sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw==", - "requires": { - "@babel/parser": "^7.28.3", - "@babel/types": "^7.28.2", - "@jridgewell/gen-mapping": "^0.3.12", - "@jridgewell/trace-mapping": "^0.3.28", - "jsesc": "^3.0.2" - }, - "dependencies": { - "@jridgewell/trace-mapping": { - "version": "0.3.31", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", - "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", - "requires": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - } - } - }, - "@babel/helper-annotate-as-pure": { - "version": "7.27.3", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz", - "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==", - "requires": { - "@babel/types": "^7.27.3" - } - }, - "@babel/helper-compilation-targets": { - "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", - "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", - "requires": { - "@babel/compat-data": "^7.27.2", - "@babel/helper-validator-option": "^7.27.1", - "browserslist": "^4.24.0", - "lru-cache": "^5.1.1", - "semver": "^6.3.1" - }, - "dependencies": { - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "requires": { - "yallist": "^3.0.2" - } - }, - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" - } - } - }, - "@babel/helper-create-class-features-plugin": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.28.5.tgz", - "integrity": "sha512-q3WC4JfdODypvxArsJQROfupPBq9+lMwjKq7C33GhbFYJsufD0yd/ziwD+hJucLeWsnFPWZjsU2DNFqBPE7jwQ==", - "requires": { - "@babel/helper-annotate-as-pure": "^7.27.3", - "@babel/helper-member-expression-to-functions": "^7.28.5", - "@babel/helper-optimise-call-expression": "^7.27.1", - "@babel/helper-replace-supers": "^7.27.1", - "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", - "@babel/traverse": "^7.28.5", - "semver": "^6.3.1" - }, - "dependencies": { - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" - } - } - }, - "@babel/helper-create-regexp-features-plugin": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.28.5.tgz", - "integrity": "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw==", - "requires": { - "@babel/helper-annotate-as-pure": "^7.27.3", - "regexpu-core": "^6.3.1", - "semver": "^6.3.1" - }, - "dependencies": { - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" - } - } - }, - "@babel/helper-define-polyfill-provider": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.5.tgz", - "integrity": "sha512-uJnGFcPsWQK8fvjgGP5LZUZZsYGIoPeRjSF5PGwrelYgq7Q15/Ft9NGFp1zglwgIv//W0uG4BevRuSJRyylZPg==", - "requires": { - "@babel/helper-compilation-targets": "^7.27.2", - "@babel/helper-plugin-utils": "^7.27.1", - "debug": "^4.4.1", - "lodash.debounce": "^4.0.8", - "resolve": "^1.22.10" - }, - "dependencies": { - "debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "requires": { - "ms": "^2.1.3" - } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - } - } - }, - "@babel/helper-globals": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", - "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==" - }, - "@babel/helper-member-expression-to-functions": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.28.5.tgz", - "integrity": "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==", - "requires": { - "@babel/traverse": "^7.28.5", - "@babel/types": "^7.28.5" - } - }, - "@babel/helper-module-imports": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", - "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", - "requires": { - "@babel/traverse": "^7.27.1", - "@babel/types": "^7.27.1" - } - }, - "@babel/helper-module-transforms": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz", - "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==", - "requires": { - "@babel/helper-module-imports": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1", - "@babel/traverse": "^7.28.3" - } - }, - "@babel/helper-optimise-call-expression": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz", - "integrity": "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==", - "requires": { - "@babel/types": "^7.27.1" - } - }, - "@babel/helper-plugin-utils": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", - "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==" - }, - "@babel/helper-remap-async-to-generator": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.27.1.tgz", - "integrity": "sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA==", - "requires": { - "@babel/helper-annotate-as-pure": "^7.27.1", - "@babel/helper-wrap-function": "^7.27.1", - "@babel/traverse": "^7.27.1" - } - }, - "@babel/helper-replace-supers": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.27.1.tgz", - "integrity": "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA==", - "requires": { - "@babel/helper-member-expression-to-functions": "^7.27.1", - "@babel/helper-optimise-call-expression": "^7.27.1", - "@babel/traverse": "^7.27.1" - } - }, - "@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.27.1.tgz", - "integrity": "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==", - "requires": { - "@babel/traverse": "^7.27.1", - "@babel/types": "^7.27.1" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", - "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", - "requires": { - "@babel/types": "^7.24.7" - } - }, - "@babel/helper-string-parser": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", - "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==" - }, - "@babel/helper-validator-identifier": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", - "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==" - }, - "@babel/helper-validator-option": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", - "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==" - }, - "@babel/helper-wrap-function": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.28.3.tgz", - "integrity": "sha512-zdf983tNfLZFletc0RRXYrHrucBEg95NIFMkn6K9dbeMYnsgHaSBGcQqdsCSStG2PYwRre0Qc2NNSCXbG+xc6g==", - "requires": { - "@babel/template": "^7.27.2", - "@babel/traverse": "^7.28.3", - "@babel/types": "^7.28.2" - } - }, - "@babel/helpers": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz", - "integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==", - "requires": { - "@babel/template": "^7.27.2", - "@babel/types": "^7.28.4" - } - }, - "@babel/parser": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz", - "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==", - "requires": { - "@babel/types": "^7.28.5" - } - }, - "@babel/plugin-bugfix-firefox-class-in-computed-class-key": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.28.5.tgz", - "integrity": "sha512-87GDMS3tsmMSi/3bWOte1UblL+YUTFMV8SZPZ2eSEL17s74Cw/l63rR6NmGVKMYW2GYi85nE+/d6Hw5N0bEk2Q==", - "requires": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/traverse": "^7.28.5" - } - }, - "@babel/plugin-bugfix-safari-class-field-initializer-scope": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.27.1.tgz", - "integrity": "sha512-qNeq3bCKnGgLkEXUuFry6dPlGfCdQNZbn7yUAPCInwAJHMU7THJfrBSozkcWq5sNM6RcF3S8XyQL2A52KNR9IA==", - "requires": { - "@babel/helper-plugin-utils": "^7.27.1" - } - }, - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.27.1.tgz", - "integrity": "sha512-g4L7OYun04N1WyqMNjldFwlfPCLVkgB54A/YCXICZYBsvJJE3kByKv9c9+R/nAfmIfjl2rKYLNyMHboYbZaWaA==", - "requires": { - "@babel/helper-plugin-utils": "^7.27.1" - } - }, - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.27.1.tgz", - "integrity": "sha512-oO02gcONcD5O1iTLi/6frMJBIwWEHceWGSGqrpCmEL8nogiS6J9PBlE48CaK20/Jx1LuRml9aDftLgdjXT8+Cw==", - "requires": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", - "@babel/plugin-transform-optional-chaining": "^7.27.1" - } - }, - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.28.3.tgz", - "integrity": "sha512-b6YTX108evsvE4YgWyQ921ZAFFQm3Bn+CA3+ZXlNVnPhx+UfsVURoPjfGAPCjBgrqo30yX/C2nZGX96DxvR9Iw==", - "requires": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/traverse": "^7.28.3" - } - }, - "@babel/plugin-proposal-private-property-in-object": { - "version": "7.21.0-placeholder-for-preset-env.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", - "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", - "requires": {} - }, - "@babel/plugin-syntax-import-assertions": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.27.1.tgz", - "integrity": "sha512-UT/Jrhw57xg4ILHLFnzFpPDlMbcdEicaAtjPQpbj9wa8T4r5KVWCimHcL/460g8Ht0DMxDyjsLgiWSkVjnwPFg==", - "requires": { - "@babel/helper-plugin-utils": "^7.27.1" - } - }, - "@babel/plugin-syntax-import-attributes": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.27.1.tgz", - "integrity": "sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==", - "requires": { - "@babel/helper-plugin-utils": "^7.27.1" - } - }, - "@babel/plugin-syntax-unicode-sets-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", - "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-transform-arrow-functions": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.27.1.tgz", - "integrity": "sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA==", - "requires": { - "@babel/helper-plugin-utils": "^7.27.1" - } - }, - "@babel/plugin-transform-async-generator-functions": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.28.0.tgz", - "integrity": "sha512-BEOdvX4+M765icNPZeidyADIvQ1m1gmunXufXxvRESy/jNNyfovIqUyE7MVgGBjWktCoJlzvFA1To2O4ymIO3Q==", - "requires": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-remap-async-to-generator": "^7.27.1", - "@babel/traverse": "^7.28.0" - } - }, - "@babel/plugin-transform-async-to-generator": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.27.1.tgz", - "integrity": "sha512-NREkZsZVJS4xmTr8qzE5y8AfIPqsdQfRuUiLRTEzb7Qii8iFWCyDKaUV2c0rCuh4ljDZ98ALHP/PetiBV2nddA==", - "requires": { - "@babel/helper-module-imports": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-remap-async-to-generator": "^7.27.1" - } - }, - "@babel/plugin-transform-block-scoped-functions": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.27.1.tgz", - "integrity": "sha512-cnqkuOtZLapWYZUYM5rVIdv1nXYuFVIltZ6ZJ7nIj585QsjKM5dhL2Fu/lICXZ1OyIAFc7Qy+bvDAtTXqGrlhg==", - "requires": { - "@babel/helper-plugin-utils": "^7.27.1" - } - }, - "@babel/plugin-transform-block-scoping": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.5.tgz", - "integrity": "sha512-45DmULpySVvmq9Pj3X9B+62Xe+DJGov27QravQJU1LLcapR6/10i+gYVAucGGJpHBp5mYxIMK4nDAT/QDLr47g==", - "requires": { - "@babel/helper-plugin-utils": "^7.27.1" - } - }, - "@babel/plugin-transform-class-properties": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.27.1.tgz", - "integrity": "sha512-D0VcalChDMtuRvJIu3U/fwWjf8ZMykz5iZsg77Nuj821vCKI3zCyRLwRdWbsuJ/uRwZhZ002QtCqIkwC/ZkvbA==", - "requires": { - "@babel/helper-create-class-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - } - }, - "@babel/plugin-transform-class-static-block": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.28.3.tgz", - "integrity": "sha512-LtPXlBbRoc4Njl/oh1CeD/3jC+atytbnf/UqLoqTDcEYGUPj022+rvfkbDYieUrSj3CaV4yHDByPE+T2HwfsJg==", - "requires": { - "@babel/helper-create-class-features-plugin": "^7.28.3", - "@babel/helper-plugin-utils": "^7.27.1" - } - }, - "@babel/plugin-transform-classes": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.4.tgz", - "integrity": "sha512-cFOlhIYPBv/iBoc+KS3M6et2XPtbT2HiCRfBXWtfpc9OAyostldxIf9YAYB6ypURBBbx+Qv6nyrLzASfJe+hBA==", - "requires": { - "@babel/helper-annotate-as-pure": "^7.27.3", - "@babel/helper-compilation-targets": "^7.27.2", - "@babel/helper-globals": "^7.28.0", - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-replace-supers": "^7.27.1", - "@babel/traverse": "^7.28.4" - } - }, - "@babel/plugin-transform-computed-properties": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.27.1.tgz", - "integrity": "sha512-lj9PGWvMTVksbWiDT2tW68zGS/cyo4AkZ/QTp0sQT0mjPopCmrSkzxeXkznjqBxzDI6TclZhOJbBmbBLjuOZUw==", - "requires": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/template": "^7.27.1" - } - }, - "@babel/plugin-transform-destructuring": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.28.5.tgz", - "integrity": "sha512-Kl9Bc6D0zTUcFUvkNuQh4eGXPKKNDOJQXVyyM4ZAQPMveniJdxi8XMJwLo+xSoW3MIq81bD33lcUe9kZpl0MCw==", - "requires": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/traverse": "^7.28.5" - } - }, - "@babel/plugin-transform-dotall-regex": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.27.1.tgz", - "integrity": "sha512-gEbkDVGRvjj7+T1ivxrfgygpT7GUd4vmODtYpbs0gZATdkX8/iSnOtZSxiZnsgm1YjTgjI6VKBGSJJevkrclzw==", - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - } - }, - "@babel/plugin-transform-duplicate-keys": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.27.1.tgz", - "integrity": "sha512-MTyJk98sHvSs+cvZ4nOauwTTG1JeonDjSGvGGUNHreGQns+Mpt6WX/dVzWBHgg+dYZhkC4X+zTDfkTU+Vy9y7Q==", - "requires": { - "@babel/helper-plugin-utils": "^7.27.1" - } - }, - "@babel/plugin-transform-duplicate-named-capturing-groups-regex": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.27.1.tgz", - "integrity": "sha512-hkGcueTEzuhB30B3eJCbCYeCaaEQOmQR0AdvzpD4LoN0GXMWzzGSuRrxR2xTnCrvNbVwK9N6/jQ92GSLfiZWoQ==", - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - } - }, - "@babel/plugin-transform-dynamic-import": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.27.1.tgz", - "integrity": "sha512-MHzkWQcEmjzzVW9j2q8LGjwGWpG2mjwaaB0BNQwst3FIjqsg8Ct/mIZlvSPJvfi9y2AC8mi/ktxbFVL9pZ1I4A==", - "requires": { - "@babel/helper-plugin-utils": "^7.27.1" - } - }, - "@babel/plugin-transform-explicit-resource-management": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-explicit-resource-management/-/plugin-transform-explicit-resource-management-7.28.0.tgz", - "integrity": "sha512-K8nhUcn3f6iB+P3gwCv/no7OdzOZQcKchW6N389V6PD8NUWKZHzndOd9sPDVbMoBsbmjMqlB4L9fm+fEFNVlwQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/plugin-transform-destructuring": "^7.28.0" - } - }, - "@babel/plugin-transform-exponentiation-operator": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.28.5.tgz", - "integrity": "sha512-D4WIMaFtwa2NizOp+dnoFjRez/ClKiC2BqqImwKd1X28nqBtZEyCYJ2ozQrrzlxAFrcrjxo39S6khe9RNDlGzw==", - "requires": { - "@babel/helper-plugin-utils": "^7.27.1" - } - }, - "@babel/plugin-transform-export-namespace-from": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.27.1.tgz", - "integrity": "sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.27.1" - } - }, - "@babel/plugin-transform-for-of": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.27.1.tgz", - "integrity": "sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw==", - "requires": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" - } - }, - "@babel/plugin-transform-function-name": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.27.1.tgz", - "integrity": "sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ==", - "requires": { - "@babel/helper-compilation-targets": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/traverse": "^7.27.1" - } - }, - "@babel/plugin-transform-json-strings": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.27.1.tgz", - "integrity": "sha512-6WVLVJiTjqcQauBhn1LkICsR2H+zm62I3h9faTDKt1qP4jn2o72tSvqMwtGFKGTpojce0gJs+76eZ2uCHRZh0Q==", - "requires": { - "@babel/helper-plugin-utils": "^7.27.1" - } - }, - "@babel/plugin-transform-literals": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.27.1.tgz", - "integrity": "sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA==", - "requires": { - "@babel/helper-plugin-utils": "^7.27.1" - } - }, - "@babel/plugin-transform-logical-assignment-operators": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.28.5.tgz", - "integrity": "sha512-axUuqnUTBuXyHGcJEVVh9pORaN6wC5bYfE7FGzPiaWa3syib9m7g+/IT/4VgCOe2Upef43PHzeAvcrVek6QuuA==", - "requires": { - "@babel/helper-plugin-utils": "^7.27.1" - } - }, - "@babel/plugin-transform-member-expression-literals": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.27.1.tgz", - "integrity": "sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.27.1" - } - }, - "@babel/plugin-transform-modules-amd": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.27.1.tgz", - "integrity": "sha512-iCsytMg/N9/oFq6n+gFTvUYDZQOMK5kEdeYxmxt91fcJGycfxVP9CnrxoliM0oumFERba2i8ZtwRUCMhvP1LnA==", - "requires": { - "@babel/helper-module-transforms": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - } - }, - "@babel/plugin-transform-modules-commonjs": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.27.1.tgz", - "integrity": "sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw==", - "requires": { - "@babel/helper-module-transforms": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - } - }, - "@babel/plugin-transform-modules-systemjs": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.28.5.tgz", - "integrity": "sha512-vn5Jma98LCOeBy/KpeQhXcV2WZgaRUtjwQmjoBuLNlOmkg0fB5pdvYVeWRYI69wWKwK2cD1QbMiUQnoujWvrew==", - "requires": { - "@babel/helper-module-transforms": "^7.28.3", - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-validator-identifier": "^7.28.5", - "@babel/traverse": "^7.28.5" - } - }, - "@babel/plugin-transform-modules-umd": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.27.1.tgz", - "integrity": "sha512-iQBE/xC5BV1OxJbp6WG7jq9IWiD+xxlZhLrdwpPkTX3ydmXdvoCpyfJN7acaIBZaOqTfr76pgzqBJflNbeRK+w==", - "requires": { - "@babel/helper-module-transforms": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - } - }, - "@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.27.1.tgz", - "integrity": "sha512-SstR5JYy8ddZvD6MhV0tM/j16Qds4mIpJTOd1Yu9J9pJjH93bxHECF7pgtc28XvkzTD6Pxcm/0Z73Hvk7kb3Ng==", - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - } - }, - "@babel/plugin-transform-new-target": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.27.1.tgz", - "integrity": "sha512-f6PiYeqXQ05lYq3TIfIDu/MtliKUbNwkGApPUvyo6+tc7uaR4cPjPe7DFPr15Uyycg2lZU6btZ575CuQoYh7MQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.27.1" - } - }, - "@babel/plugin-transform-nullish-coalescing-operator": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.27.1.tgz", - "integrity": "sha512-aGZh6xMo6q9vq1JGcw58lZ1Z0+i0xB2x0XaauNIUXd6O1xXc3RwoWEBlsTQrY4KQ9Jf0s5rgD6SiNkaUdJegTA==", - "requires": { - "@babel/helper-plugin-utils": "^7.27.1" - } - }, - "@babel/plugin-transform-numeric-separator": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.27.1.tgz", - "integrity": "sha512-fdPKAcujuvEChxDBJ5c+0BTaS6revLV7CJL08e4m3de8qJfNIuCc2nc7XJYOjBoTMJeqSmwXJ0ypE14RCjLwaw==", - "requires": { - "@babel/helper-plugin-utils": "^7.27.1" - } - }, - "@babel/plugin-transform-object-rest-spread": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.28.4.tgz", - "integrity": "sha512-373KA2HQzKhQCYiRVIRr+3MjpCObqzDlyrM6u4I201wL8Mp2wHf7uB8GhDwis03k2ti8Zr65Zyyqs1xOxUF/Ew==", - "requires": { - "@babel/helper-compilation-targets": "^7.27.2", - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/plugin-transform-destructuring": "^7.28.0", - "@babel/plugin-transform-parameters": "^7.27.7", - "@babel/traverse": "^7.28.4" - } - }, - "@babel/plugin-transform-object-super": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.27.1.tgz", - "integrity": "sha512-SFy8S9plRPbIcxlJ8A6mT/CxFdJx/c04JEctz4jf8YZaVS2px34j7NXRrlGlHkN/M2gnpL37ZpGRGVFLd3l8Ng==", - "requires": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-replace-supers": "^7.27.1" - } - }, - "@babel/plugin-transform-optional-catch-binding": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.27.1.tgz", - "integrity": "sha512-txEAEKzYrHEX4xSZN4kJ+OfKXFVSWKB2ZxM9dpcE3wT7smwkNmXo5ORRlVzMVdJbD+Q8ILTgSD7959uj+3Dm3Q==", - "requires": { - "@babel/helper-plugin-utils": "^7.27.1" - } - }, - "@babel/plugin-transform-optional-chaining": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.28.5.tgz", - "integrity": "sha512-N6fut9IZlPnjPwgiQkXNhb+cT8wQKFlJNqcZkWlcTqkcqx6/kU4ynGmLFoa4LViBSirn05YAwk+sQBbPfxtYzQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" - } - }, - "@babel/plugin-transform-parameters": { - "version": "7.27.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.27.7.tgz", - "integrity": "sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg==", - "requires": { - "@babel/helper-plugin-utils": "^7.27.1" - } - }, - "@babel/plugin-transform-private-methods": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.27.1.tgz", - "integrity": "sha512-10FVt+X55AjRAYI9BrdISN9/AQWHqldOeZDUoLyif1Kn05a56xVBXb8ZouL8pZ9jem8QpXaOt8TS7RHUIS+GPA==", - "requires": { - "@babel/helper-create-class-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - } - }, - "@babel/plugin-transform-private-property-in-object": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.27.1.tgz", - "integrity": "sha512-5J+IhqTi1XPa0DXF83jYOaARrX+41gOewWbkPyjMNRDqgOCqdffGh8L3f/Ek5utaEBZExjSAzcyjmV9SSAWObQ==", - "requires": { - "@babel/helper-annotate-as-pure": "^7.27.1", - "@babel/helper-create-class-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - } - }, - "@babel/plugin-transform-property-literals": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.27.1.tgz", - "integrity": "sha512-oThy3BCuCha8kDZ8ZkgOg2exvPYUlprMukKQXI1r1pJ47NCvxfkEy8vK+r/hT9nF0Aa4H1WUPZZjHTFtAhGfmQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.27.1" - } - }, - "@babel/plugin-transform-regenerator": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.28.4.tgz", - "integrity": "sha512-+ZEdQlBoRg9m2NnzvEeLgtvBMO4tkFBw5SQIUgLICgTrumLoU7lr+Oghi6km2PFj+dbUt2u1oby2w3BDO9YQnA==", - "requires": { - "@babel/helper-plugin-utils": "^7.27.1" - } - }, - "@babel/plugin-transform-regexp-modifiers": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.27.1.tgz", - "integrity": "sha512-TtEciroaiODtXvLZv4rmfMhkCv8jx3wgKpL68PuiPh2M4fvz5jhsA7697N1gMvkvr/JTF13DrFYyEbY9U7cVPA==", - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - } - }, - "@babel/plugin-transform-reserved-words": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.27.1.tgz", - "integrity": "sha512-V2ABPHIJX4kC7HegLkYoDpfg9PVmuWy/i6vUM5eGK22bx4YVFD3M5F0QQnWQoDs6AGsUWTVOopBiMFQgHaSkVw==", - "requires": { - "@babel/helper-plugin-utils": "^7.27.1" - } - }, - "@babel/plugin-transform-runtime": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.28.3.tgz", - "integrity": "sha512-Y6ab1kGqZ0u42Zv/4a7l0l72n9DKP/MKoKWaUSBylrhNZO2prYuqFOLbn5aW5SIFXwSH93yfjbgllL8lxuGKLg==", - "requires": { - "@babel/helper-module-imports": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1", - "babel-plugin-polyfill-corejs2": "^0.4.14", - "babel-plugin-polyfill-corejs3": "^0.13.0", - "babel-plugin-polyfill-regenerator": "^0.6.5", - "semver": "^6.3.1" - }, - "dependencies": { - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" - } - } - }, - "@babel/plugin-transform-shorthand-properties": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.27.1.tgz", - "integrity": "sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.27.1" - } - }, - "@babel/plugin-transform-spread": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.27.1.tgz", - "integrity": "sha512-kpb3HUqaILBJcRFVhFUs6Trdd4mkrzcGXss+6/mxUd273PfbWqSDHRzMT2234gIg2QYfAjvXLSquP1xECSg09Q==", - "requires": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" - } - }, - "@babel/plugin-transform-sticky-regex": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.27.1.tgz", - "integrity": "sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g==", - "requires": { - "@babel/helper-plugin-utils": "^7.27.1" - } - }, - "@babel/plugin-transform-template-literals": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.27.1.tgz", - "integrity": "sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg==", - "requires": { - "@babel/helper-plugin-utils": "^7.27.1" - } - }, - "@babel/plugin-transform-typeof-symbol": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.27.1.tgz", - "integrity": "sha512-RiSILC+nRJM7FY5srIyc4/fGIwUhyDuuBSdWn4y6yT6gm652DpCHZjIipgn6B7MQ1ITOUnAKWixEUjQRIBIcLw==", - "requires": { - "@babel/helper-plugin-utils": "^7.27.1" - } - }, - "@babel/plugin-transform-unicode-escapes": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.27.1.tgz", - "integrity": "sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg==", - "requires": { - "@babel/helper-plugin-utils": "^7.27.1" - } - }, - "@babel/plugin-transform-unicode-property-regex": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.27.1.tgz", - "integrity": "sha512-uW20S39PnaTImxp39O5qFlHLS9LJEmANjMG7SxIhap8rCHqu0Ik+tLEPX5DKmHn6CsWQ7j3lix2tFOa5YtL12Q==", - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - } - }, - "@babel/plugin-transform-unicode-regex": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.27.1.tgz", - "integrity": "sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw==", - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - } - }, - "@babel/plugin-transform-unicode-sets-regex": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.27.1.tgz", - "integrity": "sha512-EtkOujbc4cgvb0mlpQefi4NTPBzhSIevblFevACNLUspmrALgmEBdL/XfnyyITfd8fKBZrZys92zOWcik7j9Tw==", - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" - } - }, - "@babel/preset-env": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.28.3.tgz", - "integrity": "sha512-ROiDcM+GbYVPYBOeCR6uBXKkQpBExLl8k9HO1ygXEyds39j+vCCsjmj7S8GOniZQlEs81QlkdJZe76IpLSiqpg==", - "requires": { - "@babel/compat-data": "^7.28.0", - "@babel/helper-compilation-targets": "^7.27.2", - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-validator-option": "^7.27.1", - "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.27.1", - "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.27.1", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.27.1", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.27.1", - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.28.3", - "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", - "@babel/plugin-syntax-import-assertions": "^7.27.1", - "@babel/plugin-syntax-import-attributes": "^7.27.1", - "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", - "@babel/plugin-transform-arrow-functions": "^7.27.1", - "@babel/plugin-transform-async-generator-functions": "^7.28.0", - "@babel/plugin-transform-async-to-generator": "^7.27.1", - "@babel/plugin-transform-block-scoped-functions": "^7.27.1", - "@babel/plugin-transform-block-scoping": "^7.28.0", - "@babel/plugin-transform-class-properties": "^7.27.1", - "@babel/plugin-transform-class-static-block": "^7.28.3", - "@babel/plugin-transform-classes": "^7.28.3", - "@babel/plugin-transform-computed-properties": "^7.27.1", - "@babel/plugin-transform-destructuring": "^7.28.0", - "@babel/plugin-transform-dotall-regex": "^7.27.1", - "@babel/plugin-transform-duplicate-keys": "^7.27.1", - "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.27.1", - "@babel/plugin-transform-dynamic-import": "^7.27.1", - "@babel/plugin-transform-explicit-resource-management": "^7.28.0", - "@babel/plugin-transform-exponentiation-operator": "^7.27.1", - "@babel/plugin-transform-export-namespace-from": "^7.27.1", - "@babel/plugin-transform-for-of": "^7.27.1", - "@babel/plugin-transform-function-name": "^7.27.1", - "@babel/plugin-transform-json-strings": "^7.27.1", - "@babel/plugin-transform-literals": "^7.27.1", - "@babel/plugin-transform-logical-assignment-operators": "^7.27.1", - "@babel/plugin-transform-member-expression-literals": "^7.27.1", - "@babel/plugin-transform-modules-amd": "^7.27.1", - "@babel/plugin-transform-modules-commonjs": "^7.27.1", - "@babel/plugin-transform-modules-systemjs": "^7.27.1", - "@babel/plugin-transform-modules-umd": "^7.27.1", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.27.1", - "@babel/plugin-transform-new-target": "^7.27.1", - "@babel/plugin-transform-nullish-coalescing-operator": "^7.27.1", - "@babel/plugin-transform-numeric-separator": "^7.27.1", - "@babel/plugin-transform-object-rest-spread": "^7.28.0", - "@babel/plugin-transform-object-super": "^7.27.1", - "@babel/plugin-transform-optional-catch-binding": "^7.27.1", - "@babel/plugin-transform-optional-chaining": "^7.27.1", - "@babel/plugin-transform-parameters": "^7.27.7", - "@babel/plugin-transform-private-methods": "^7.27.1", - "@babel/plugin-transform-private-property-in-object": "^7.27.1", - "@babel/plugin-transform-property-literals": "^7.27.1", - "@babel/plugin-transform-regenerator": "^7.28.3", - "@babel/plugin-transform-regexp-modifiers": "^7.27.1", - "@babel/plugin-transform-reserved-words": "^7.27.1", - "@babel/plugin-transform-shorthand-properties": "^7.27.1", - "@babel/plugin-transform-spread": "^7.27.1", - "@babel/plugin-transform-sticky-regex": "^7.27.1", - "@babel/plugin-transform-template-literals": "^7.27.1", - "@babel/plugin-transform-typeof-symbol": "^7.27.1", - "@babel/plugin-transform-unicode-escapes": "^7.27.1", - "@babel/plugin-transform-unicode-property-regex": "^7.27.1", - "@babel/plugin-transform-unicode-regex": "^7.27.1", - "@babel/plugin-transform-unicode-sets-regex": "^7.27.1", - "@babel/preset-modules": "0.1.6-no-external-plugins", - "babel-plugin-polyfill-corejs2": "^0.4.14", - "babel-plugin-polyfill-corejs3": "^0.13.0", - "babel-plugin-polyfill-regenerator": "^0.6.5", - "core-js-compat": "^3.43.0", - "semver": "^6.3.1" - }, - "dependencies": { - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" - } - } - }, - "@babel/preset-modules": { - "version": "0.1.6-no-external-plugins", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", - "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/types": "^7.4.4", - "esutils": "^2.0.2" - } - }, - "@babel/runtime": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.3.tgz", - "integrity": "sha512-9uIQ10o0WGdpP6GDhXcdOJPJuDgFtIDtN/9+ArJQ2NAfAmiuhTQdzkaTGR33v43GYS2UrSA0eX2pPPHoFVvpxA==" - }, - "@babel/template": { - "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", - "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", - "requires": { - "@babel/code-frame": "^7.27.1", - "@babel/parser": "^7.27.2", - "@babel/types": "^7.27.1" - } - }, - "@babel/traverse": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.5.tgz", - "integrity": "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==", - "requires": { - "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.28.5", - "@babel/helper-globals": "^7.28.0", - "@babel/parser": "^7.28.5", - "@babel/template": "^7.27.2", - "@babel/types": "^7.28.5", - "debug": "^4.3.1" - }, - "dependencies": { - "@babel/generator": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.5.tgz", - "integrity": "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==", - "requires": { - "@babel/parser": "^7.28.5", - "@babel/types": "^7.28.5", - "@jridgewell/gen-mapping": "^0.3.12", - "@jridgewell/trace-mapping": "^0.3.28", - "jsesc": "^3.0.2" - } - }, - "@jridgewell/trace-mapping": { - "version": "0.3.31", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", - "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", - "requires": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - } - } - }, - "@babel/types": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz", - "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==", - "requires": { - "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.28.5" - } - }, - "@bramus/specificity": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/@bramus/specificity/-/specificity-2.4.2.tgz", - "integrity": "sha512-ctxtJ/eA+t+6q2++vj5j7FYX3nRu311q1wfYH3xjlLOsczhlhxAg2FWNUXhpGvAw3BWo1xBcvOV6/YLc2r5FJw==", - "devOptional": true, - "requires": { - "css-tree": "^3.0.0" - } - }, - "@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dev": true, - "requires": { - "@jridgewell/trace-mapping": "0.3.9" - } - }, - "@csstools/color-helpers": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-6.1.1.tgz", - "integrity": "sha512-gLNsunvwf3mCi5u5o46/Z/JcJMnhbHSaZ69rkgPzNM3J4s8hWwpPUQB6/tt0EDFyCiWzxANlx+2LJwpYj4zS1w==", - "devOptional": true - }, - "@csstools/css-calc": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-3.3.0.tgz", - "integrity": "sha512-c5ihYsPkdG6JCkU2zTMm4+k6r7RXuGxtWYhu5DHMIiF1FHzrfmHL5so11AoFpUv/tu61xfcmT4AmKoFfMPoqdQ==", - "devOptional": true, - "requires": {} - }, - "@csstools/css-color-parser": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-4.2.1.tgz", - "integrity": "sha512-YpAJZhaHplYQkG8ib+/Fx5Y0eF2lVWi3tIvMJA6i39TLyUNp2439cifzW8VMjhlqrBjHzK5hVGugRRm2zTKI/A==", - "devOptional": true, - "requires": { - "@csstools/color-helpers": "^6.1.1", - "@csstools/css-calc": "^3.3.0" - } - }, - "@csstools/css-parser-algorithms": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-4.0.0.tgz", - "integrity": "sha512-+B87qS7fIG3L5h3qwJ/IFbjoVoOe/bpOdh9hAjXbvx0o8ImEmUsGXN0inFOnk2ChCFgqkkGFQ+TpM5rbhkKe4w==", - "devOptional": true, - "requires": {} - }, - "@csstools/css-syntax-patches-for-csstree": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.1.9.tgz", - "integrity": "sha512-iGGw4OsAYsS6pD29MdJ2bX/nJx65a04ZZiw6x+VwWlP2DdXf6f++Zmuv/OzALpdyfVhjbduIIF2cXM7HWBIe9A==", - "devOptional": true, - "requires": {} - }, - "@csstools/css-tokenizer": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-4.0.0.tgz", - "integrity": "sha512-QxULHAm7cNu72w97JUNCBFODFaXpbDg+dP8b/oWFAZ2MTRppA3U00Y2L1HqaS4J6yBqxwa/Y3nMBaxVKbB/NsA==", - "devOptional": true - }, - "@cypress/request": { - "version": "3.0.10", - "resolved": "https://registry.npmjs.org/@cypress/request/-/request-3.0.10.tgz", - "integrity": "sha512-hauBrOdvu08vOsagkZ/Aju5XuiZx6ldsLfByg1htFeldhex+PeMrYauANzFsMJeAA0+dyPLbDoX2OYuvVoLDkQ==", - "optional": true, - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~4.0.4", - "http-signature": "~1.4.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "performance-now": "^2.1.0", - "qs": "~6.14.1", - "safe-buffer": "^5.1.2", - "tough-cookie": "^5.0.0", - "tunnel-agent": "^0.6.0", - "uuid": "^8.3.2" - } - }, - "@cypress/schematic": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/@cypress/schematic/-/schematic-2.5.0.tgz", - "integrity": "sha512-Yt/fQxYIHl9lU8LSoJL92nIwTVyYG5uP4VqW4taTn3viVWvssjK7sRtTI/LRxOoeMYX2RRlXQyUbFEikByn0cQ==", - "optional": true, - "requires": { - "jsonc-parser": "^3.0.0", - "rxjs": "~6.6.0" - }, - "dependencies": { - "rxjs": { - "version": "6.6.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", - "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", - "optional": true, - "requires": { - "tslib": "^1.9.0" - } - }, - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "optional": true - } - } - }, - "@cypress/xvfb": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@cypress/xvfb/-/xvfb-1.2.4.tgz", - "integrity": "sha512-skbBzPggOVYCbnGgV+0dmBdW/s77ZkAOXIC1knS8NagwDjBrNC1LuXtQJeiN6l+m7lzmHtaoUw/ctJKdqkG57Q==", - "optional": true, - "requires": { - "debug": "^3.1.0", - "lodash.once": "^4.1.1" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "optional": true, - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "@discoveryjs/json-ext": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.6.3.tgz", - "integrity": "sha512-4B4OijXeVNOPZlYA2oEwWOTkzyltLao+xbotHQeqN++Rv27Y6s818+n2Qkp8q+Fxhn0t/5lA5X1Mxktud8eayQ==" - }, - "@esbuild/aix-ppc64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.9.tgz", - "integrity": "sha512-OaGtL73Jck6pBKjNIe24BnFE6agGl+6KxDtTfHhy1HmhthfKouEcOhqpSL64K4/0WCtbKFLOdzD/44cJ4k9opA==", - "optional": true - }, - "@esbuild/android-arm": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.9.tgz", - "integrity": "sha512-5WNI1DaMtxQ7t7B6xa572XMXpHAaI/9Hnhk8lcxF4zVN4xstUgTlvuGDorBguKEnZO70qwEcLpfifMLoxiPqHQ==", - "optional": true - }, - "@esbuild/android-arm64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.9.tgz", - "integrity": "sha512-IDrddSmpSv51ftWslJMvl3Q2ZT98fUSL2/rlUXuVqRXHCs5EUF1/f+jbjF5+NG9UffUDMCiTyh8iec7u8RlTLg==", - "optional": true - }, - "@esbuild/android-x64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.9.tgz", - "integrity": "sha512-I853iMZ1hWZdNllhVZKm34f4wErd4lMyeV7BLzEExGEIZYsOzqDWDf+y082izYUE8gtJnYHdeDpN/6tUdwvfiw==", - "optional": true - }, - "@esbuild/darwin-arm64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.9.tgz", - "integrity": "sha512-XIpIDMAjOELi/9PB30vEbVMs3GV1v2zkkPnuyRRURbhqjyzIINwj+nbQATh4H9GxUgH1kFsEyQMxwiLFKUS6Rg==", - "optional": true - }, - "@esbuild/darwin-x64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.9.tgz", - "integrity": "sha512-jhHfBzjYTA1IQu8VyrjCX4ApJDnH+ez+IYVEoJHeqJm9VhG9Dh2BYaJritkYK3vMaXrf7Ogr/0MQ8/MeIefsPQ==", - "optional": true - }, - "@esbuild/freebsd-arm64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.9.tgz", - "integrity": "sha512-z93DmbnY6fX9+KdD4Ue/H6sYs+bhFQJNCPZsi4XWJoYblUqT06MQUdBCpcSfuiN72AbqeBFu5LVQTjfXDE2A6Q==", - "optional": true - }, - "@esbuild/freebsd-x64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.9.tgz", - "integrity": "sha512-mrKX6H/vOyo5v71YfXWJxLVxgy1kyt1MQaD8wZJgJfG4gq4DpQGpgTB74e5yBeQdyMTbgxp0YtNj7NuHN0PoZg==", - "optional": true - }, - "@esbuild/linux-arm": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.9.tgz", - "integrity": "sha512-HBU2Xv78SMgaydBmdor38lg8YDnFKSARg1Q6AT0/y2ezUAKiZvc211RDFHlEZRFNRVhcMamiToo7bDx3VEOYQw==", - "optional": true - }, - "@esbuild/linux-arm64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.9.tgz", - "integrity": "sha512-BlB7bIcLT3G26urh5Dmse7fiLmLXnRlopw4s8DalgZ8ef79Jj4aUcYbk90g8iCa2467HX8SAIidbL7gsqXHdRw==", - "optional": true - }, - "@esbuild/linux-ia32": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.9.tgz", - "integrity": "sha512-e7S3MOJPZGp2QW6AK6+Ly81rC7oOSerQ+P8L0ta4FhVi+/j/v2yZzx5CqqDaWjtPFfYz21Vi1S0auHrap3Ma3A==", - "optional": true - }, - "@esbuild/linux-loong64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.9.tgz", - "integrity": "sha512-Sbe10Bnn0oUAB2AalYztvGcK+o6YFFA/9829PhOCUS9vkJElXGdphz0A3DbMdP8gmKkqPmPcMJmJOrI3VYB1JQ==", - "optional": true - }, - "@esbuild/linux-mips64el": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.9.tgz", - "integrity": "sha512-YcM5br0mVyZw2jcQeLIkhWtKPeVfAerES5PvOzaDxVtIyZ2NUBZKNLjC5z3/fUlDgT6w89VsxP2qzNipOaaDyA==", - "optional": true - }, - "@esbuild/linux-ppc64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.9.tgz", - "integrity": "sha512-++0HQvasdo20JytyDpFvQtNrEsAgNG2CY1CLMwGXfFTKGBGQT3bOeLSYE2l1fYdvML5KUuwn9Z8L1EWe2tzs1w==", - "optional": true - }, - "@esbuild/linux-riscv64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.9.tgz", - "integrity": "sha512-uNIBa279Y3fkjV+2cUjx36xkx7eSjb8IvnL01eXUKXez/CBHNRw5ekCGMPM0BcmqBxBcdgUWuUXmVWwm4CH9kg==", - "optional": true - }, - "@esbuild/linux-s390x": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.9.tgz", - "integrity": "sha512-Mfiphvp3MjC/lctb+7D287Xw1DGzqJPb/J2aHHcHxflUo+8tmN/6d4k6I2yFR7BVo5/g7x2Monq4+Yew0EHRIA==", - "optional": true - }, - "@esbuild/linux-x64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.9.tgz", - "integrity": "sha512-iSwByxzRe48YVkmpbgoxVzn76BXjlYFXC7NvLYq+b+kDjyyk30J0JY47DIn8z1MO3K0oSl9fZoRmZPQI4Hklzg==", - "optional": true - }, - "@esbuild/netbsd-arm64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.9.tgz", - "integrity": "sha512-9jNJl6FqaUG+COdQMjSCGW4QiMHH88xWbvZ+kRVblZsWrkXlABuGdFJ1E9L7HK+T0Yqd4akKNa/lO0+jDxQD4Q==", - "optional": true - }, - "@esbuild/netbsd-x64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.9.tgz", - "integrity": "sha512-RLLdkflmqRG8KanPGOU7Rpg829ZHu8nFy5Pqdi9U01VYtG9Y0zOG6Vr2z4/S+/3zIyOxiK6cCeYNWOFR9QP87g==", - "optional": true - }, - "@esbuild/openbsd-arm64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.9.tgz", - "integrity": "sha512-YaFBlPGeDasft5IIM+CQAhJAqS3St3nJzDEgsgFixcfZeyGPCd6eJBWzke5piZuZ7CtL656eOSYKk4Ls2C0FRQ==", - "optional": true - }, - "@esbuild/openbsd-x64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.9.tgz", - "integrity": "sha512-1MkgTCuvMGWuqVtAvkpkXFmtL8XhWy+j4jaSO2wxfJtilVCi0ZE37b8uOdMItIHz4I6z1bWWtEX4CJwcKYLcuA==", - "optional": true - }, - "@esbuild/openharmony-arm64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.9.tgz", - "integrity": "sha512-4Xd0xNiMVXKh6Fa7HEJQbrpP3m3DDn43jKxMjxLLRjWnRsfxjORYJlXPO4JNcXtOyfajXorRKY9NkOpTHptErg==", - "optional": true - }, - "@esbuild/sunos-x64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.9.tgz", - "integrity": "sha512-WjH4s6hzo00nNezhp3wFIAfmGZ8U7KtrJNlFMRKxiI9mxEK1scOMAaa9i4crUtu+tBr+0IN6JCuAcSBJZfnphw==", - "optional": true - }, - "@esbuild/win32-arm64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.9.tgz", - "integrity": "sha512-mGFrVJHmZiRqmP8xFOc6b84/7xa5y5YvR1x8djzXpJBSv/UsNK6aqec+6JDjConTgvvQefdGhFDAs2DLAds6gQ==", - "optional": true - }, - "@esbuild/win32-ia32": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.9.tgz", - "integrity": "sha512-b33gLVU2k11nVx1OhX3C8QQP6UHQK4ZtN56oFWvVXvz2VkDoe6fbG8TOgHFxEvqeqohmRnIHe5A1+HADk4OQww==", - "optional": true - }, - "@esbuild/win32-x64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.9.tgz", - "integrity": "sha512-PPOl1mi6lpLNQxnGoyAfschAodRFYXJ+9fs6WHXz7CSWKbOqiMZsubC+BQsVKuul+3vKLuwTHsS2c2y9EoKwxQ==", - "optional": true - }, - "@eslint-community/eslint-utils": { - "version": "4.9.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz", - "integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^3.4.3" - } - }, - "@eslint-community/regexpp": { - "version": "4.12.2", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", - "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", - "dev": true - }, - "@eslint/config-array": { - "version": "0.21.1", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz", - "integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==", - "dev": true, - "requires": { - "@eslint/object-schema": "^2.1.7", - "debug": "^4.3.1", - "minimatch": "^3.1.2" - } - }, - "@eslint/config-helpers": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", - "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", - "dev": true, - "requires": { - "@eslint/core": "^0.17.0" - } - }, - "@eslint/core": { - "version": "0.17.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", - "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.15" - } - }, - "@eslint/eslintrc": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", - "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", - "dev": true, - "requires": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^10.0.1", - "globals": "^14.0.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "dependencies": { - "ignore": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", - "dev": true - } - } - }, - "@eslint/js": { - "version": "9.39.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.0.tgz", - "integrity": "sha512-BIhe0sW91JGPiaF1mOuPy5v8NflqfjIcDNpC+LbW9f609WVRX1rArrhi6Z2ymvrAry9jw+5POTj4t2t62o8Bmw==", - "dev": true - }, - "@eslint/object-schema": { - "version": "2.1.7", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", - "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", - "dev": true - }, - "@eslint/plugin-kit": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", - "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", - "dev": true, - "requires": { - "@eslint/core": "^0.17.0", - "levn": "^0.4.1" - } - }, - "@exodus/bytes": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/@exodus/bytes/-/bytes-1.15.1.tgz", - "integrity": "sha512-S6mL0yNB/Abt9Ei4tq8gDhcczc4S3+vQ4ra7vxnAf+YHC02srtqxKKZghx2Dq6p0e66THKwR6r8N6P95wEty7Q==", - "devOptional": true, - "requires": {} - }, - "@fortawesome/angular-fontawesome": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@fortawesome/angular-fontawesome/-/angular-fontawesome-3.0.0.tgz", - "integrity": "sha512-+8Dd6DoJnqArfrZ5NvjHyRL64IIkTigXclbOOcFdYQ8/WFERQUDaEU6SAV8Q0JBpJhMS1McED7YCOCAE6SIVyA==", - "requires": { - "@fortawesome/fontawesome-svg-core": "^7.0.0", - "tslib": "^2.8.1" - }, - "dependencies": { - "@fortawesome/fontawesome-common-types": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-7.1.0.tgz", - "integrity": "sha512-l/BQM7fYntsCI//du+6sEnHOP6a74UixFyOYUyz2DLMXKx+6DEhfR3F2NYGE45XH1JJuIamacb4IZs9S0ZOWLA==" - }, - "@fortawesome/fontawesome-svg-core": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-7.1.0.tgz", - "integrity": "sha512-fNxRUk1KhjSbnbuBxlWSnBLKLBNun52ZBTcs22H/xEEzM6Ap81ZFTQ4bZBxVQGQgVY0xugKGoRcCbaKjLQ3XZA==", - "requires": { - "@fortawesome/fontawesome-common-types": "7.1.0" - } - } - } - }, - "@fortawesome/fontawesome-common-types": { - "version": "6.7.2", - "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.7.2.tgz", - "integrity": "sha512-Zs+YeHUC5fkt7Mg1l6XTniei3k4bwG/yo3iFUtZWd/pMx9g3fdvkSK9E0FOC+++phXOka78uJcYb8JaFkW52Xg==" - }, - "@fortawesome/fontawesome-svg-core": { - "version": "6.7.2", - "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.7.2.tgz", - "integrity": "sha512-yxtOBWDrdi5DD5o1pmVdq3WMCvnobT0LU6R8RyyVXPvFRd2o79/0NCuQoCjNTeZz9EzA9xS3JxNWfv54RIHFEA==", - "requires": { - "@fortawesome/fontawesome-common-types": "6.7.2" - } - }, - "@fortawesome/free-solid-svg-icons": { - "version": "6.7.2", - "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.7.2.tgz", - "integrity": "sha512-GsBrnOzU8uj0LECDfD5zomZJIjrPhIlWU82AHwa2s40FKH+kcxQaBvBo3Z4TxyZHIyX8XTDxsyA33/Vx9eFuQA==", - "requires": { - "@fortawesome/fontawesome-common-types": "6.7.2" - } - }, - "@hapi/address": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@hapi/address/-/address-5.1.1.tgz", - "integrity": "sha512-A+po2d/dVoY7cYajycYI43ZbYMXukuopIsqCjh5QzsBCipDtdofHntljDlpccMjIfTy6UOkg+5KPriwYch2bXA==", - "optional": true, - "requires": { - "@hapi/hoek": "^11.0.2" - } - }, - "@hapi/formula": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@hapi/formula/-/formula-3.0.2.tgz", - "integrity": "sha512-hY5YPNXzw1He7s0iqkRQi+uMGh383CGdyyIGYtB+W5N3KHPXoqychklvHhKCC9M3Xtv0OCs/IHw+r4dcHtBYWw==", - "optional": true - }, - "@hapi/hoek": { - "version": "11.0.7", - "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-11.0.7.tgz", - "integrity": "sha512-HV5undWkKzcB4RZUusqOpcgxOaq6VOAH7zhhIr2g3G8NF/MlFO75SjOr2NfuSx0Mh40+1FqCkagKLJRykUWoFQ==", - "optional": true - }, - "@hapi/pinpoint": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@hapi/pinpoint/-/pinpoint-2.0.1.tgz", - "integrity": "sha512-EKQmr16tM8s16vTT3cA5L0kZZcTMU5DUOZTuvpnY738m+jyP3JIUj+Mm1xc1rsLkGBQ/gVnfKYPwOmPg1tUR4Q==", - "optional": true - }, - "@hapi/tlds": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@hapi/tlds/-/tlds-1.1.4.tgz", - "integrity": "sha512-Fq+20dxsxLaUn5jSSWrdtSRcIUba2JquuorF9UW1wIJS5cSUwxIsO2GIhaWynPRflvxSzFN+gxKte2HEW1OuoA==", - "optional": true - }, - "@hapi/topo": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-6.0.2.tgz", - "integrity": "sha512-KR3rD5inZbGMrHmgPxsJ9dbi6zEK+C3ZwUwTa+eMwWLz7oijWUTWD2pMSNNYJAU6Qq+65NkxXjqHr/7LM2Xkqg==", - "optional": true, - "requires": { - "@hapi/hoek": "^11.0.2" - } - }, - "@hono/node-server": { - "version": "1.19.11", - "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.11.tgz", - "integrity": "sha512-dr8/3zEaB+p0D2n/IUrlPF1HZm586qgJNXK1a9fhg/PzdtkK7Ksd5l312tJX2yBuALqDYBlG20QEbayqPyxn+g==", - "requires": {} - }, - "@humanfs/core": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", - "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", - "dev": true - }, - "@humanfs/node": { - "version": "0.16.7", - "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", - "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", - "dev": true, - "requires": { - "@humanfs/core": "^0.19.1", - "@humanwhocodes/retry": "^0.4.0" - } - }, - "@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true - }, - "@humanwhocodes/retry": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", - "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", - "dev": true - }, - "@inquirer/ansi": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@inquirer/ansi/-/ansi-1.0.1.tgz", - "integrity": "sha512-yqq0aJW/5XPhi5xOAL1xRCpe1eh8UFVgYFpFsjEqmIR8rKLyP+HINvFXwUaxYICflJrVlxnp7lLN6As735kVpw==" - }, - "@inquirer/checkbox": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-4.3.0.tgz", - "integrity": "sha512-5+Q3PKH35YsnoPTh75LucALdAxom6xh5D1oeY561x4cqBuH24ZFVyFREPe14xgnrtmGu3EEt1dIi60wRVSnGCw==", - "requires": { - "@inquirer/ansi": "^1.0.1", - "@inquirer/core": "^10.3.0", - "@inquirer/figures": "^1.0.14", - "@inquirer/type": "^3.0.9", - "yoctocolors-cjs": "^2.1.2" - } - }, - "@inquirer/confirm": { - "version": "5.1.14", - "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-5.1.14.tgz", - "integrity": "sha512-5yR4IBfe0kXe59r1YCTG8WXkUbl7Z35HK87Sw+WUyGD8wNUx7JvY7laahzeytyE1oLn74bQnL7hstctQxisQ8Q==", - "requires": { - "@inquirer/core": "^10.1.15", - "@inquirer/type": "^3.0.8" - } - }, - "@inquirer/core": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.3.0.tgz", - "integrity": "sha512-Uv2aPPPSK5jeCplQmQ9xadnFx2Zhj9b5Dj7bU6ZeCdDNNY11nhYy4btcSdtDguHqCT2h5oNeQTcUNSGGLA7NTA==", - "requires": { - "@inquirer/ansi": "^1.0.1", - "@inquirer/figures": "^1.0.14", - "@inquirer/type": "^3.0.9", - "cli-width": "^4.1.0", - "mute-stream": "^2.0.0", - "signal-exit": "^4.1.0", - "wrap-ansi": "^6.2.0", - "yoctocolors-cjs": "^2.1.2" - }, - "dependencies": { - "signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==" - } - } - }, - "@inquirer/editor": { - "version": "4.2.21", - "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-4.2.21.tgz", - "integrity": "sha512-MjtjOGjr0Kh4BciaFShYpZ1s9400idOdvQ5D7u7lE6VztPFoyLcVNE5dXBmEEIQq5zi4B9h2kU+q7AVBxJMAkQ==", - "requires": { - "@inquirer/core": "^10.3.0", - "@inquirer/external-editor": "^1.0.2", - "@inquirer/type": "^3.0.9" - } - }, - "@inquirer/expand": { - "version": "4.0.21", - "resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-4.0.21.tgz", - "integrity": "sha512-+mScLhIcbPFmuvU3tAGBed78XvYHSvCl6dBiYMlzCLhpr0bzGzd8tfivMMeqND6XZiaZ1tgusbUHJEfc6YzOdA==", - "requires": { - "@inquirer/core": "^10.3.0", - "@inquirer/type": "^3.0.9", - "yoctocolors-cjs": "^2.1.2" - } - }, - "@inquirer/external-editor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@inquirer/external-editor/-/external-editor-1.0.2.tgz", - "integrity": "sha512-yy9cOoBnx58TlsPrIxauKIFQTiyH+0MK4e97y4sV9ERbI+zDxw7i2hxHLCIEGIE/8PPvDxGhgzIOTSOWcs6/MQ==", - "requires": { - "chardet": "^2.1.0", - "iconv-lite": "^0.7.0" - }, - "dependencies": { - "iconv-lite": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.0.tgz", - "integrity": "sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==", - "requires": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - } - } - } - }, - "@inquirer/figures": { - "version": "1.0.14", - "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.14.tgz", - "integrity": "sha512-DbFgdt+9/OZYFM+19dbpXOSeAstPy884FPy1KjDu4anWwymZeOYhMY1mdFri172htv6mvc/uvIAAi7b7tvjJBQ==" - }, - "@inquirer/input": { - "version": "4.2.5", - "resolved": "https://registry.npmjs.org/@inquirer/input/-/input-4.2.5.tgz", - "integrity": "sha512-7GoWev7P6s7t0oJbenH0eQ0ThNdDJbEAEtVt9vsrYZ9FulIokvd823yLyhQlWHJPGce1wzP53ttfdCZmonMHyA==", - "requires": { - "@inquirer/core": "^10.3.0", - "@inquirer/type": "^3.0.9" - } - }, - "@inquirer/number": { - "version": "3.0.21", - "resolved": "https://registry.npmjs.org/@inquirer/number/-/number-3.0.21.tgz", - "integrity": "sha512-5QWs0KGaNMlhbdhOSCFfKsW+/dcAVC2g4wT/z2MCiZM47uLgatC5N20kpkDQf7dHx+XFct/MJvvNGy6aYJn4Pw==", - "requires": { - "@inquirer/core": "^10.3.0", - "@inquirer/type": "^3.0.9" - } - }, - "@inquirer/password": { - "version": "4.0.21", - "resolved": "https://registry.npmjs.org/@inquirer/password/-/password-4.0.21.tgz", - "integrity": "sha512-xxeW1V5SbNFNig2pLfetsDb0svWlKuhmr7MPJZMYuDnCTkpVBI+X/doudg4pznc1/U+yYmWFFOi4hNvGgUo7EA==", - "requires": { - "@inquirer/ansi": "^1.0.1", - "@inquirer/core": "^10.3.0", - "@inquirer/type": "^3.0.9" - } - }, - "@inquirer/prompts": { - "version": "7.8.2", - "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-7.8.2.tgz", - "integrity": "sha512-nqhDw2ZcAUrKNPwhjinJny903bRhI0rQhiDz1LksjeRxqa36i3l75+4iXbOy0rlDpLJGxqtgoPavQjmmyS5UJw==", - "requires": { - "@inquirer/checkbox": "^4.2.1", - "@inquirer/confirm": "^5.1.14", - "@inquirer/editor": "^4.2.17", - "@inquirer/expand": "^4.0.17", - "@inquirer/input": "^4.2.1", - "@inquirer/number": "^3.0.17", - "@inquirer/password": "^4.0.17", - "@inquirer/rawlist": "^4.1.5", - "@inquirer/search": "^3.1.0", - "@inquirer/select": "^4.3.1" - } - }, - "@inquirer/rawlist": { - "version": "4.1.9", - "resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-4.1.9.tgz", - "integrity": "sha512-AWpxB7MuJrRiSfTKGJ7Y68imYt8P9N3Gaa7ySdkFj1iWjr6WfbGAhdZvw/UnhFXTHITJzxGUI9k8IX7akAEBCg==", - "requires": { - "@inquirer/core": "^10.3.0", - "@inquirer/type": "^3.0.9", - "yoctocolors-cjs": "^2.1.2" - } - }, - "@inquirer/search": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@inquirer/search/-/search-3.2.0.tgz", - "integrity": "sha512-a5SzB/qrXafDX1Z4AZW3CsVoiNxcIYCzYP7r9RzrfMpaLpB+yWi5U8BWagZyLmwR0pKbbL5umnGRd0RzGVI8bQ==", - "requires": { - "@inquirer/core": "^10.3.0", - "@inquirer/figures": "^1.0.14", - "@inquirer/type": "^3.0.9", - "yoctocolors-cjs": "^2.1.2" - } - }, - "@inquirer/select": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-4.4.0.tgz", - "integrity": "sha512-kaC3FHsJZvVyIjYBs5Ih8y8Bj4P/QItQWrZW22WJax7zTN+ZPXVGuOM55vzbdCP9zKUiBd9iEJVdesujfF+cAA==", - "requires": { - "@inquirer/ansi": "^1.0.1", - "@inquirer/core": "^10.3.0", - "@inquirer/figures": "^1.0.14", - "@inquirer/type": "^3.0.9", - "yoctocolors-cjs": "^2.1.2" - } - }, - "@inquirer/type": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.9.tgz", - "integrity": "sha512-QPaNt/nmE2bLGQa9b7wwyRJoLZ7pN6rcyXvzU0YCmivmJyq1BVo94G98tStRWkoD1RgDX5C+dPlhhHzNdu/W/w==", - "requires": {} - }, - "@isaacs/fs-minipass": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", - "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", - "requires": { - "minipass": "^7.0.4" - } - }, - "@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==" - }, - "@jridgewell/gen-mapping": { - "version": "0.3.13", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", - "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", - "requires": { - "@jridgewell/sourcemap-codec": "^1.5.0", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "dependencies": { - "@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "requires": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - } - } - }, - "@jridgewell/resolve-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", - "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==" - }, - "@jridgewell/source-map": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", - "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", - "requires": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" - } - }, - "@jridgewell/sourcemap-codec": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", - "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==" - }, - "@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "requires": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, - "@jsonjoy.com/base64": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-q6XAnWQDIMA3+FTiOYajoYqySkO+JSat0ytXGSuRdq9uXE7o92gzuQwQM14xaCRlBLGq3v5miDGC4vkVTn54xA==", - "requires": {} - }, - "@jsonjoy.com/buffers": { - "version": "17.67.0", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/buffers/-/buffers-17.67.0.tgz", - "integrity": "sha512-tfExRpYxBvi32vPs9ZHaTjSP4fHAfzSmcahOfNxtvGHcyJel+aibkPlGeBB+7AoC6hL7lXIE++8okecBxx7lcw==", - "requires": {} - }, - "@jsonjoy.com/codegen": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/codegen/-/codegen-1.0.0.tgz", - "integrity": "sha512-E8Oy+08cmCf0EK/NMxpaJZmOxPqM+6iSe2S4nlSBrPZOORoDJILxtbSUEDKQyTamm/BVAhIGllOBNU79/dwf0g==", - "requires": {} - }, - "@jsonjoy.com/fs-core": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-core/-/fs-core-4.57.1.tgz", - "integrity": "sha512-YrEi/ZPmgc+GfdO0esBF04qv8boK9Dg9WpRQw/+vM8Qt3nnVIJWIa8HwZ/LXVZ0DB11XUROM8El/7yYTJX+WtA==", - "requires": { - "@jsonjoy.com/fs-node-builtins": "4.57.1", - "@jsonjoy.com/fs-node-utils": "4.57.1", - "thingies": "^2.5.0" - } - }, - "@jsonjoy.com/fs-fsa": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-fsa/-/fs-fsa-4.57.1.tgz", - "integrity": "sha512-ooEPvSW/HQDivPDPZMibHGKZf/QS4WRir1czGZmXmp3MsQqLECZEpN0JobrD8iV9BzsuwdIv+PxtWX9WpPLsIA==", - "requires": { - "@jsonjoy.com/fs-core": "4.57.1", - "@jsonjoy.com/fs-node-builtins": "4.57.1", - "@jsonjoy.com/fs-node-utils": "4.57.1", - "thingies": "^2.5.0" - } - }, - "@jsonjoy.com/fs-node": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node/-/fs-node-4.57.1.tgz", - "integrity": "sha512-3YaKhP8gXEKN+2O49GLNfNb5l2gbnCFHyAaybbA2JkkbQP3dpdef7WcUaHAulg/c5Dg4VncHsA3NWAUSZMR5KQ==", - "requires": { - "@jsonjoy.com/fs-core": "4.57.1", - "@jsonjoy.com/fs-node-builtins": "4.57.1", - "@jsonjoy.com/fs-node-utils": "4.57.1", - "@jsonjoy.com/fs-print": "4.57.1", - "@jsonjoy.com/fs-snapshot": "4.57.1", - "glob-to-regex.js": "^1.0.0", - "thingies": "^2.5.0" - } - }, - "@jsonjoy.com/fs-node-builtins": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node-builtins/-/fs-node-builtins-4.57.1.tgz", - "integrity": "sha512-XHkFKQ5GSH3uxm8c3ZYXVrexGdscpWKIcMWKFQpMpMJc8gA3AwOMBJXJlgpdJqmrhPyQXxaY9nbkNeYpacC0Og==", - "requires": {} - }, - "@jsonjoy.com/fs-node-to-fsa": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node-to-fsa/-/fs-node-to-fsa-4.57.1.tgz", - "integrity": "sha512-pqGHyWWzNck4jRfaGV39hkqpY5QjRUQ/nRbNT7FYbBa0xf4bDG+TE1Gt2KWZrSkrkZZDE3qZUjYMbjwSliX6pg==", - "requires": { - "@jsonjoy.com/fs-fsa": "4.57.1", - "@jsonjoy.com/fs-node-builtins": "4.57.1", - "@jsonjoy.com/fs-node-utils": "4.57.1" - } - }, - "@jsonjoy.com/fs-node-utils": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node-utils/-/fs-node-utils-4.57.1.tgz", - "integrity": "sha512-vp+7ZzIB8v43G+GLXTS4oDUSQmhAsRz532QmmWBbdYA20s465JvwhkSFvX9cVTqRRAQg+vZ7zWDaIEh0lFe2gw==", - "requires": { - "@jsonjoy.com/fs-node-builtins": "4.57.1" - } - }, - "@jsonjoy.com/fs-print": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-print/-/fs-print-4.57.1.tgz", - "integrity": "sha512-Ynct7ZJmfk6qoXDOKfpovNA36ITUx8rChLmRQtW08J73VOiuNsU8PB6d/Xs7fxJC2ohWR3a5AqyjmLojfrw5yw==", - "requires": { - "@jsonjoy.com/fs-node-utils": "4.57.1", - "tree-dump": "^1.1.0" - } - }, - "@jsonjoy.com/fs-snapshot": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-snapshot/-/fs-snapshot-4.57.1.tgz", - "integrity": "sha512-/oG8xBNFMbDXTq9J7vepSA1kerS5vpgd3p5QZSPd+nX59uwodGJftI51gDYyHRpP57P3WCQf7LHtBYPqwUg2Bg==", - "requires": { - "@jsonjoy.com/buffers": "^17.65.0", - "@jsonjoy.com/fs-node-utils": "4.57.1", - "@jsonjoy.com/json-pack": "^17.65.0", - "@jsonjoy.com/util": "^17.65.0" - }, - "dependencies": { - "@jsonjoy.com/base64": { - "version": "17.67.0", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/base64/-/base64-17.67.0.tgz", - "integrity": "sha512-5SEsJGsm15aP8TQGkDfJvz9axgPwAEm98S5DxOuYe8e1EbfajcDmgeXXzccEjh+mLnjqEKrkBdjHWS5vFNwDdw==", - "requires": {} - }, - "@jsonjoy.com/codegen": { - "version": "17.67.0", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/codegen/-/codegen-17.67.0.tgz", - "integrity": "sha512-idnkUplROpdBOV0HMcwhsCUS5TRUi9poagdGs70A6S4ux9+/aPuKbh8+UYRTLYQHtXvAdNfQWXDqZEx5k4Dj2Q==", - "requires": {} - }, - "@jsonjoy.com/json-pack": { - "version": "17.67.0", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-17.67.0.tgz", - "integrity": "sha512-t0ejURcGaZsn1ClbJ/3kFqSOjlryd92eQY465IYrezsXmPcfHPE/av4twRSxf6WE+TkZgLY+71vCZbiIiFKA/w==", - "requires": { - "@jsonjoy.com/base64": "17.67.0", - "@jsonjoy.com/buffers": "17.67.0", - "@jsonjoy.com/codegen": "17.67.0", - "@jsonjoy.com/json-pointer": "17.67.0", - "@jsonjoy.com/util": "17.67.0", - "hyperdyperid": "^1.2.0", - "thingies": "^2.5.0", - "tree-dump": "^1.1.0" - } - }, - "@jsonjoy.com/json-pointer": { - "version": "17.67.0", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pointer/-/json-pointer-17.67.0.tgz", - "integrity": "sha512-+iqOFInH+QZGmSuaybBUNdh7yvNrXvqR+h3wjXm0N/3JK1EyyFAeGJvqnmQL61d1ARLlk/wJdFKSL+LHJ1eaUA==", - "requires": { - "@jsonjoy.com/util": "17.67.0" - } - }, - "@jsonjoy.com/util": { - "version": "17.67.0", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-17.67.0.tgz", - "integrity": "sha512-6+8xBaz1rLSohlGh68D1pdw3AwDi9xydm8QNlAFkvnavCJYSze+pxoW2VKP8p308jtlMRLs5NTHfPlZLd4w7ew==", - "requires": { - "@jsonjoy.com/buffers": "17.67.0", - "@jsonjoy.com/codegen": "17.67.0" - } - } - } - }, - "@jsonjoy.com/json-pack": { - "version": "1.21.0", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-1.21.0.tgz", - "integrity": "sha512-+AKG+R2cfZMShzrF2uQw34v3zbeDYUqnQ+jg7ORic3BGtfw9p/+N6RJbq/kkV8JmYZaINknaEQ2m0/f693ZPpg==", - "requires": { - "@jsonjoy.com/base64": "^1.1.2", - "@jsonjoy.com/buffers": "^1.2.0", - "@jsonjoy.com/codegen": "^1.0.0", - "@jsonjoy.com/json-pointer": "^1.0.2", - "@jsonjoy.com/util": "^1.9.0", - "hyperdyperid": "^1.2.0", - "thingies": "^2.5.0", - "tree-dump": "^1.1.0" - }, - "dependencies": { - "@jsonjoy.com/buffers": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/buffers/-/buffers-1.2.1.tgz", - "integrity": "sha512-12cdlDwX4RUM3QxmUbVJWqZ/mrK6dFQH4Zxq6+r1YXKXYBNgZXndx2qbCJwh3+WWkCSn67IjnlG3XYTvmvYtgA==", - "requires": {} - } - } - }, - "@jsonjoy.com/json-pointer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pointer/-/json-pointer-1.0.2.tgz", - "integrity": "sha512-Fsn6wM2zlDzY1U+v4Nc8bo3bVqgfNTGcn6dMgs6FjrEnt4ZCe60o6ByKRjOGlI2gow0aE/Q41QOigdTqkyK5fg==", - "requires": { - "@jsonjoy.com/codegen": "^1.0.0", - "@jsonjoy.com/util": "^1.9.0" - } - }, - "@jsonjoy.com/util": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-1.9.0.tgz", - "integrity": "sha512-pLuQo+VPRnN8hfPqUTLTHk126wuYdXVxE6aDmjSeV4NCAgyxWbiOIeNJVtID3h1Vzpoi9m4jXezf73I6LgabgQ==", - "requires": { - "@jsonjoy.com/buffers": "^1.0.0", - "@jsonjoy.com/codegen": "^1.0.0" - }, - "dependencies": { - "@jsonjoy.com/buffers": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/buffers/-/buffers-1.2.1.tgz", - "integrity": "sha512-12cdlDwX4RUM3QxmUbVJWqZ/mrK6dFQH4Zxq6+r1YXKXYBNgZXndx2qbCJwh3+WWkCSn67IjnlG3XYTvmvYtgA==", - "requires": {} - } - } - }, - "@leichtgewicht/ip-codec": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz", - "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==" - }, - "@lmdb/lmdb-darwin-arm64": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-arm64/-/lmdb-darwin-arm64-3.4.2.tgz", - "integrity": "sha512-NK80WwDoODyPaSazKbzd3NEJ3ygePrkERilZshxBViBARNz21rmediktGHExoj9n5t9+ChlgLlxecdFKLCuCKg==", - "optional": true - }, - "@lmdb/lmdb-darwin-x64": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-x64/-/lmdb-darwin-x64-3.4.2.tgz", - "integrity": "sha512-zevaowQNmrp3U7Fz1s9pls5aIgpKRsKb3dZWDINtLiozh3jZI9fBrI19lYYBxqdyiIyNdlyiidPnwPShj4aK+w==", - "optional": true - }, - "@lmdb/lmdb-linux-arm": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm/-/lmdb-linux-arm-3.4.2.tgz", - "integrity": "sha512-OmHCULY17rkx/RoCoXlzU7LyR8xqrksgdYWwtYa14l/sseezZ8seKWXcogHcjulBddER5NnEFV4L/Jtr2nyxeg==", - "optional": true - }, - "@lmdb/lmdb-linux-arm64": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm64/-/lmdb-linux-arm64-3.4.2.tgz", - "integrity": "sha512-ZBEfbNZdkneebvZs98Lq30jMY8V9IJzckVeigGivV7nTHJc+89Ctomp1kAIWKlwIG0ovCDrFI448GzFPORANYg==", - "optional": true - }, - "@lmdb/lmdb-linux-x64": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-x64/-/lmdb-linux-x64-3.4.2.tgz", - "integrity": "sha512-vL9nM17C77lohPYE4YaAQvfZCSVJSryE4fXdi8M7uWPBnU+9DJabgKVAeyDb84ZM2vcFseoBE4/AagVtJeRE7g==", - "optional": true - }, - "@lmdb/lmdb-win32-arm64": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-win32-arm64/-/lmdb-win32-arm64-3.4.2.tgz", - "integrity": "sha512-SXWjdBfNDze4ZPeLtYIzsIeDJDJ/SdsA0pEXcUBayUIMO0FQBHfVZZyHXQjjHr4cvOAzANBgIiqaXRwfMhzmLw==", - "optional": true - }, - "@lmdb/lmdb-win32-x64": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-win32-x64/-/lmdb-win32-x64-3.4.2.tgz", - "integrity": "sha512-IY+r3bxKW6Q6sIPiMC0L533DEfRJSXibjSI3Ft/w9Q8KQBNqEIvUFXt+09wV8S5BRk0a8uSF19YWxuRwEfI90g==", - "optional": true - }, - "@modelcontextprotocol/sdk": { - "version": "1.26.0", - "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.26.0.tgz", - "integrity": "sha512-Y5RmPncpiDtTXDbLKswIJzTqu2hyBKxTNsgKqKclDbhIgg1wgtf1fRuvxgTnRfcnxtvvgbIEcqUOzZrJ6iSReg==", - "requires": { - "@hono/node-server": "^1.19.9", - "ajv": "^8.17.1", - "ajv-formats": "^3.0.1", - "content-type": "^1.0.5", - "cors": "^2.8.5", - "cross-spawn": "^7.0.5", - "eventsource": "^3.0.2", - "eventsource-parser": "^3.0.0", - "express": "^5.2.1", - "express-rate-limit": "^8.2.1", - "hono": "^4.11.4", - "jose": "^6.1.3", - "json-schema-typed": "^8.0.2", - "pkce-challenge": "^5.0.0", - "raw-body": "^3.0.0", - "zod": "^3.25 || ^4.0", - "zod-to-json-schema": "^3.25.1" - }, - "dependencies": { - "ajv": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", - "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", - "requires": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - } - }, - "ajv-formats": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", - "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", - "requires": { - "ajv": "^8.0.0" - } - }, - "http-errors": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", - "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", - "requires": { - "depd": "~2.0.0", - "inherits": "~2.0.4", - "setprototypeof": "~1.2.0", - "statuses": "~2.0.2", - "toidentifier": "~1.0.1" - } - }, - "iconv-lite": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz", - "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==", - "requires": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - } - }, - "json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" - }, - "raw-body": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz", - "integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==", - "requires": { - "bytes": "~3.1.2", - "http-errors": "~2.0.1", - "iconv-lite": "~0.7.0", - "unpipe": "~1.0.0" - } - }, - "statuses": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", - "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==" - } - } - }, - "@msgpackr-extract/msgpackr-extract-darwin-arm64": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-3.0.3.tgz", - "integrity": "sha512-QZHtlVgbAdy2zAqNA9Gu1UpIuI8Xvsd1v8ic6B2pZmeFnFcMWiPLfWXh7TVw4eGEZ/C9TH281KwhVoeQUKbyjw==", - "optional": true - }, - "@msgpackr-extract/msgpackr-extract-darwin-x64": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-x64/-/msgpackr-extract-darwin-x64-3.0.3.tgz", - "integrity": "sha512-mdzd3AVzYKuUmiWOQ8GNhl64/IoFGol569zNRdkLReh6LRLHOXxU4U8eq0JwaD8iFHdVGqSy4IjFL4reoWCDFw==", - "optional": true - }, - "@msgpackr-extract/msgpackr-extract-linux-arm": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm/-/msgpackr-extract-linux-arm-3.0.3.tgz", - "integrity": "sha512-fg0uy/dG/nZEXfYilKoRe7yALaNmHoYeIoJuJ7KJ+YyU2bvY8vPv27f7UKhGRpY6euFYqEVhxCFZgAUNQBM3nw==", - "optional": true - }, - "@msgpackr-extract/msgpackr-extract-linux-arm64": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm64/-/msgpackr-extract-linux-arm64-3.0.3.tgz", - "integrity": "sha512-YxQL+ax0XqBJDZiKimS2XQaf+2wDGVa1enVRGzEvLLVFeqa5kx2bWbtcSXgsxjQB7nRqqIGFIcLteF/sHeVtQg==", - "optional": true - }, - "@msgpackr-extract/msgpackr-extract-linux-x64": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-x64/-/msgpackr-extract-linux-x64-3.0.3.tgz", - "integrity": "sha512-cvwNfbP07pKUfq1uH+S6KJ7dT9K8WOE4ZiAcsrSes+UY55E/0jLYc+vq+DO7jlmqRb5zAggExKm0H7O/CBaesg==", - "optional": true - }, - "@msgpackr-extract/msgpackr-extract-win32-x64": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-3.0.3.tgz", - "integrity": "sha512-x0fWaQtYp4E6sktbsdAqnehxDgEc/VwM7uLsRCYWaiGu0ykYdZPiS8zCWdnjHwyiumousxfBm4SO31eXqwEZhQ==", - "optional": true - }, - "@napi-rs/nice": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@napi-rs/nice/-/nice-1.1.1.tgz", - "integrity": "sha512-xJIPs+bYuc9ASBl+cvGsKbGrJmS6fAKaSZCnT0lhahT5rhA2VVy9/EcIgd2JhtEuFOJNx7UHNn/qiTPTY4nrQw==", - "optional": true, - "requires": { - "@napi-rs/nice-android-arm-eabi": "1.1.1", - "@napi-rs/nice-android-arm64": "1.1.1", - "@napi-rs/nice-darwin-arm64": "1.1.1", - "@napi-rs/nice-darwin-x64": "1.1.1", - "@napi-rs/nice-freebsd-x64": "1.1.1", - "@napi-rs/nice-linux-arm-gnueabihf": "1.1.1", - "@napi-rs/nice-linux-arm64-gnu": "1.1.1", - "@napi-rs/nice-linux-arm64-musl": "1.1.1", - "@napi-rs/nice-linux-ppc64-gnu": "1.1.1", - "@napi-rs/nice-linux-riscv64-gnu": "1.1.1", - "@napi-rs/nice-linux-s390x-gnu": "1.1.1", - "@napi-rs/nice-linux-x64-gnu": "1.1.1", - "@napi-rs/nice-linux-x64-musl": "1.1.1", - "@napi-rs/nice-openharmony-arm64": "1.1.1", - "@napi-rs/nice-win32-arm64-msvc": "1.1.1", - "@napi-rs/nice-win32-ia32-msvc": "1.1.1", - "@napi-rs/nice-win32-x64-msvc": "1.1.1" - } - }, - "@napi-rs/nice-android-arm-eabi": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-android-arm-eabi/-/nice-android-arm-eabi-1.1.1.tgz", - "integrity": "sha512-kjirL3N6TnRPv5iuHw36wnucNqXAO46dzK9oPb0wj076R5Xm8PfUVA9nAFB5ZNMmfJQJVKACAPd/Z2KYMppthw==", - "optional": true - }, - "@napi-rs/nice-android-arm64": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-android-arm64/-/nice-android-arm64-1.1.1.tgz", - "integrity": "sha512-blG0i7dXgbInN5urONoUCNf+DUEAavRffrO7fZSeoRMJc5qD+BJeNcpr54msPF6qfDD6kzs9AQJogZvT2KD5nw==", - "optional": true - }, - "@napi-rs/nice-darwin-arm64": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-darwin-arm64/-/nice-darwin-arm64-1.1.1.tgz", - "integrity": "sha512-s/E7w45NaLqTGuOjC2p96pct4jRfo61xb9bU1unM/MJ/RFkKlJyJDx7OJI/O0ll/hrfpqKopuAFDV8yo0hfT7A==", - "optional": true - }, - "@napi-rs/nice-darwin-x64": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-darwin-x64/-/nice-darwin-x64-1.1.1.tgz", - "integrity": "sha512-dGoEBnVpsdcC+oHHmW1LRK5eiyzLwdgNQq3BmZIav+9/5WTZwBYX7r5ZkQC07Nxd3KHOCkgbHSh4wPkH1N1LiQ==", - "optional": true - }, - "@napi-rs/nice-freebsd-x64": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-freebsd-x64/-/nice-freebsd-x64-1.1.1.tgz", - "integrity": "sha512-kHv4kEHAylMYmlNwcQcDtXjklYp4FCf0b05E+0h6nDHsZ+F0bDe04U/tXNOqrx5CmIAth4vwfkjjUmp4c4JktQ==", - "optional": true - }, - "@napi-rs/nice-linux-arm-gnueabihf": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-arm-gnueabihf/-/nice-linux-arm-gnueabihf-1.1.1.tgz", - "integrity": "sha512-E1t7K0efyKXZDoZg1LzCOLxgolxV58HCkaEkEvIYQx12ht2pa8hoBo+4OB3qh7e+QiBlp1SRf+voWUZFxyhyqg==", - "optional": true - }, - "@napi-rs/nice-linux-arm64-gnu": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-arm64-gnu/-/nice-linux-arm64-gnu-1.1.1.tgz", - "integrity": "sha512-CIKLA12DTIZlmTaaKhQP88R3Xao+gyJxNWEn04wZwC2wmRapNnxCUZkVwggInMJvtVElA+D4ZzOU5sX4jV+SmQ==", - "optional": true - }, - "@napi-rs/nice-linux-arm64-musl": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-arm64-musl/-/nice-linux-arm64-musl-1.1.1.tgz", - "integrity": "sha512-+2Rzdb3nTIYZ0YJF43qf2twhqOCkiSrHx2Pg6DJaCPYhhaxbLcdlV8hCRMHghQ+EtZQWGNcS2xF4KxBhSGeutg==", - "optional": true - }, - "@napi-rs/nice-linux-ppc64-gnu": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-ppc64-gnu/-/nice-linux-ppc64-gnu-1.1.1.tgz", - "integrity": "sha512-4FS8oc0GeHpwvv4tKciKkw3Y4jKsL7FRhaOeiPei0X9T4Jd619wHNe4xCLmN2EMgZoeGg+Q7GY7BsvwKpL22Tg==", - "optional": true - }, - "@napi-rs/nice-linux-riscv64-gnu": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-riscv64-gnu/-/nice-linux-riscv64-gnu-1.1.1.tgz", - "integrity": "sha512-HU0nw9uD4FO/oGCCk409tCi5IzIZpH2agE6nN4fqpwVlCn5BOq0MS1dXGjXaG17JaAvrlpV5ZeyZwSon10XOXw==", - "optional": true - }, - "@napi-rs/nice-linux-s390x-gnu": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-s390x-gnu/-/nice-linux-s390x-gnu-1.1.1.tgz", - "integrity": "sha512-2YqKJWWl24EwrX0DzCQgPLKQBxYDdBxOHot1KWEq7aY2uYeX+Uvtv4I8xFVVygJDgf6/92h9N3Y43WPx8+PAgQ==", - "optional": true - }, - "@napi-rs/nice-linux-x64-gnu": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-x64-gnu/-/nice-linux-x64-gnu-1.1.1.tgz", - "integrity": "sha512-/gaNz3R92t+dcrfCw/96pDopcmec7oCcAQ3l/M+Zxr82KT4DljD37CpgrnXV+pJC263JkW572pdbP3hP+KjcIg==", - "optional": true - }, - "@napi-rs/nice-linux-x64-musl": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-x64-musl/-/nice-linux-x64-musl-1.1.1.tgz", - "integrity": "sha512-xScCGnyj/oppsNPMnevsBe3pvNaoK7FGvMjT35riz9YdhB2WtTG47ZlbxtOLpjeO9SqqQ2J2igCmz6IJOD5JYw==", - "optional": true - }, - "@napi-rs/nice-openharmony-arm64": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-openharmony-arm64/-/nice-openharmony-arm64-1.1.1.tgz", - "integrity": "sha512-6uJPRVwVCLDeoOaNyeiW0gp2kFIM4r7PL2MczdZQHkFi9gVlgm+Vn+V6nTWRcu856mJ2WjYJiumEajfSm7arPQ==", - "optional": true - }, - "@napi-rs/nice-win32-arm64-msvc": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-win32-arm64-msvc/-/nice-win32-arm64-msvc-1.1.1.tgz", - "integrity": "sha512-uoTb4eAvM5B2aj/z8j+Nv8OttPf2m+HVx3UjA5jcFxASvNhQriyCQF1OB1lHL43ZhW+VwZlgvjmP5qF3+59atA==", - "optional": true - }, - "@napi-rs/nice-win32-ia32-msvc": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-win32-ia32-msvc/-/nice-win32-ia32-msvc-1.1.1.tgz", - "integrity": "sha512-CNQqlQT9MwuCsg1Vd/oKXiuH+TcsSPJmlAFc5frFyX/KkOh0UpBLEj7aoY656d5UKZQMQFP7vJNa1DNUNORvug==", - "optional": true - }, - "@napi-rs/nice-win32-x64-msvc": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-win32-x64-msvc/-/nice-win32-x64-msvc-1.1.1.tgz", - "integrity": "sha512-vB+4G/jBQCAh0jelMTY3+kgFy00Hlx2f2/1zjMoH821IbplbWZOkLiTYXQkygNTzQJTq5cvwBDgn2ppHD+bglQ==", - "optional": true - }, - "@ng-bootstrap/ng-bootstrap": { - "version": "19.0.1", - "resolved": "https://registry.npmjs.org/@ng-bootstrap/ng-bootstrap/-/ng-bootstrap-19.0.1.tgz", - "integrity": "sha512-1lErAkwh0F+gWkzpiddViY4GfA9LVXkwLpgBsV9Mb3IC0zo6WNkY8WxCC+LqajirBTu20DCkZSqeRzrwaVLpZw==", - "requires": { - "tslib": "^2.3.0" - } - }, - "@ngtools/webpack": { - "version": "20.3.22", - "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-20.3.22.tgz", - "integrity": "sha512-EgOiRjYpNG5Mu/WAhMwQrAB1BBwWrApbYm2hTU9KjaxOZvtWHjeFfsiULgd1T76GpiF4t3Iw1GtNljzgD6fT/A==", - "requires": {} - }, - "@noble/secp256k1": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@noble/secp256k1/-/secp256k1-3.0.0.tgz", - "integrity": "sha512-NJBaR352KyIvj3t6sgT/+7xrNyF9Xk9QlLSIqUGVUYlsnDTAUqY8LOmwpcgEx4AMJXRITQ5XEVHD+mMaPfr3mg==" - }, - "@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "requires": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - } - }, - "@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==" - }, - "@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "requires": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - } - }, - "@npmcli/agent": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@npmcli/agent/-/agent-4.0.0.tgz", - "integrity": "sha512-kAQTcEN9E8ERLVg5AsGwLNoFb+oEG6engbqAU2P43gD4JEIkNGMHdVQ096FsOAAYpZPB0RSt0zgInKIAS1l5QA==", - "requires": { - "agent-base": "^7.1.0", - "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.1", - "lru-cache": "^11.2.1", - "socks-proxy-agent": "^8.0.3" - } - }, - "@npmcli/fs": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-5.0.0.tgz", - "integrity": "sha512-7OsC1gNORBEawOa5+j2pXN9vsicaIOH5cPXxoR6fJOmH6/EXpJB2CajXOu1fPRFun2m1lktEFX11+P89hqO/og==", - "requires": { - "semver": "^7.3.5" - } - }, - "@npmcli/git": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-7.0.1.tgz", - "integrity": "sha512-+XTFxK2jJF/EJJ5SoAzXk3qwIDfvFc5/g+bD274LZ7uY7LE8sTfG6Z8rOanPl2ZEvZWqNvmEdtXC25cE54VcoA==", - "requires": { - "@npmcli/promise-spawn": "^9.0.0", - "ini": "^6.0.0", - "lru-cache": "^11.2.1", - "npm-pick-manifest": "^11.0.1", - "proc-log": "^6.0.0", - "promise-retry": "^2.0.1", - "semver": "^7.3.5", - "which": "^6.0.0" - }, - "dependencies": { - "ini": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/ini/-/ini-6.0.0.tgz", - "integrity": "sha512-IBTdIkzZNOpqm7q3dRqJvMaldXjDHWkEDfrwGEQTs5eaQMWV+djAhR+wahyNNMAa+qpbDUhBMVt4ZKNwpPm7xQ==" - }, - "isexe": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", - "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==" - }, - "proc-log": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-6.1.0.tgz", - "integrity": "sha512-iG+GYldRf2BQ0UDUAd6JQ/RwzaQy6mXmsk/IzlYyal4A4SNFw54MeH4/tLkF4I5WoWG9SQwuqWzS99jaFQHBuQ==" - }, - "which": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/which/-/which-6.0.0.tgz", - "integrity": "sha512-f+gEpIKMR9faW/JgAgPK1D7mekkFoqbmiwvNzuhsHetni20QSgzg9Vhn0g2JSJkkfehQnqdUAx7/e15qS1lPxg==", - "requires": { - "isexe": "^3.1.1" - } - } - } - }, - "@npmcli/installed-package-contents": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@npmcli/installed-package-contents/-/installed-package-contents-4.0.0.tgz", - "integrity": "sha512-yNyAdkBxB72gtZ4GrwXCM0ZUedo9nIbOMKfGjt6Cu6DXf0p8y1PViZAKDC8q8kv/fufx0WTjRBdSlyrvnP7hmA==", - "requires": { - "npm-bundled": "^5.0.0", - "npm-normalize-package-bin": "^5.0.0" - } - }, - "@npmcli/node-gyp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@npmcli/node-gyp/-/node-gyp-5.0.0.tgz", - "integrity": "sha512-uuG5HZFXLfyFKqg8QypsmgLQW7smiRjVc45bqD/ofZZcR/uxEjgQU8qDPv0s9TEeMUiAAU/GC5bR6++UdTirIQ==" - }, - "@npmcli/package-json": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/@npmcli/package-json/-/package-json-7.0.4.tgz", - "integrity": "sha512-0wInJG3j/K40OJt/33ax47WfWMzZTm6OQxB9cDhTt5huCP2a9g2GnlsxmfN+PulItNPIpPrZ+kfwwUil7eHcZQ==", - "requires": { - "@npmcli/git": "^7.0.0", - "glob": "^13.0.0", - "hosted-git-info": "^9.0.0", - "json-parse-even-better-errors": "^5.0.0", - "proc-log": "^6.0.0", - "semver": "^7.5.3", - "validate-npm-package-license": "^3.0.4" - }, - "dependencies": { - "json-parse-even-better-errors": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-5.0.0.tgz", - "integrity": "sha512-ZF1nxZ28VhQouRWhUcVlUIN3qwSgPuswK05s/HIaoetAoE/9tngVmCHjSxmSQPav1nd+lPtTL0YZ/2AFdR/iYQ==" - }, - "proc-log": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-6.1.0.tgz", - "integrity": "sha512-iG+GYldRf2BQ0UDUAd6JQ/RwzaQy6mXmsk/IzlYyal4A4SNFw54MeH4/tLkF4I5WoWG9SQwuqWzS99jaFQHBuQ==" - } - } - }, - "@npmcli/promise-spawn": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-9.0.1.tgz", - "integrity": "sha512-OLUaoqBuyxeTqUvjA3FZFiXUfYC1alp3Sa99gW3EUDz3tZ3CbXDdcZ7qWKBzicrJleIgucoWamWH1saAmH/l2Q==", - "requires": { - "which": "^6.0.0" - }, - "dependencies": { - "isexe": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", - "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==" - }, - "which": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/which/-/which-6.0.0.tgz", - "integrity": "sha512-f+gEpIKMR9faW/JgAgPK1D7mekkFoqbmiwvNzuhsHetni20QSgzg9Vhn0g2JSJkkfehQnqdUAx7/e15qS1lPxg==", - "requires": { - "isexe": "^3.1.1" - } - } - } - }, - "@npmcli/redact": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@npmcli/redact/-/redact-4.0.0.tgz", - "integrity": "sha512-gOBg5YHMfZy+TfHArfVogwgfBeQnKbbGo3pSUyK/gSI0AVu+pEiDVcKlQb0D8Mg1LNRZILZ6XG8I5dJ4KuAd9Q==" - }, - "@npmcli/run-script": { - "version": "10.0.3", - "resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-10.0.3.tgz", - "integrity": "sha512-ER2N6itRkzWbbtVmZ9WKaWxVlKlOeBFF1/7xx+KA5J1xKa4JjUwBdb6tDpk0v1qA+d+VDwHI9qmLcXSWcmi+Rw==", - "requires": { - "@npmcli/node-gyp": "^5.0.0", - "@npmcli/package-json": "^7.0.0", - "@npmcli/promise-spawn": "^9.0.0", - "node-gyp": "^12.1.0", - "proc-log": "^6.0.0", - "which": "^6.0.0" - }, - "dependencies": { - "isexe": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", - "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==" - }, - "proc-log": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-6.1.0.tgz", - "integrity": "sha512-iG+GYldRf2BQ0UDUAd6JQ/RwzaQy6mXmsk/IzlYyal4A4SNFw54MeH4/tLkF4I5WoWG9SQwuqWzS99jaFQHBuQ==" - }, - "which": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/which/-/which-6.0.0.tgz", - "integrity": "sha512-f+gEpIKMR9faW/JgAgPK1D7mekkFoqbmiwvNzuhsHetni20QSgzg9Vhn0g2JSJkkfehQnqdUAx7/e15qS1lPxg==", - "requires": { - "isexe": "^3.1.1" - } - } - } - }, - "@parcel/watcher": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.1.tgz", - "integrity": "sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==", - "optional": true, - "requires": { - "@parcel/watcher-android-arm64": "2.5.1", - "@parcel/watcher-darwin-arm64": "2.5.1", - "@parcel/watcher-darwin-x64": "2.5.1", - "@parcel/watcher-freebsd-x64": "2.5.1", - "@parcel/watcher-linux-arm-glibc": "2.5.1", - "@parcel/watcher-linux-arm-musl": "2.5.1", - "@parcel/watcher-linux-arm64-glibc": "2.5.1", - "@parcel/watcher-linux-arm64-musl": "2.5.1", - "@parcel/watcher-linux-x64-glibc": "2.5.1", - "@parcel/watcher-linux-x64-musl": "2.5.1", - "@parcel/watcher-win32-arm64": "2.5.1", - "@parcel/watcher-win32-ia32": "2.5.1", - "@parcel/watcher-win32-x64": "2.5.1", - "detect-libc": "^1.0.3", - "is-glob": "^4.0.3", - "micromatch": "^4.0.5", - "node-addon-api": "^7.0.0" - }, - "dependencies": { - "detect-libc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", - "optional": true - }, - "node-addon-api": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", - "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", - "optional": true - } - } - }, - "@parcel/watcher-android-arm64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.1.tgz", - "integrity": "sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==", - "optional": true - }, - "@parcel/watcher-darwin-arm64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.1.tgz", - "integrity": "sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==", - "optional": true - }, - "@parcel/watcher-darwin-x64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.1.tgz", - "integrity": "sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==", - "optional": true - }, - "@parcel/watcher-freebsd-x64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.1.tgz", - "integrity": "sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==", - "optional": true - }, - "@parcel/watcher-linux-arm-glibc": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.1.tgz", - "integrity": "sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==", - "optional": true - }, - "@parcel/watcher-linux-arm-musl": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.1.tgz", - "integrity": "sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==", - "optional": true - }, - "@parcel/watcher-linux-arm64-glibc": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.1.tgz", - "integrity": "sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==", - "optional": true - }, - "@parcel/watcher-linux-arm64-musl": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.1.tgz", - "integrity": "sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==", - "optional": true - }, - "@parcel/watcher-linux-x64-glibc": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.1.tgz", - "integrity": "sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==", - "optional": true - }, - "@parcel/watcher-linux-x64-musl": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.1.tgz", - "integrity": "sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==", - "optional": true - }, - "@parcel/watcher-win32-arm64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.1.tgz", - "integrity": "sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==", - "optional": true - }, - "@parcel/watcher-win32-ia32": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.1.tgz", - "integrity": "sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ==", - "optional": true - }, - "@parcel/watcher-win32-x64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.1.tgz", - "integrity": "sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==", - "optional": true - }, - "@popperjs/core": { - "version": "2.11.8", - "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", - "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", - "peer": true - }, - "@rollup/rollup-android-arm-eabi": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.59.0.tgz", - "integrity": "sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==", - "optional": true - }, - "@rollup/rollup-android-arm64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.59.0.tgz", - "integrity": "sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==", - "optional": true - }, - "@rollup/rollup-darwin-arm64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.59.0.tgz", - "integrity": "sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==", - "optional": true - }, - "@rollup/rollup-darwin-x64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.59.0.tgz", - "integrity": "sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==", - "optional": true - }, - "@rollup/rollup-freebsd-arm64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.59.0.tgz", - "integrity": "sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==", - "optional": true - }, - "@rollup/rollup-freebsd-x64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.59.0.tgz", - "integrity": "sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==", - "optional": true - }, - "@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.59.0.tgz", - "integrity": "sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==", - "optional": true - }, - "@rollup/rollup-linux-arm-musleabihf": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.59.0.tgz", - "integrity": "sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==", - "optional": true - }, - "@rollup/rollup-linux-arm64-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.59.0.tgz", - "integrity": "sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==", - "optional": true - }, - "@rollup/rollup-linux-arm64-musl": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.59.0.tgz", - "integrity": "sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==", - "optional": true - }, - "@rollup/rollup-linux-loong64-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.59.0.tgz", - "integrity": "sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==", - "optional": true - }, - "@rollup/rollup-linux-loong64-musl": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.59.0.tgz", - "integrity": "sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==", - "optional": true - }, - "@rollup/rollup-linux-ppc64-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.59.0.tgz", - "integrity": "sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==", - "optional": true - }, - "@rollup/rollup-linux-ppc64-musl": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.59.0.tgz", - "integrity": "sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==", - "optional": true - }, - "@rollup/rollup-linux-riscv64-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.59.0.tgz", - "integrity": "sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==", - "optional": true - }, - "@rollup/rollup-linux-riscv64-musl": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.59.0.tgz", - "integrity": "sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==", - "optional": true - }, - "@rollup/rollup-linux-s390x-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.59.0.tgz", - "integrity": "sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==", - "optional": true - }, - "@rollup/rollup-linux-x64-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.59.0.tgz", - "integrity": "sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==", - "optional": true - }, - "@rollup/rollup-linux-x64-musl": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.59.0.tgz", - "integrity": "sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==", - "optional": true - }, - "@rollup/rollup-openbsd-x64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.59.0.tgz", - "integrity": "sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==", - "optional": true - }, - "@rollup/rollup-openharmony-arm64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.59.0.tgz", - "integrity": "sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==", - "optional": true - }, - "@rollup/rollup-win32-arm64-msvc": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.59.0.tgz", - "integrity": "sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==", - "optional": true - }, - "@rollup/rollup-win32-ia32-msvc": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.59.0.tgz", - "integrity": "sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==", - "optional": true - }, - "@rollup/rollup-win32-x64-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.59.0.tgz", - "integrity": "sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==", - "optional": true - }, - "@rollup/rollup-win32-x64-msvc": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.59.0.tgz", - "integrity": "sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==", - "optional": true - }, - "@schematics/angular": { - "version": "20.3.22", - "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-20.3.22.tgz", - "integrity": "sha512-wXTdFaPIBnSSNj/m0kclvPCYQOc2EGTQN1+Q3j9RIghS9gKgPxI1unSfgieJldZWKzcl8+WdB2zUuDzE7tEshQ==", - "requires": { - "@angular-devkit/core": "20.3.22", - "@angular-devkit/schematics": "20.3.22", - "jsonc-parser": "3.3.1" - }, - "dependencies": { - "@angular-devkit/core": { - "version": "20.3.22", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-20.3.22.tgz", - "integrity": "sha512-1vZnZTAjGcCM+86v2al+2eiROiSw0uAWeVllfHSQe0KsKOP1FE8UUUiWChhxVn7vIxypphlfGunkeeIn1C/ZFw==", - "requires": { - "ajv": "8.18.0", - "ajv-formats": "3.0.1", - "jsonc-parser": "3.3.1", - "picomatch": "4.0.4", - "rxjs": "7.8.2", - "source-map": "0.7.6" - } - }, - "ajv": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", - "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", - "requires": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - } - }, - "ajv-formats": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", - "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", - "requires": { - "ajv": "^8.0.0" - } - }, - "json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" - }, - "picomatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==" - }, - "source-map": { - "version": "0.7.6", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", - "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==" - } - } - }, - "@sigstore/bundle": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@sigstore/bundle/-/bundle-4.0.0.tgz", - "integrity": "sha512-NwCl5Y0V6Di0NexvkTqdoVfmjTaQwoLM236r89KEojGmq/jMls8S+zb7yOwAPdXvbwfKDlP+lmXgAL4vKSQT+A==", - "requires": { - "@sigstore/protobuf-specs": "^0.5.0" - } - }, - "@sigstore/core": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@sigstore/core/-/core-3.1.0.tgz", - "integrity": "sha512-o5cw1QYhNQ9IroioJxpzexmPjfCe7gzafd2RY3qnMpxr4ZEja+Jad/U8sgFpaue6bOaF+z7RVkyKVV44FN+N8A==" - }, - "@sigstore/protobuf-specs": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@sigstore/protobuf-specs/-/protobuf-specs-0.5.0.tgz", - "integrity": "sha512-MM8XIwUjN2bwvCg1QvrMtbBmpcSHrkhFSCu1D11NyPvDQ25HEc4oG5/OcQfd/Tlf/OxmKWERDj0zGE23jQaMwA==" - }, - "@sigstore/sign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@sigstore/sign/-/sign-4.1.0.tgz", - "integrity": "sha512-Vx1RmLxLGnSUqx/o5/VsCjkuN5L7y+vxEEwawvc7u+6WtX2W4GNa7b9HEjmcRWohw/d6BpATXmvOwc78m+Swdg==", - "requires": { - "@sigstore/bundle": "^4.0.0", - "@sigstore/core": "^3.1.0", - "@sigstore/protobuf-specs": "^0.5.0", - "make-fetch-happen": "^15.0.3", - "proc-log": "^6.1.0", - "promise-retry": "^2.0.1" - }, - "dependencies": { - "proc-log": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-6.1.0.tgz", - "integrity": "sha512-iG+GYldRf2BQ0UDUAd6JQ/RwzaQy6mXmsk/IzlYyal4A4SNFw54MeH4/tLkF4I5WoWG9SQwuqWzS99jaFQHBuQ==" - } - } - }, - "@sigstore/tuf": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@sigstore/tuf/-/tuf-4.0.1.tgz", - "integrity": "sha512-OPZBg8y5Vc9yZjmWCHrlWPMBqW5yd8+wFNl+thMdtcWz3vjVSoJQutF8YkrzI0SLGnkuFof4HSsWUhXrf219Lw==", - "requires": { - "@sigstore/protobuf-specs": "^0.5.0", - "tuf-js": "^4.1.0" - } - }, - "@sigstore/verify": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@sigstore/verify/-/verify-3.1.0.tgz", - "integrity": "sha512-mNe0Iigql08YupSOGv197YdHpPPr+EzDZmfCgMc7RPNaZTw5aLN01nBl6CHJOh3BGtnMIj83EeN4butBchc8Ag==", - "requires": { - "@sigstore/bundle": "^4.0.0", - "@sigstore/core": "^3.1.0", - "@sigstore/protobuf-specs": "^0.5.0" - } - }, - "@sinonjs/commons": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz", - "integrity": "sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==", - "optional": true, - "requires": { - "type-detect": "4.0.8" - } - }, - "@sinonjs/fake-timers": { - "version": "11.2.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-11.2.2.tgz", - "integrity": "sha512-G2piCSxQ7oWOxwGSAyFHfPIsyeJGXYtc6mFbnFA+kRXkiEnTl8c/8jul2S329iFBnDI9HGoeWWAZvuvOkZccgw==", - "optional": true, - "requires": { - "@sinonjs/commons": "^3.0.0" - } - }, - "@sinonjs/samsam": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.0.tgz", - "integrity": "sha512-Bp8KUVlLp8ibJZrnvq2foVhP0IVX2CIprMJPK0vqGqgrDa0OHVKeZyBykqskkrdxV6yKBPmGasO8LVjAKR3Gew==", - "optional": true, - "requires": { - "@sinonjs/commons": "^2.0.0", - "lodash.get": "^4.4.2", - "type-detect": "^4.0.8" - }, - "dependencies": { - "@sinonjs/commons": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", - "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", - "optional": true, - "requires": { - "type-detect": "4.0.8" - } - } - } - }, - "@sinonjs/text-encoding": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.2.tgz", - "integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==", - "optional": true - }, - "@socket.io/component-emitter": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz", - "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==", - "devOptional": true - }, - "@standard-schema/spec": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.0.0.tgz", - "integrity": "sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==", - "optional": true - }, - "@tsconfig/node10": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", - "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", - "dev": true - }, - "@tsconfig/node12": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true - }, - "@tsconfig/node14": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true - }, - "@tsconfig/node16": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", - "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", - "dev": true - }, - "@tufjs/canonical-json": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@tufjs/canonical-json/-/canonical-json-2.0.0.tgz", - "integrity": "sha512-yVtV8zsdo8qFHe+/3kw81dSLyF7D576A5cCFCi4X7B39tWT7SekaEFUnvnWJHz+9qO7qJTah1JbrDjWKqFtdWA==" - }, - "@tufjs/models": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@tufjs/models/-/models-4.1.0.tgz", - "integrity": "sha512-Y8cK9aggNRsqJVaKUlEYs4s7CvQ1b1ta2DVPyAimb0I2qhzjNk+A+mxvll/klL0RlfuIUei8BF7YWiua4kQqww==", - "requires": { - "@tufjs/canonical-json": "2.0.0", - "minimatch": "^10.1.1" - }, - "dependencies": { - "balanced-match": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", - "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==" - }, - "brace-expansion": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", - "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", - "requires": { - "balanced-match": "^4.0.2" - } - }, - "minimatch": { - "version": "10.2.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", - "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", - "requires": { - "brace-expansion": "^5.0.2" - } - } - } - }, - "@types/babel__core": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", - "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", - "requires": { - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "@types/babel__generator": { - "version": "7.27.0", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", - "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", - "requires": { - "@babel/types": "^7.0.0" - } - }, - "@types/babel__template": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", - "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", - "requires": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "@types/babel__traverse": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", - "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", - "requires": { - "@babel/types": "^7.28.2" - } - }, - "@types/body-parser": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.0.tgz", - "integrity": "sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ==", - "requires": { - "@types/connect": "*", - "@types/node": "*" - } - }, - "@types/bonjour": { - "version": "3.5.13", - "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", - "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", - "requires": { - "@types/node": "*" - } - }, - "@types/chai": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", - "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", - "devOptional": true, - "requires": { - "@types/deep-eql": "*", - "assertion-error": "^2.0.1" - }, - "dependencies": { - "assertion-error": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", - "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", - "devOptional": true - } - } - }, - "@types/connect": { - "version": "3.4.33", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.33.tgz", - "integrity": "sha512-2+FrkXY4zllzTNfJth7jOqEHC+enpLeGslEhpnTAkg21GkRrWV4SsAtqchtT4YS9/nODBU2/ZfsBY2X4J/dX7A==", - "requires": { - "@types/node": "*" - } - }, - "@types/connect-history-api-fallback": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz", - "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==", - "requires": { - "@types/express-serve-static-core": "*", - "@types/node": "*" - } - }, - "@types/cookie": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz", - "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==", - "devOptional": true - }, - "@types/cors": { - "version": "2.8.17", - "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.17.tgz", - "integrity": "sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==", - "devOptional": true, - "requires": { - "@types/node": "*" - } - }, - "@types/deep-eql": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", - "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", - "devOptional": true - }, - "@types/eslint": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", - "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", - "requires": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "@types/eslint-scope": { - "version": "3.7.7", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", - "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", - "requires": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, - "@types/estree": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", - "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==" - }, - "@types/express": { - "version": "4.17.25", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.25.tgz", - "integrity": "sha512-dVd04UKsfpINUnK0yBoYHDF3xu7xVH4BuDotC/xGuycx4CgbP48X/KF/586bcObxT0HENHXEU8Nqtu6NR+eKhw==", - "requires": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.33", - "@types/qs": "*", - "@types/serve-static": "^1" - } - }, - "@types/express-serve-static-core": { - "version": "4.19.7", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.7.tgz", - "integrity": "sha512-FvPtiIf1LfhzsaIXhv/PHan/2FeQBbtBDtfX2QfvPxdUelMDEckK08SM6nqo1MIZY3RUlfA+HV8+hFUSio78qg==", - "requires": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*", - "@types/send": "*" - } - }, - "@types/http-errors": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.5.tgz", - "integrity": "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==" - }, - "@types/http-proxy": { - "version": "1.17.17", - "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.17.tgz", - "integrity": "sha512-ED6LB+Z1AVylNTu7hdzuBqOgMnvG/ld6wGCG8wFnAzKX5uyW2K3WD52v0gnLCTK/VLpXtKckgWuyScYK6cSPaw==", - "requires": { - "@types/node": "*" - } - }, - "@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==" - }, - "@types/mime": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", - "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==" - }, - "@types/node": { - "version": "24.9.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-24.9.2.tgz", - "integrity": "sha512-uWN8YqxXxqFMX2RqGOrumsKeti4LlmIMIyV0lgut4jx7KQBcBiW6vkDtIBvHnHIquwNfJhk8v2OtmO8zXWHfPA==", - "requires": { - "undici-types": "~7.16.0" - } - }, - "@types/node-forge": { - "version": "1.3.14", - "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.14.tgz", - "integrity": "sha512-mhVF2BnD4BO+jtOp7z1CdzaK4mbuK0LLQYAvdOLqHTavxFNq4zA1EmYkpnFjP8HOUzedfQkRnp0E2ulSAYSzAw==", - "requires": { - "@types/node": "*" - } - }, - "@types/qrcode": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@types/qrcode/-/qrcode-1.5.0.tgz", - "integrity": "sha512-x5ilHXRxUPIMfjtM+1vf/GPTRWZ81nqscursm5gMznJeK9M0YnZ1c3bEvRLQ0zSSgedLx1J6MGL231ObQGGhaA==", - "requires": { - "@types/node": "*" - } - }, - "@types/qs": { - "version": "6.9.5", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.5.tgz", - "integrity": "sha512-/JHkVHtx/REVG0VVToGRGH2+23hsYLHdyG+GrvoUGlGAd0ErauXDyvHtRI/7H7mzLm+tBCKA7pfcpkQ1lf58iQ==" - }, - "@types/range-parser": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz", - "integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==" - }, - "@types/retry": { - "version": "0.12.2", - "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.2.tgz", - "integrity": "sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==" - }, - "@types/send": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@types/send/-/send-1.2.1.tgz", - "integrity": "sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ==", - "requires": { - "@types/node": "*" - } - }, - "@types/serve-index": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", - "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", - "requires": { - "@types/express": "*" - } - }, - "@types/serve-static": { - "version": "1.15.10", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.10.tgz", - "integrity": "sha512-tRs1dB+g8Itk72rlSI2ZrW6vZg0YrLI81iQSTkMmOqnqCaNr/8Ek4VwWcN5vZgCYWbg/JJSGBlUaYGAOP73qBw==", - "requires": { - "@types/http-errors": "*", - "@types/node": "*", - "@types/send": "<1" - }, - "dependencies": { - "@types/send": { - "version": "0.17.6", - "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.6.tgz", - "integrity": "sha512-Uqt8rPBE8SY0RK8JB1EzVOIZ32uqy8HwdxCnoCOsYrvnswqmFZ/k+9Ikidlk/ImhsdvBsloHbAlewb2IEBV/Og==", - "requires": { - "@types/mime": "^1", - "@types/node": "*" - } - } - } - }, - "@types/sinonjs__fake-timers": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.1.tgz", - "integrity": "sha512-0kSuKjAS0TrGLJ0M/+8MaFkGsQhZpB6pxOmvS3K8FYI72K//YmdfoW9X2qPsAKh1mkwxGD5zib9s1FIFed6E8g==", - "optional": true - }, - "@types/sizzle": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.2.tgz", - "integrity": "sha512-7EJYyKTL7tFR8+gDbB6Wwz/arpGa0Mywk1TJbNzKzHtzbwVmY4HR9WqS5VV7dsBUKQmPNr192jHr/VpBluj/hg==", - "optional": true - }, - "@types/sockjs": { - "version": "0.3.36", - "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", - "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", - "requires": { - "@types/node": "*" - } - }, - "@types/tmp": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/@types/tmp/-/tmp-0.2.6.tgz", - "integrity": "sha512-chhaNf2oKHlRkDGt+tiKE2Z5aJ6qalm7Z9rlLdBwmOiAAf09YQvvoLXjWK4HWPF1xU/fqvMgfNfpVoBscA/tKA==", - "optional": true - }, - "@types/ws": { - "version": "8.18.1", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz", - "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==", - "requires": { - "@types/node": "*" - } - }, - "@types/yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==", - "optional": true, - "requires": { - "@types/node": "*" - } - }, - "@typescript-eslint/eslint-plugin": { - "version": "8.46.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.46.2.tgz", - "integrity": "sha512-ZGBMToy857/NIPaaCucIUQgqueOiq7HeAKkhlvqVV4lm089zUFW6ikRySx2v+cAhKeUCPuWVHeimyk6Dw1iY3w==", - "dev": true, - "requires": { - "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.46.2", - "@typescript-eslint/type-utils": "8.46.2", - "@typescript-eslint/utils": "8.46.2", - "@typescript-eslint/visitor-keys": "8.46.2", - "graphemer": "^1.4.0", - "ignore": "^7.0.0", - "natural-compare": "^1.4.0", - "ts-api-utils": "^2.1.0" - } - }, - "@typescript-eslint/parser": { - "version": "8.46.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.46.2.tgz", - "integrity": "sha512-BnOroVl1SgrPLywqxyqdJ4l3S2MsKVLDVxZvjI1Eoe8ev2r3kGDo+PcMihNmDE+6/KjkTubSJnmqGZZjQSBq/g==", - "dev": true, - "requires": { - "@typescript-eslint/scope-manager": "8.46.2", - "@typescript-eslint/types": "8.46.2", - "@typescript-eslint/typescript-estree": "8.46.2", - "@typescript-eslint/visitor-keys": "8.46.2", - "debug": "^4.3.4" - } - }, - "@typescript-eslint/project-service": { - "version": "8.46.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.46.2.tgz", - "integrity": "sha512-PULOLZ9iqwI7hXcmL4fVfIsBi6AN9YxRc0frbvmg8f+4hQAjQ5GYNKK0DIArNo+rOKmR/iBYwkpBmnIwin4wBg==", - "dev": true, - "requires": { - "@typescript-eslint/tsconfig-utils": "^8.46.2", - "@typescript-eslint/types": "^8.46.2", - "debug": "^4.3.4" - } - }, - "@typescript-eslint/scope-manager": { - "version": "8.46.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.46.2.tgz", - "integrity": "sha512-LF4b/NmGvdWEHD2H4MsHD8ny6JpiVNDzrSZr3CsckEgCbAGZbYM4Cqxvi9L+WqDMT+51Ozy7lt2M+d0JLEuBqA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "8.46.2", - "@typescript-eslint/visitor-keys": "8.46.2" - } - }, - "@typescript-eslint/tsconfig-utils": { - "version": "8.46.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.46.2.tgz", - "integrity": "sha512-a7QH6fw4S57+F5y2FIxxSDyi5M4UfGF+Jl1bCGd7+L4KsaUY80GsiF/t0UoRFDHAguKlBaACWJRmdrc6Xfkkag==", - "dev": true, - "requires": {} - }, - "@typescript-eslint/type-utils": { - "version": "8.46.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.46.2.tgz", - "integrity": "sha512-HbPM4LbaAAt/DjxXaG9yiS9brOOz6fabal4uvUmaUYe6l3K1phQDMQKBRUrr06BQkxkvIZVVHttqiybM9nJsLA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "8.46.2", - "@typescript-eslint/typescript-estree": "8.46.2", - "@typescript-eslint/utils": "8.46.2", - "debug": "^4.3.4", - "ts-api-utils": "^2.1.0" - } - }, - "@typescript-eslint/types": { - "version": "8.46.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.46.2.tgz", - "integrity": "sha512-lNCWCbq7rpg7qDsQrd3D6NyWYu+gkTENkG5IKYhUIcxSb59SQC/hEQ+MrG4sTgBVghTonNWq42bA/d4yYumldQ==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "8.46.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.46.2.tgz", - "integrity": "sha512-f7rW7LJ2b7Uh2EiQ+7sza6RDZnajbNbemn54Ob6fRwQbgcIn+GWfyuHDHRYgRoZu1P4AayVScrRW+YfbTvPQoQ==", - "dev": true, - "requires": { - "@typescript-eslint/project-service": "8.46.2", - "@typescript-eslint/tsconfig-utils": "8.46.2", - "@typescript-eslint/types": "8.46.2", - "@typescript-eslint/visitor-keys": "8.46.2", - "debug": "^4.3.4", - "fast-glob": "^3.3.2", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^2.1.0" - }, - "dependencies": { - "brace-expansion": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.3.tgz", - "integrity": "sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0" - } - }, - "minimatch": { - "version": "9.0.9", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", - "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", - "dev": true, - "requires": { - "brace-expansion": "^2.0.2" - } - } - } - }, - "@typescript-eslint/utils": { - "version": "8.46.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.46.2.tgz", - "integrity": "sha512-sExxzucx0Tud5tE0XqR0lT0psBQvEpnpiul9XbGUB1QwpWJJAps1O/Z7hJxLGiZLBKMCutjTzDgmd1muEhBnVg==", - "dev": true, - "requires": { - "@eslint-community/eslint-utils": "^4.7.0", - "@typescript-eslint/scope-manager": "8.46.2", - "@typescript-eslint/types": "8.46.2", - "@typescript-eslint/typescript-estree": "8.46.2" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "8.46.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.46.2.tgz", - "integrity": "sha512-tUFMXI4gxzzMXt4xpGJEsBsTox0XbNQ1y94EwlD/CuZwFcQP79xfQqMhau9HsRc/J0cAPA/HZt1dZPtGn9V/7w==", - "dev": true, - "requires": { - "@typescript-eslint/types": "8.46.2", - "eslint-visitor-keys": "^4.2.1" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", - "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", - "dev": true - } - } - }, - "@vitejs/plugin-basic-ssl": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-basic-ssl/-/plugin-basic-ssl-2.1.0.tgz", - "integrity": "sha512-dOxxrhgyDIEUADhb/8OlV9JIqYLgos03YorAueTIeOUskLJSEsfwCByjbu98ctXitUN3znXKp0bYD/WHSudCeA==", - "requires": {} - }, - "@vitest/expect": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.7.tgz", - "integrity": "sha512-E8eBXaKibuvH2pSZErOjdVb5vF4PbKYcrnluBTYxEk1l/VhhwZg1kZQsdtjq+CsF5CFydf2Rdkz7jDHKSisi3w==", - "devOptional": true, - "requires": { - "@types/chai": "^5.2.2", - "@vitest/spy": "3.2.7", - "@vitest/utils": "3.2.7", - "chai": "^5.2.0", - "tinyrainbow": "^2.0.0" - }, - "dependencies": { - "assertion-error": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", - "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", - "devOptional": true - }, - "chai": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/chai/-/chai-5.3.3.tgz", - "integrity": "sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==", - "devOptional": true, - "requires": { - "assertion-error": "^2.0.1", - "check-error": "^2.1.1", - "deep-eql": "^5.0.1", - "loupe": "^3.1.0", - "pathval": "^2.0.0" - } - }, - "check-error": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.3.tgz", - "integrity": "sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==", - "devOptional": true - }, - "deep-eql": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", - "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", - "devOptional": true - }, - "loupe": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.1.tgz", - "integrity": "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==", - "devOptional": true - }, - "pathval": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz", - "integrity": "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==", - "devOptional": true - } - } - }, - "@vitest/mocker": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.2.7.tgz", - "integrity": "sha512-Trr0hYO9CM3Wj6ksWHRhK9IZpIY6wTMO5u/MqXurMxT57sWBaOPEtP3Oq60ihZuh5JsiagKfz95OcxdEP6dBrA==", - "devOptional": true, - "requires": { - "@vitest/spy": "3.2.7", - "estree-walker": "^3.0.3", - "magic-string": "^0.30.17" - } - }, - "@vitest/pretty-format": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.7.tgz", - "integrity": "sha512-KUHlwqVu0sRlhCdyPdQ/wBoTfRahjUky1MubOmYw9fWfIZy1gNoHpuaaQBPAaMaVYdQYHJLurzj8ECCj5OwTqA==", - "devOptional": true, - "requires": { - "tinyrainbow": "^2.0.0" - } - }, - "@vitest/runner": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.2.7.tgz", - "integrity": "sha512-sB9y4ovltoQP+WaUPwmSxO9WIg9Ig694Di5PalVPsYHklAdE027mehpWF2SQSVq+k6sFgaivbTjTJwZLSHbedA==", - "devOptional": true, - "requires": { - "@vitest/utils": "3.2.7", - "pathe": "^2.0.3", - "strip-literal": "^3.0.0" - } - }, - "@vitest/snapshot": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.2.7.tgz", - "integrity": "sha512-7C+MwShwtBSI5Buwoyg3s/iY1eHL9PKAf+O1wVh/TdnjXUtkoL/9YQtre90i4MtNXM6edP1wJ2zOBpfCyhIS7g==", - "devOptional": true, - "requires": { - "@vitest/pretty-format": "3.2.7", - "magic-string": "^0.30.17", - "pathe": "^2.0.3" - } - }, - "@vitest/spy": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.7.tgz", - "integrity": "sha512-Q2eQGI6d2L/hBtZ0qNuKcAGid68XK6cv1xsoaIma6PaJhHPoqcEJhYpXZ/5myCMqkNgtP6UKuBhbc0nHKnrkuQ==", - "devOptional": true, - "requires": { - "tinyspy": "^4.0.3" - } - }, - "@vitest/utils": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.2.7.tgz", - "integrity": "sha512-x6BDOd7dyo3PFLY3I9/HJ25X/6OurhGXk2/B9gOZNPF7XDVjeBK4k01lQE5uvDpbuheErh91qYuE1E2OEjK3Rw==", - "devOptional": true, - "requires": { - "@vitest/pretty-format": "3.2.7", - "loupe": "^3.1.4", - "tinyrainbow": "^2.0.0" - }, - "dependencies": { - "loupe": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.1.tgz", - "integrity": "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==", - "devOptional": true - } - } - }, - "@webassemblyjs/ast": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", - "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", - "requires": { - "@webassemblyjs/helper-numbers": "1.13.2", - "@webassemblyjs/helper-wasm-bytecode": "1.13.2" - } - }, - "@webassemblyjs/floating-point-hex-parser": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", - "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==" - }, - "@webassemblyjs/helper-api-error": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", - "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==" - }, - "@webassemblyjs/helper-buffer": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", - "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==" - }, - "@webassemblyjs/helper-numbers": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", - "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", - "requires": { - "@webassemblyjs/floating-point-hex-parser": "1.13.2", - "@webassemblyjs/helper-api-error": "1.13.2", - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", - "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==" - }, - "@webassemblyjs/helper-wasm-section": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", - "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", - "requires": { - "@webassemblyjs/ast": "1.14.1", - "@webassemblyjs/helper-buffer": "1.14.1", - "@webassemblyjs/helper-wasm-bytecode": "1.13.2", - "@webassemblyjs/wasm-gen": "1.14.1" - } - }, - "@webassemblyjs/ieee754": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", - "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", - "requires": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "@webassemblyjs/leb128": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", - "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", - "requires": { - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/utf8": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", - "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==" - }, - "@webassemblyjs/wasm-edit": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", - "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", - "requires": { - "@webassemblyjs/ast": "1.14.1", - "@webassemblyjs/helper-buffer": "1.14.1", - "@webassemblyjs/helper-wasm-bytecode": "1.13.2", - "@webassemblyjs/helper-wasm-section": "1.14.1", - "@webassemblyjs/wasm-gen": "1.14.1", - "@webassemblyjs/wasm-opt": "1.14.1", - "@webassemblyjs/wasm-parser": "1.14.1", - "@webassemblyjs/wast-printer": "1.14.1" - } - }, - "@webassemblyjs/wasm-gen": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", - "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", - "requires": { - "@webassemblyjs/ast": "1.14.1", - "@webassemblyjs/helper-wasm-bytecode": "1.13.2", - "@webassemblyjs/ieee754": "1.13.2", - "@webassemblyjs/leb128": "1.13.2", - "@webassemblyjs/utf8": "1.13.2" - } - }, - "@webassemblyjs/wasm-opt": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", - "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", - "requires": { - "@webassemblyjs/ast": "1.14.1", - "@webassemblyjs/helper-buffer": "1.14.1", - "@webassemblyjs/wasm-gen": "1.14.1", - "@webassemblyjs/wasm-parser": "1.14.1" - } - }, - "@webassemblyjs/wasm-parser": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", - "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", - "requires": { - "@webassemblyjs/ast": "1.14.1", - "@webassemblyjs/helper-api-error": "1.13.2", - "@webassemblyjs/helper-wasm-bytecode": "1.13.2", - "@webassemblyjs/ieee754": "1.13.2", - "@webassemblyjs/leb128": "1.13.2", - "@webassemblyjs/utf8": "1.13.2" - } - }, - "@webassemblyjs/wast-printer": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", - "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", - "requires": { - "@webassemblyjs/ast": "1.14.1", - "@xtuc/long": "4.2.2" - } - }, - "@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==" - }, - "@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" - }, - "@yarnpkg/lockfile": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", - "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==" - }, - "abbrev": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-4.0.0.tgz", - "integrity": "sha512-a1wflyaL0tHtJSmLSOVybYhy22vRih4eduhhrkcjgrWGnRfrZtovJ2FRjxuTtkkj47O/baf0R86QU5OuYpz8fA==" - }, - "accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "requires": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - } - }, - "acorn": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", - "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==" - }, - "acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "requires": {} - }, - "adjust-sourcemap-loader": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-4.0.0.tgz", - "integrity": "sha512-OXwN5b9pCUXNQHJpwwD2qP40byEmSgzj8B4ydSN0uMNYWiFmJ6x6KwUllMmfk8Rwu/HJDFR7U8ubsWBoN0Xp0A==", - "requires": { - "loader-utils": "^2.0.0", - "regex-parser": "^2.2.11" - } - }, - "agent-base": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", - "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==" - }, - "aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "optional": true, - "requires": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - } - }, - "ajv": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", - "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-formats": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", - "requires": { - "ajv": "^8.0.0" - }, - "dependencies": { - "ajv": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", - "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", - "requires": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - } - }, - "json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" - } - } - }, - "algoliasearch": { - "version": "5.35.0", - "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-5.35.0.tgz", - "integrity": "sha512-Y+moNhsqgLmvJdgTsO4GZNgsaDWv8AOGAaPeIeHKlDn/XunoAqYbA+XNpBd1dW8GOXAUDyxC9Rxc7AV4kpFcIg==", - "requires": { - "@algolia/abtesting": "1.1.0", - "@algolia/client-abtesting": "5.35.0", - "@algolia/client-analytics": "5.35.0", - "@algolia/client-common": "5.35.0", - "@algolia/client-insights": "5.35.0", - "@algolia/client-personalization": "5.35.0", - "@algolia/client-query-suggestions": "5.35.0", - "@algolia/client-search": "5.35.0", - "@algolia/ingestion": "1.35.0", - "@algolia/monitoring": "1.35.0", - "@algolia/recommend": "5.35.0", - "@algolia/requester-browser-xhr": "5.35.0", - "@algolia/requester-fetch": "5.35.0", - "@algolia/requester-node-http": "5.35.0" - } - }, - "ansi-colors": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", - "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==" - }, - "ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "optional": true, - "requires": { - "type-fest": "^0.21.3" - } - }, - "ansi-html-community": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", - "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==" - }, - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, - "anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "arch": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz", - "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==", - "optional": true - }, - "arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true - }, - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" - }, - "array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" - }, - "asn1": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", - "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", - "optional": true, - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", - "optional": true - }, - "assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "optional": true - }, - "astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "optional": true - }, - "async-each-series": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/async-each-series/-/async-each-series-0.1.1.tgz", - "integrity": "sha512-p4jj6Fws4Iy2m0iCmI2am2ZNZCgbdgE+P8F/8csmn2vx7ixXrO2zGcuNsD46X5uZSVecmkEy/M06X2vG8KD6dQ==", - "devOptional": true - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "optional": true - }, - "at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", - "optional": true - }, - "autoprefixer": { - "version": "10.4.21", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.21.tgz", - "integrity": "sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==", - "requires": { - "browserslist": "^4.24.4", - "caniuse-lite": "^1.0.30001702", - "fraction.js": "^4.3.7", - "normalize-range": "^0.1.2", - "picocolors": "^1.1.1", - "postcss-value-parser": "^4.2.0" - } - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", - "optional": true - }, - "aws4": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.13.2.tgz", - "integrity": "sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw==", - "optional": true - }, - "axios": { - "version": "1.13.5", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.5.tgz", - "integrity": "sha512-cz4ur7Vb0xS4/KUN0tPWe44eqxrIu31me+fbang3ijiNscE129POzipJJA6zniq2C/Z6sJCjMimjS8Lc/GAs8Q==", - "optional": true, - "requires": { - "follow-redirects": "^1.15.11", - "form-data": "^4.0.5", - "proxy-from-env": "^1.1.0" - }, - "dependencies": { - "proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "optional": true - } - } - }, - "babel-loader": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-10.0.0.tgz", - "integrity": "sha512-z8jt+EdS61AMw22nSfoNJAZ0vrtmhPRVi6ghL3rCeRZI8cdNYFiV5xeV3HbE7rlZZNmGH8BVccwWt8/ED0QOHA==", - "requires": { - "find-up": "^5.0.0" - }, - "dependencies": { - "find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "requires": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - } - }, - "locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "requires": { - "p-locate": "^5.0.0" - } - }, - "p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "requires": { - "p-limit": "^3.0.2" - } - } - } - }, - "babel-plugin-polyfill-corejs2": { - "version": "0.4.14", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.14.tgz", - "integrity": "sha512-Co2Y9wX854ts6U8gAAPXfn0GmAyctHuK8n0Yhfjd6t30g7yvKjspvvOo9yG+z52PZRgFErt7Ka2pYnXCjLKEpg==", - "requires": { - "@babel/compat-data": "^7.27.7", - "@babel/helper-define-polyfill-provider": "^0.6.5", - "semver": "^6.3.1" - }, - "dependencies": { - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" - } - } - }, - "babel-plugin-polyfill-corejs3": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.13.0.tgz", - "integrity": "sha512-U+GNwMdSFgzVmfhNm8GJUX88AadB3uo9KpJqS3FaqNIPKgySuvMb+bHPsOmmuWyIcuqZj/pzt1RUIUZns4y2+A==", - "requires": { - "@babel/helper-define-polyfill-provider": "^0.6.5", - "core-js-compat": "^3.43.0" - } - }, - "babel-plugin-polyfill-regenerator": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.5.tgz", - "integrity": "sha512-ISqQ2frbiNU9vIJkzg7dlPpznPZ4jOiUQ1uSmB0fEHeowtN3COYRsXr/xexn64NpU13P06jc/L5TgiJXOgrbEg==", - "requires": { - "@babel/helper-define-polyfill-provider": "^0.6.5" - } - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "devOptional": true - }, - "base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "optional": true - }, - "base64id": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", - "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==", - "devOptional": true - }, - "baseline-browser-mapping": { - "version": "2.9.19", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.19.tgz", - "integrity": "sha512-ipDqC8FrAl/76p2SSWKSI+H9tFwm7vYqXQrItCuiVPt26Km0jS+NzSsBWAaBusvSbQcfJG+JitdMm+wZAgTYqg==" - }, - "batch": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", - "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==" - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", - "optional": true, - "requires": { - "tweetnacl": "^0.14.3" - } - }, - "beasties": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/beasties/-/beasties-0.3.5.tgz", - "integrity": "sha512-NaWu+f4YrJxEttJSm16AzMIFtVldCvaJ68b1L098KpqXmxt9xOLtKoLkKxb8ekhOrLqEJAbvT6n6SEvB/sac7A==", - "requires": { - "css-select": "^6.0.0", - "css-what": "^7.0.0", - "dom-serializer": "^2.0.0", - "domhandler": "^5.0.3", - "htmlparser2": "^10.0.0", - "picocolors": "^1.1.1", - "postcss": "^8.4.49", - "postcss-media-query-parser": "^0.2.3" - } - }, - "bidi-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/bidi-js/-/bidi-js-1.0.3.tgz", - "integrity": "sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==", - "devOptional": true, - "requires": { - "require-from-string": "^2.0.2" - } - }, - "big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==" - }, - "binary-extensions": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", - "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==" - }, - "blob-util": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/blob-util/-/blob-util-2.0.2.tgz", - "integrity": "sha512-T7JQa+zsXXEa6/8ZhHcQEW1UFfVM49Ts65uBkFL6fz2QmrElqmbajIDJvuA0tEhRe5eIjpV9ZF+0RfZR9voJFQ==", - "optional": true - }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "optional": true - }, - "body-parser": { - "version": "1.20.4", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.4.tgz", - "integrity": "sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA==", - "requires": { - "bytes": "~3.1.2", - "content-type": "~1.0.5", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "~1.2.0", - "http-errors": "~2.0.1", - "iconv-lite": "~0.4.24", - "on-finished": "~2.4.1", - "qs": "~6.14.0", - "raw-body": "~2.5.3", - "type-is": "~1.6.18", - "unpipe": "~1.0.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "http-errors": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", - "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", - "requires": { - "depd": "~2.0.0", - "inherits": "~2.0.4", - "setprototypeof": "~1.2.0", - "statuses": "~2.0.2", - "toidentifier": "~1.0.1" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "requires": { - "ee-first": "1.1.1" - } - }, - "statuses": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", - "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==" - } - } - }, - "bonjour-service": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.3.0.tgz", - "integrity": "sha512-3YuAUiSkWykd+2Azjgyxei8OWf8thdn8AITIog2M4UICzoqfjlqr64WIjEXZllf/W6vK1goqleSR6brGomxQqA==", - "requires": { - "fast-deep-equal": "^3.1.3", - "multicast-dns": "^7.2.5" - } - }, - "boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" - }, - "bootstrap": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.6.2.tgz", - "integrity": "sha512-51Bbp/Uxr9aTuy6ca/8FbFloBUJZLHwnhTcnjIeRn2suQWsWzcuJhGjKDB5eppVte/8oCdOL3VuwxvZDUggwGQ==", - "requires": {} - }, - "brace-expansion": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", - "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", - "devOptional": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "requires": { - "fill-range": "^7.1.1" - } - }, - "browser-sync": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/browser-sync/-/browser-sync-3.0.3.tgz", - "integrity": "sha512-91hoBHKk1C4pGeD+oE9Ld222k2GNQEAsI5AElqR8iLLWNrmZR2LPP8B0h8dpld9u7kro5IEUB3pUb0DJ3n1cRQ==", - "devOptional": true, - "requires": { - "browser-sync-client": "^3.0.3", - "browser-sync-ui": "^3.0.3", - "bs-recipes": "1.3.4", - "chalk": "4.1.2", - "chokidar": "^3.5.1", - "connect": "3.6.6", - "connect-history-api-fallback": "^1", - "dev-ip": "^1.0.1", - "easy-extender": "^2.3.4", - "eazy-logger": "^4.0.1", - "etag": "^1.8.1", - "fresh": "^0.5.2", - "fs-extra": "3.0.1", - "http-proxy": "^1.18.1", - "immutable": "^3", - "micromatch": "^4.0.8", - "opn": "5.3.0", - "portscanner": "2.2.0", - "raw-body": "^2.3.2", - "resp-modifier": "6.0.2", - "rx": "4.1.0", - "send": "^0.19.0", - "serve-index": "^1.9.1", - "serve-static": "^1.16.2", - "server-destroy": "1.0.1", - "socket.io": "^4.4.1", - "ua-parser-js": "^1.0.33", - "yargs": "^17.3.1" - }, - "dependencies": { - "cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "devOptional": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - } - }, - "fs-extra": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-3.0.1.tgz", - "integrity": "sha512-V3Z3WZWVUYd8hoCL5xfXJCaHWYzmtwW5XWYSlLgERi8PWd8bx1kUHUk8L1BT57e49oKnDDD180mjfrHc1yA9rg==", - "devOptional": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^3.0.0", - "universalify": "^0.1.0" - } - }, - "jsonfile": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-3.0.1.tgz", - "integrity": "sha512-oBko6ZHlubVB5mRFkur5vgYR1UyqX+S6Y/oCfLhqNdcc2fYFlDpIoNc7AfKS1KOGcnNAkvsr0grLck9ANM815w==", - "devOptional": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "ua-parser-js": { - "version": "1.0.36", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.36.tgz", - "integrity": "sha512-znuyCIXzl8ciS3+y3fHJI/2OhQIXbXw9MWC/o3qwyR+RGppjZHrM27CGFSKCJXi2Kctiz537iOu2KnXs1lMQhw==", - "devOptional": true - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "devOptional": true - }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "devOptional": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "devOptional": true - }, - "yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "devOptional": true, - "requires": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - } - }, - "yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "devOptional": true - } - } - }, - "browser-sync-client": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/browser-sync-client/-/browser-sync-client-3.0.3.tgz", - "integrity": "sha512-TOEXaMgYNjBYIcmX5zDlOdjEqCeCN/d7opf/fuyUD/hhGVCfP54iQIDhENCi012AqzYZm3BvuFl57vbwSTwkSQ==", - "devOptional": true, - "requires": { - "etag": "1.8.1", - "fresh": "0.5.2", - "mitt": "^1.1.3" - } - }, - "browser-sync-ui": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/browser-sync-ui/-/browser-sync-ui-3.0.3.tgz", - "integrity": "sha512-FcGWo5lP5VodPY6O/f4pXQy5FFh4JK0f2/fTBsp0Lx1NtyBWs/IfPPJbW8m1ujTW/2r07oUXKTF2LYZlCZktjw==", - "devOptional": true, - "requires": { - "async-each-series": "0.1.1", - "chalk": "4.1.2", - "connect-history-api-fallback": "^1", - "immutable": "^3", - "server-destroy": "1.0.1", - "socket.io-client": "^4.4.1", - "stream-throttle": "^0.1.3" - } - }, - "browserslist": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", - "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", - "requires": { - "baseline-browser-mapping": "^2.9.0", - "caniuse-lite": "^1.0.30001759", - "electron-to-chromium": "^1.5.263", - "node-releases": "^2.0.27", - "update-browserslist-db": "^1.2.0" - } - }, - "bs-recipes": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/bs-recipes/-/bs-recipes-1.3.4.tgz", - "integrity": "sha512-BXvDkqhDNxXEjeGM8LFkSbR+jzmP/CYpCiVKYn+soB1dDldeU15EBNDkwVXndKuX35wnNUaPd0qSoQEAkmQtMw==", - "devOptional": true - }, - "buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "optional": true, - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", - "optional": true - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" - }, - "bundle-name": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", - "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", - "requires": { - "run-applescript": "^7.0.0" - } - }, - "bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" - }, - "cac": { - "version": "6.7.14", - "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", - "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", - "devOptional": true - }, - "cacache": { - "version": "20.0.3", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-20.0.3.tgz", - "integrity": "sha512-3pUp4e8hv07k1QlijZu6Kn7c9+ZpWWk4j3F8N3xPuCExULobqJydKYOTj1FTq58srkJsXvO7LbGAH4C0ZU3WGw==", - "requires": { - "@npmcli/fs": "^5.0.0", - "fs-minipass": "^3.0.0", - "glob": "^13.0.0", - "lru-cache": "^11.1.0", - "minipass": "^7.0.3", - "minipass-collect": "^2.0.1", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "p-map": "^7.0.2", - "ssri": "^13.0.0", - "unique-filename": "^5.0.0" - }, - "dependencies": { - "p-map": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-7.0.4.tgz", - "integrity": "sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ==" - } - } - }, - "cachedir": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.3.0.tgz", - "integrity": "sha512-A+Fezp4zxnit6FanDmv9EqXNAi3vt9DWp51/71UEhXukb7QUuvtv9344h91dyAxuTLoSYJFU299qzR3tzwPAhw==", - "optional": true - }, - "call-bind-apply-helpers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", - "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", - "requires": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2" - } - }, - "call-bound": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", - "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", - "requires": { - "call-bind-apply-helpers": "^1.0.2", - "get-intrinsic": "^1.3.0" - } - }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" - }, - "caniuse-lite": { - "version": "1.0.30001770", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001770.tgz", - "integrity": "sha512-x/2CLQ1jHENRbHg5PSId2sXq1CIO1CISvwWAj027ltMVG2UNgW+w9oH2+HzgEIRFembL8bUlXtfbBHR1fCg2xw==" - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", - "optional": true - }, - "chai": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.5.0.tgz", - "integrity": "sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==", - "optional": true, - "requires": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.3", - "deep-eql": "^4.1.3", - "get-func-name": "^2.0.2", - "loupe": "^2.3.6", - "pathval": "^1.1.1", - "type-detect": "^4.1.0" - }, - "dependencies": { - "type-detect": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", - "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", - "optional": true - } - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "devOptional": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "chardet": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-2.1.1.tgz", - "integrity": "sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==" - }, - "check-error": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", - "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", - "optional": true, - "requires": { - "get-func-name": "^2.0.2" - } - }, - "check-more-types": { - "version": "2.24.0", - "resolved": "https://registry.npmjs.org/check-more-types/-/check-more-types-2.24.0.tgz", - "integrity": "sha1-FCD/sQ/URNz8ebQ4kbv//TKoRgA=", - "optional": true - }, - "chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "requires": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "fsevents": "~2.3.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - } - }, - "chownr": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", - "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==" - }, - "chrome-trace-event": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", - "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==" - }, - "ci-info": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.1.0.tgz", - "integrity": "sha512-HutrvTNsF48wnxkzERIXOe5/mlcfFcbfCmwcg6CJnizbSue78AbDt+1cgl26zwn61WFxhcPykPfZrbqjGmBb4A==", - "optional": true - }, - "clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "optional": true - }, - "cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "optional": true, - "requires": { - "restore-cursor": "^3.1.0" - } - }, - "cli-spinners": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", - "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==" - }, - "cli-table3": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.1.tgz", - "integrity": "sha512-w0q/enDHhPLq44ovMGdQeeDLvwxwavsJX7oQGYt/LrBlYsyaxyDnp6z3QzFut/6kLLKnlcUVJLrpB7KBfgG/RA==", - "optional": true, - "requires": { - "colors": "1.4.0", - "string-width": "^4.2.0" - } - }, - "cli-truncate": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", - "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", - "optional": true, - "requires": { - "slice-ansi": "^3.0.0", - "string-width": "^4.2.0" - } - }, - "cli-width": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", - "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==" - }, - "clipboard": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.11.tgz", - "integrity": "sha512-C+0bbOqkezLIsmWSvlsXS0Q0bmkugu7jcfMIACB+RDEntIzQIkdr148we28AfSloQLRdZlYL/QYyrq05j/3Faw==", - "requires": { - "good-listener": "^1.2.2", - "select": "^1.1.2", - "tiny-emitter": "^2.0.0" - } - }, - "cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" - } - }, - "clone-deep": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", - "requires": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "colorette": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==" - }, - "colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", - "optional": true - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "optional": true, - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" - }, - "common-tags": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.0.tgz", - "integrity": "sha512-6P6g0uetGpW/sdyUy/iQQCbFF0kWVMSIVSyYz7Zgjcgh8mgw8PQzDNZeyZ5DQ2gM7LBoZPHmnjz8rUthkBG5tw==", - "optional": true - }, - "compressible": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", - "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", - "requires": { - "mime-db": ">= 1.43.0 < 2" - } - }, - "compression": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.8.1.tgz", - "integrity": "sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w==", - "requires": { - "bytes": "3.1.2", - "compressible": "~2.0.18", - "debug": "2.6.9", - "negotiator": "~0.6.4", - "on-headers": "~1.1.0", - "safe-buffer": "5.2.1", - "vary": "~1.1.2" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "negotiator": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", - "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==" - } - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "devOptional": true - }, - "connect": { - "version": "3.6.6", - "resolved": "https://registry.npmjs.org/connect/-/connect-3.6.6.tgz", - "integrity": "sha512-OO7axMmPpu/2XuX1+2Yrg0ddju31B6xLZMWkJ5rYBu4YRmRVlOjvlY6kw2FJKiAzyxGwnrDUAG4s1Pf0sbBMCQ==", - "devOptional": true, - "requires": { - "debug": "2.6.9", - "finalhandler": "1.1.0", - "parseurl": "~1.3.2", - "utils-merge": "1.0.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "devOptional": true, - "requires": { - "ms": "2.0.0" - } - }, - "finalhandler": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz", - "integrity": "sha512-ejnvM9ZXYzp6PUPUyQBMBf0Co5VX2gr5H2VQe2Ui2jWXNlxv+PYZo8wpAymJNJdLsG1R4p+M4aynF8KuoUEwRw==", - "devOptional": true, - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.1", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.2", - "statuses": "~1.3.1", - "unpipe": "~1.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "devOptional": true - }, - "statuses": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", - "integrity": "sha512-wuTCPGlJONk/a1kqZ4fQM2+908lC7fa7nPYpTC1EhnvqLX/IICbeP1OZGDtA374trpSq68YubKUMo8oRhN46yg==", - "devOptional": true - } - } - }, - "connect-history-api-fallback": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz", - "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==", - "devOptional": true - }, - "content-disposition": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.1.tgz", - "integrity": "sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==" - }, - "content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==" - }, - "convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" - }, - "cookie": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", - "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==" - }, - "cookie-signature": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", - "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==" - }, - "copy-anything": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-2.0.6.tgz", - "integrity": "sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==", - "requires": { - "is-what": "^3.14.1" - } - }, - "copy-webpack-plugin": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-14.0.0.tgz", - "integrity": "sha512-3JLW90aBGeaTLpM7mYQKpnVdgsUZRExY55giiZgLuX/xTQRUs1dOCwbBnWnvY6Q6rfZoXMNwzOQJCSZPppfqXA==", - "requires": { - "glob-parent": "^6.0.1", - "normalize-path": "^3.0.0", - "schema-utils": "^4.2.0", - "serialize-javascript": "^7.0.3", - "tinyglobby": "^0.2.12" - }, - "dependencies": { - "glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "requires": { - "is-glob": "^4.0.3" - } - } - } - }, - "core-js-compat": { - "version": "3.46.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.46.0.tgz", - "integrity": "sha512-p9hObIIEENxSV8xIu+V68JjSeARg6UVMG5mR+JEUguG3sI6MsiS1njz2jHmyJDvA+8jX/sytkBHup6kxhM9law==", - "requires": { - "browserslist": "^4.26.3" - } - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", - "requires": { - "object-assign": "^4", - "vary": "^1" - } - }, - "cosmiconfig": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", - "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", - "requires": { - "env-paths": "^2.2.1", - "import-fresh": "^3.3.0", - "js-yaml": "^4.1.0", - "parse-json": "^5.2.0" - } - }, - "create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true - }, - "cross-spawn": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "css-loader": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-7.1.2.tgz", - "integrity": "sha512-6WvYYn7l/XEGN8Xu2vWFt9nVzrCn39vKyTEFf/ExEyoksJjjSZV/0/35XPlMbpnr6VGhZIUg5yJrL8tGfes/FA==", - "requires": { - "icss-utils": "^5.1.0", - "postcss": "^8.4.33", - "postcss-modules-extract-imports": "^3.1.0", - "postcss-modules-local-by-default": "^4.0.5", - "postcss-modules-scope": "^3.2.0", - "postcss-modules-values": "^4.0.0", - "postcss-value-parser": "^4.2.0", - "semver": "^7.5.4" - } - }, - "css-select": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-6.0.0.tgz", - "integrity": "sha512-rZZVSLle8v0+EY8QAkDWrKhpgt6SA5OtHsgBnsj6ZaLb5dmDVOWUDtQitd9ydxxvEjhewNudS6eTVU7uOyzvXw==", - "requires": { - "boolbase": "^1.0.0", - "css-what": "^7.0.0", - "domhandler": "^5.0.3", - "domutils": "^3.2.2", - "nth-check": "^2.1.1" - } - }, - "css-tree": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.2.1.tgz", - "integrity": "sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==", - "devOptional": true, - "requires": { - "mdn-data": "2.27.1", - "source-map-js": "^1.2.1" - } - }, - "css-what": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-7.0.0.tgz", - "integrity": "sha512-wD5oz5xibMOPHzy13CyGmogB3phdvcDaB5t0W/Nr5Z2O/agcB8YwOz6e2Lsp10pNDzBoDO9nVa3RGs/2BttpHQ==" - }, - "cssesc": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==" - }, - "cypress": { - "version": "15.9.0", - "resolved": "https://registry.npmjs.org/cypress/-/cypress-15.9.0.tgz", - "integrity": "sha512-Ks6Bdilz3TtkLZtTQyqYaqtL/WT3X3APKaSLhTV96TmTyudzSjc6EJsJCHmBb7DxO+3R12q3Jkbjgm/iPgmwfg==", - "optional": true, - "requires": { - "@cypress/request": "^3.0.10", - "@cypress/xvfb": "^1.2.4", - "@types/sinonjs__fake-timers": "8.1.1", - "@types/sizzle": "^2.3.2", - "@types/tmp": "^0.2.3", - "arch": "^2.2.0", - "blob-util": "^2.0.2", - "bluebird": "^3.7.2", - "buffer": "^5.7.1", - "cachedir": "^2.3.0", - "chalk": "^4.1.0", - "ci-info": "^4.1.0", - "cli-cursor": "^3.1.0", - "cli-table3": "0.6.1", - "commander": "^6.2.1", - "common-tags": "^1.8.0", - "dayjs": "^1.10.4", - "debug": "^4.3.4", - "enquirer": "^2.3.6", - "eventemitter2": "6.4.7", - "execa": "4.1.0", - "executable": "^4.1.1", - "extract-zip": "2.0.1", - "figures": "^3.2.0", - "fs-extra": "^9.1.0", - "hasha": "5.2.2", - "is-installed-globally": "~0.4.0", - "listr2": "^3.8.3", - "lodash": "^4.17.21", - "log-symbols": "^4.0.0", - "minimist": "^1.2.8", - "ospath": "^1.2.2", - "pretty-bytes": "^5.6.0", - "process": "^0.11.10", - "proxy-from-env": "1.0.0", - "request-progress": "^3.0.0", - "supports-color": "^8.1.1", - "systeminformation": "^5.27.14", - "tmp": "~0.2.4", - "tree-kill": "1.2.2", - "untildify": "^4.0.0", - "yauzl": "^2.10.0" - }, - "dependencies": { - "commander": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", - "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", - "optional": true - }, - "execa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", - "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", - "optional": true, - "requires": { - "cross-spawn": "^7.0.0", - "get-stream": "^5.0.0", - "human-signals": "^1.1.1", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.0", - "onetime": "^5.1.0", - "signal-exit": "^3.0.2", - "strip-final-newline": "^2.0.0" - } - }, - "fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "optional": true, - "requires": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - }, - "get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "optional": true, - "requires": { - "pump": "^3.0.0" - } - }, - "supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "optional": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "tmp": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.5.tgz", - "integrity": "sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==", - "optional": true - } - } - }, - "cypress-fail-on-console-error": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/cypress-fail-on-console-error/-/cypress-fail-on-console-error-5.1.1.tgz", - "integrity": "sha512-JGpHxvwuSxDDT32cUflo0x7yJBFdhYsv5MVBPmNv/kulavQcl0cSguDtSpwWXhBXr1oBSzYUsQkxGnAN4EDqWA==", - "optional": true, - "requires": { - "chai": "^4.3.10", - "sinon": "^17.0.0", - "sinon-chai": "^3.7.0", - "type-detect": "^4.0.8" - } - }, - "cypress-wait-until": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/cypress-wait-until/-/cypress-wait-until-3.0.2.tgz", - "integrity": "sha512-iemies796dD5CgjG5kV0MnpEmKSH+s7O83ZoJLVzuVbZmm4lheMsZqAVT73hlMx4QlkwhxbyUzhOBUOZwoOe0w==", - "optional": true - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", - "optional": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, - "data-urls": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-7.0.0.tgz", - "integrity": "sha512-23XHcCF+coGYevirZceTVD7NdJOqVn+49IHyxgszm+JIiHLoB2TkmPtsYkNWT1pvRSGkc35L6NHs0yHkN2SumA==", - "devOptional": true, - "requires": { - "whatwg-mimetype": "^5.0.0", - "whatwg-url": "^16.0.0" - }, - "dependencies": { - "whatwg-url": { - "version": "16.0.1", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-16.0.1.tgz", - "integrity": "sha512-1to4zXBxmXHV3IiSSEInrreIlu02vUOvrhxJJH5vcxYTBDAx51cqZiKdyTxlecdKNSjj8EcxGBxNf6Vg+945gw==", - "devOptional": true, - "requires": { - "@exodus/bytes": "^1.11.0", - "tr46": "^6.0.0", - "webidl-conversions": "^8.0.1" - } - } - } - }, - "dayjs": { - "version": "1.11.9", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.9.tgz", - "integrity": "sha512-QvzAURSbQ0pKdIye2txOzNaHmxtUBXerpY0FJsFXUMKbIZeFm5ht1LS/jFsrncjnmtv8HsG0W2g6c0zUjZWmpA==", - "optional": true - }, - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "requires": { - "ms": "2.1.2" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" - }, - "decimal.js": { - "version": "10.6.0", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz", - "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==", - "devOptional": true - }, - "deep-eql": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", - "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", - "optional": true, - "requires": { - "type-detect": "^4.0.0" - } - }, - "deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "default-browser": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.5.0.tgz", - "integrity": "sha512-H9LMLr5zwIbSxrmvikGuI/5KGhZ8E2zH3stkMgM5LpOWDutGM2JZaj460Udnf1a+946zc7YBgrqEWwbk7zHvGw==", - "requires": { - "bundle-name": "^4.1.0", - "default-browser-id": "^5.0.0" - } - }, - "default-browser-id": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.1.tgz", - "integrity": "sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==" - }, - "define-lazy-prop": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", - "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==" - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "optional": true - }, - "delegate": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/delegate/-/delegate-3.2.0.tgz", - "integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==" - }, - "depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" - }, - "destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==" - }, - "detect-libc": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", - "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", - "optional": true - }, - "detect-node": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", - "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==" - }, - "dev-ip": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/dev-ip/-/dev-ip-1.0.1.tgz", - "integrity": "sha512-LmVkry/oDShEgSZPNgqCIp2/TlqtExeGmymru3uCELnfyjY11IzpAproLYs+1X88fXO6DBoYP3ul2Xo2yz2j6A==", - "devOptional": true - }, - "diff": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.4.tgz", - "integrity": "sha512-X07nttJQkwkfKfvTPG/KSnE2OMdcUCao6+eXF3wmnIQRn2aPAHH3VxDbDOdegkd6JbPsXqShpvEOHfAT+nCNwQ==", - "dev": true - }, - "dijkstrajs": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/dijkstrajs/-/dijkstrajs-1.0.1.tgz", - "integrity": "sha1-082BIh4+pAdCz83lVtTpnpjdxxs=" - }, - "dns-packet": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", - "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", - "requires": { - "@leichtgewicht/ip-codec": "^2.0.1" - } - }, - "dom-serializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", - "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", - "requires": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.2", - "entities": "^4.2.0" - } - }, - "domelementtype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", - "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==" - }, - "domhandler": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", - "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", - "requires": { - "domelementtype": "^2.3.0" - } - }, - "domino": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/domino/-/domino-2.1.6.tgz", - "integrity": "sha512-3VdM/SXBZX2omc9JF9nOPCtDaYQ67BGp5CoLpIQlO2KCAPETs8TcDHacF26jXadGbvUteZzRTeos2fhID5+ucQ==" - }, - "domutils": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", - "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", - "requires": { - "dom-serializer": "^2.0.0", - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3" - } - }, - "dunder-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", - "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", - "requires": { - "call-bind-apply-helpers": "^1.0.1", - "es-errors": "^1.3.0", - "gopd": "^1.2.0" - } - }, - "duplexer": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", - "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", - "optional": true - }, - "easy-extender": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/easy-extender/-/easy-extender-2.3.4.tgz", - "integrity": "sha512-8cAwm6md1YTiPpOvDULYJL4ZS6WfM5/cTeVVh4JsvyYZAoqlRVUpHL9Gr5Fy7HA6xcSZicUia3DeAgO3Us8E+Q==", - "devOptional": true, - "requires": { - "lodash": "^4.17.10" - } - }, - "eazy-logger": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/eazy-logger/-/eazy-logger-4.1.0.tgz", - "integrity": "sha512-+mn7lRm+Zf1UT/YaH8WXtpU6PIV2iOjzP6jgKoiaq/VNrjYKp+OHZGe2znaLgDeFkw8cL9ffuaUm+nNnzcYyGw==", - "devOptional": true, - "requires": { - "chalk": "4.1.2" - } - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", - "optional": true, - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "echarts": { - "version": "5.4.3", - "resolved": "https://registry.npmjs.org/echarts/-/echarts-5.4.3.tgz", - "integrity": "sha512-mYKxLxhzy6zyTi/FaEbJMOZU1ULGEQHaeIeuMR5L+JnJTpz+YR03mnnpBhbR4+UYJAgiXgpyTVLffPAjOTLkZA==", - "requires": { - "tslib": "2.3.0", - "zrender": "5.4.4" - }, - "dependencies": { - "tslib": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", - "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==" - } - } - }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" - }, - "electron-to-chromium": { - "version": "1.5.286", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.286.tgz", - "integrity": "sha512-9tfDXhJ4RKFNerfjdCcZfufu49vg620741MNs26a9+bhLThdB+plgMeou98CAaHu/WATj2iHOOHTp1hWtABj2A==" - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==" - }, - "encode-utf8": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/encode-utf8/-/encode-utf8-1.0.3.tgz", - "integrity": "sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw==" - }, - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" - }, - "encoding": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", - "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", - "optional": true, - "requires": { - "iconv-lite": "^0.6.2" - }, - "dependencies": { - "iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "optional": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - } - } - } - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "optional": true, - "requires": { - "once": "^1.4.0" - } - }, - "engine.io": { - "version": "6.6.2", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.6.2.tgz", - "integrity": "sha512-gmNvsYi9C8iErnZdVcJnvCpSKbWTt1E8+JZo8b+daLninywUWi5NQ5STSHZ9rFjFO7imNcvb8Pc5pe/wMR5xEw==", - "devOptional": true, - "requires": { - "@types/cookie": "^0.4.1", - "@types/cors": "^2.8.12", - "@types/node": ">=10.0.0", - "accepts": "~1.3.4", - "base64id": "2.0.0", - "cookie": "~0.7.2", - "cors": "~2.8.5", - "debug": "~4.3.1", - "engine.io-parser": "~5.2.1", - "ws": "~8.17.1" - } - }, - "engine.io-client": { - "version": "6.6.1", - "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.6.1.tgz", - "integrity": "sha512-aYuoak7I+R83M/BBPIOs2to51BmFIpC1wZe6zZzMrT2llVsHy5cvcmdsJgP2Qz6smHu+sD9oexiSUAVd8OfBPw==", - "devOptional": true, - "requires": { - "@socket.io/component-emitter": "~3.1.0", - "debug": "~4.3.1", - "engine.io-parser": "~5.2.1", - "ws": "~8.17.1", - "xmlhttprequest-ssl": "~2.1.1" - } - }, - "engine.io-parser": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz", - "integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==", - "devOptional": true - }, - "enhanced-resolve": { - "version": "5.19.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.19.0.tgz", - "integrity": "sha512-phv3E1Xl4tQOShqSte26C7Fl84EwUdZsyOuSSk9qtAGyyQs2s3jJzComh+Abf4g187lUUAvH+H26omrqia2aGg==", - "requires": { - "graceful-fs": "^4.2.4", - "tapable": "^2.3.0" - } - }, - "enquirer": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", - "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", - "optional": true, - "requires": { - "ansi-colors": "^4.1.1", - "strip-ansi": "^6.0.1" - } - }, - "entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==" - }, - "env-paths": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", - "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==" - }, - "environment": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", - "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==" - }, - "err-code": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", - "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==" - }, - "errno": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", - "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", - "optional": true, - "requires": { - "prr": "~1.0.1" - } - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "es-define-property": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", - "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==" - }, - "es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==" - }, - "es-module-lexer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.0.0.tgz", - "integrity": "sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==" - }, - "es-object-atoms": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", - "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", - "requires": { - "es-errors": "^1.3.0" - } - }, - "es-set-tostringtag": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", - "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", - "optional": true, - "requires": { - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.6", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.2" - } - }, - "esbuild": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.9.tgz", - "integrity": "sha512-CRbODhYyQx3qp7ZEwzxOk4JBqmD/seJrzPa/cGjY1VtIn5E09Oi9/dB4JwctnfZ8Q8iT7rioVv5k/FNT/uf54g==", - "requires": { - "@esbuild/aix-ppc64": "0.25.9", - "@esbuild/android-arm": "0.25.9", - "@esbuild/android-arm64": "0.25.9", - "@esbuild/android-x64": "0.25.9", - "@esbuild/darwin-arm64": "0.25.9", - "@esbuild/darwin-x64": "0.25.9", - "@esbuild/freebsd-arm64": "0.25.9", - "@esbuild/freebsd-x64": "0.25.9", - "@esbuild/linux-arm": "0.25.9", - "@esbuild/linux-arm64": "0.25.9", - "@esbuild/linux-ia32": "0.25.9", - "@esbuild/linux-loong64": "0.25.9", - "@esbuild/linux-mips64el": "0.25.9", - "@esbuild/linux-ppc64": "0.25.9", - "@esbuild/linux-riscv64": "0.25.9", - "@esbuild/linux-s390x": "0.25.9", - "@esbuild/linux-x64": "0.25.9", - "@esbuild/netbsd-arm64": "0.25.9", - "@esbuild/netbsd-x64": "0.25.9", - "@esbuild/openbsd-arm64": "0.25.9", - "@esbuild/openbsd-x64": "0.25.9", - "@esbuild/openharmony-arm64": "0.25.9", - "@esbuild/sunos-x64": "0.25.9", - "@esbuild/win32-arm64": "0.25.9", - "@esbuild/win32-ia32": "0.25.9", - "@esbuild/win32-x64": "0.25.9" - } - }, - "esbuild-wasm": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/esbuild-wasm/-/esbuild-wasm-0.25.9.tgz", - "integrity": "sha512-Jpv5tCSwQg18aCqCRD3oHIX/prBhXMDapIoG//A+6+dV0e7KQMGFg85ihJ5T1EeMjbZjON3TqFy0VrGAnIHLDA==" - }, - "escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==" - }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "optional": true - }, - "eslint": { - "version": "9.39.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.0.tgz", - "integrity": "sha512-iy2GE3MHrYTL5lrCtMZ0X1KLEKKUjmK0kzwcnefhR66txcEmXZD2YWgR5GNdcEwkNx3a0siYkSvl0vIC+Svjmg==", - "dev": true, - "requires": { - "@eslint-community/eslint-utils": "^4.8.0", - "@eslint-community/regexpp": "^4.12.1", - "@eslint/config-array": "^0.21.1", - "@eslint/config-helpers": "^0.4.2", - "@eslint/core": "^0.17.0", - "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "9.39.0", - "@eslint/plugin-kit": "^0.4.1", - "@humanfs/node": "^0.16.6", - "@humanwhocodes/module-importer": "^1.0.1", - "@humanwhocodes/retry": "^0.4.2", - "@types/estree": "^1.0.6", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.6", - "debug": "^4.3.2", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^8.4.0", - "eslint-visitor-keys": "^4.2.1", - "espree": "^10.4.0", - "esquery": "^1.5.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^8.0.0", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3" - }, - "dependencies": { - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true - }, - "eslint-scope": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", - "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - } - }, - "eslint-visitor-keys": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", - "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", - "dev": true - }, - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - }, - "find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "requires": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - } - }, - "glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "requires": { - "is-glob": "^4.0.3" - } - }, - "ignore": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", - "dev": true - }, - "locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "requires": { - "p-locate": "^5.0.0" - } - }, - "p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "requires": { - "p-limit": "^3.0.2" - } - } - } - }, - "eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - } - }, - "eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true - }, - "espree": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", - "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", - "dev": true, - "requires": { - "acorn": "^8.15.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^4.2.1" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", - "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", - "dev": true - } - } - }, - "esquery": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", - "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", - "dev": true, - "requires": { - "estraverse": "^5.1.0" - }, - "dependencies": { - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - } - } - }, - "esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "requires": { - "estraverse": "^5.2.0" - }, - "dependencies": { - "estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==" - } - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==" - }, - "estree-walker": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", - "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", - "devOptional": true, - "requires": { - "@types/estree": "^1.0.0" - } - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" - }, - "etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==" - }, - "event-stream": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz", - "integrity": "sha1-SrTJoPWlTbkzi0w02Gv86PSzVXE=", - "optional": true, - "requires": { - "duplexer": "~0.1.1", - "from": "~0", - "map-stream": "~0.1.0", - "pause-stream": "0.0.11", - "split": "0.3", - "stream-combiner": "~0.0.4", - "through": "~2.3.1" - }, - "dependencies": { - "stream-combiner": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz", - "integrity": "sha1-TV5DPBhSYd3mI8o/RMWGvPXErRQ=", - "optional": true, - "requires": { - "duplexer": "~0.1.1" - } - } - } - }, - "eventemitter2": { - "version": "6.4.7", - "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.7.tgz", - "integrity": "sha512-tYUSVOGeQPKt/eC1ABfhHy5Xd96N3oIijJvN3O9+TsC28T5V9yX9oEfEK5faP0EFSNVOG97qtAS68GBrQB2hDg==", - "optional": true - }, - "eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" - }, - "events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==" - }, - "eventsource": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-3.0.7.tgz", - "integrity": "sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==", - "requires": { - "eventsource-parser": "^3.0.1" - } - }, - "eventsource-parser": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.6.tgz", - "integrity": "sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==" - }, - "execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "optional": true, - "requires": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - }, - "dependencies": { - "human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "optional": true - } - } - }, - "executable": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/executable/-/executable-4.1.1.tgz", - "integrity": "sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==", - "optional": true, - "requires": { - "pify": "^2.2.0" - } - }, - "expect-type": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.4.0.tgz", - "integrity": "sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==", - "devOptional": true - }, - "exponential-backoff": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.3.tgz", - "integrity": "sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA==" - }, - "express": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz", - "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==", - "requires": { - "accepts": "^2.0.0", - "body-parser": "^2.2.1", - "content-disposition": "^1.0.0", - "content-type": "^1.0.5", - "cookie": "^0.7.1", - "cookie-signature": "^1.2.1", - "debug": "^4.4.0", - "depd": "^2.0.0", - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "etag": "^1.8.1", - "finalhandler": "^2.1.0", - "fresh": "^2.0.0", - "http-errors": "^2.0.0", - "merge-descriptors": "^2.0.0", - "mime-types": "^3.0.0", - "on-finished": "^2.4.1", - "once": "^1.4.0", - "parseurl": "^1.3.3", - "proxy-addr": "^2.0.7", - "qs": "^6.14.0", - "range-parser": "^1.2.1", - "router": "^2.2.0", - "send": "^1.1.0", - "serve-static": "^2.2.0", - "statuses": "^2.0.1", - "type-is": "^2.0.1", - "vary": "^1.1.2" - }, - "dependencies": { - "accepts": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", - "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", - "requires": { - "mime-types": "^3.0.0", - "negotiator": "^1.0.0" - } - }, - "body-parser": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.2.tgz", - "integrity": "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==", - "requires": { - "bytes": "^3.1.2", - "content-type": "^1.0.5", - "debug": "^4.4.3", - "http-errors": "^2.0.0", - "iconv-lite": "^0.7.0", - "on-finished": "^2.4.1", - "qs": "^6.14.1", - "raw-body": "^3.0.1", - "type-is": "^2.0.1" - } - }, - "debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "requires": { - "ms": "^2.1.3" - } - }, - "encodeurl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", - "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==" - }, - "fresh": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", - "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==" - }, - "http-errors": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", - "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", - "requires": { - "depd": "~2.0.0", - "inherits": "~2.0.4", - "setprototypeof": "~1.2.0", - "statuses": "~2.0.2", - "toidentifier": "~1.0.1" - } - }, - "iconv-lite": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz", - "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==", - "requires": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - } - }, - "media-typer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", - "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==" - }, - "mime-db": { - "version": "1.54.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", - "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==" - }, - "mime-types": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", - "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", - "requires": { - "mime-db": "^1.54.0" - } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "negotiator": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", - "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==" - }, - "on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "requires": { - "ee-first": "1.1.1" - } - }, - "raw-body": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz", - "integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==", - "requires": { - "bytes": "~3.1.2", - "http-errors": "~2.0.1", - "iconv-lite": "~0.7.0", - "unpipe": "~1.0.0" - } - }, - "send": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz", - "integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==", - "requires": { - "debug": "^4.4.3", - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "etag": "^1.8.1", - "fresh": "^2.0.0", - "http-errors": "^2.0.1", - "mime-types": "^3.0.2", - "ms": "^2.1.3", - "on-finished": "^2.4.1", - "range-parser": "^1.2.1", - "statuses": "^2.0.2" - } - }, - "serve-static": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz", - "integrity": "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==", - "requires": { - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "parseurl": "^1.3.3", - "send": "^1.2.0" - } - }, - "statuses": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", - "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==" - }, - "type-is": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", - "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", - "requires": { - "content-type": "^1.0.5", - "media-typer": "^1.1.0", - "mime-types": "^3.0.0" - } - } - } - }, - "express-rate-limit": { - "version": "8.3.1", - "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.3.1.tgz", - "integrity": "sha512-D1dKN+cmyPWuvB+G2SREQDzPY1agpBIcTa9sJxOPMCNeH3gwzhqJRDWCXW3gg0y//+LQ/8j52JbMROWyrKdMdw==", - "requires": { - "ip-address": "10.1.0" - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "optional": true - }, - "extract-zip": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", - "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", - "optional": true, - "requires": { - "@types/yauzl": "^2.9.1", - "debug": "^4.1.1", - "get-stream": "^5.1.0", - "yauzl": "^2.10.0" - }, - "dependencies": { - "get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "optional": true, - "requires": { - "pump": "^3.0.0" - } - } - } - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", - "optional": true - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - }, - "fast-glob": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", - "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", - "requires": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.8" - } - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true - }, - "fast-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", - "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==" - }, - "fastq": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", - "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", - "requires": { - "reusify": "^1.0.4" - } - }, - "faye-websocket": { - "version": "0.11.4", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", - "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", - "requires": { - "websocket-driver": ">=0.5.1" - } - }, - "fd-slicer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", - "optional": true, - "requires": { - "pend": "~1.2.0" - } - }, - "figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", - "optional": true, - "requires": { - "escape-string-regexp": "^1.0.5" - } - }, - "file-entry-cache": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", - "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", - "dev": true, - "requires": { - "flat-cache": "^4.0.0" - } - }, - "fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "finalhandler": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz", - "integrity": "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==", - "requires": { - "debug": "^4.4.0", - "encodeurl": "^2.0.0", - "escape-html": "^1.0.3", - "on-finished": "^2.4.1", - "parseurl": "^1.3.3", - "statuses": "^2.0.1" - }, - "dependencies": { - "debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "requires": { - "ms": "^2.1.3" - } - }, - "encodeurl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", - "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==" - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "requires": { - "ee-first": "1.1.1" - } - }, - "statuses": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", - "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==" - } - } - }, - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==" - }, - "flat-cache": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", - "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", - "dev": true, - "requires": { - "flatted": "^3.2.9", - "keyv": "^4.5.4" - } - }, - "flatted": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", - "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", - "dev": true - }, - "follow-redirects": { - "version": "1.15.11", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", - "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==" - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", - "optional": true - }, - "form-data": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", - "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", - "optional": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "es-set-tostringtag": "^2.1.0", - "hasown": "^2.0.2", - "mime-types": "^2.1.12" - } - }, - "forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" - }, - "fraction.js": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", - "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==" - }, - "fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==" - }, - "from": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", - "integrity": "sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4=", - "optional": true - }, - "fs-minipass": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz", - "integrity": "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==", - "requires": { - "minipass": "^7.0.3" - } - }, - "fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "optional": true - }, - "function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" - }, - "gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==" - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" - }, - "get-east-asian-width": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.4.0.tgz", - "integrity": "sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==" - }, - "get-func-name": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", - "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", - "optional": true - }, - "get-intrinsic": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", - "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", - "requires": { - "call-bind-apply-helpers": "^1.0.2", - "es-define-property": "^1.0.1", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.1.1", - "function-bind": "^1.1.2", - "get-proto": "^1.0.1", - "gopd": "^1.2.0", - "has-symbols": "^1.1.0", - "hasown": "^2.0.2", - "math-intrinsics": "^1.1.0" - } - }, - "get-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", - "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", - "requires": { - "dunder-proto": "^1.0.1", - "es-object-atoms": "^1.0.0" - } - }, - "get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "optional": true - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", - "optional": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, - "glob": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.0.tgz", - "integrity": "sha512-tvZgpqk6fz4BaNZ66ZsRaZnbHvP/jG3uKJvAZOwEVUL4RTA5nJeeLYfyN9/VA8NX/V3IBG+hkeuGpKjvELkVhA==", - "requires": { - "minimatch": "^10.1.1", - "minipass": "^7.1.2", - "path-scurry": "^2.0.0" - }, - "dependencies": { - "balanced-match": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", - "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==" - }, - "brace-expansion": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", - "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", - "requires": { - "balanced-match": "^4.0.2" - } - }, - "minimatch": { - "version": "10.2.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", - "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", - "requires": { - "brace-expansion": "^5.0.2" - } - } - } - }, - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "requires": { - "is-glob": "^4.0.1" - } - }, - "glob-to-regex.js": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/glob-to-regex.js/-/glob-to-regex.js-1.2.0.tgz", - "integrity": "sha512-QMwlOQKU/IzqMUOAZWubUOT8Qft+Y0KQWnX9nK3ch0CJg0tTp4TvGZsTfudYKv2NzoQSyPcnA6TYeIQ3jGichQ==", - "requires": {} - }, - "glob-to-regexp": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" - }, - "global-dirs": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz", - "integrity": "sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==", - "optional": true, - "requires": { - "ini": "2.0.0" - }, - "dependencies": { - "ini": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", - "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", - "optional": true - } - } - }, - "globals": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", - "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", - "dev": true - }, - "good-listener": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/good-listener/-/good-listener-1.2.2.tgz", - "integrity": "sha1-1TswzfkxPf+33JoNR3CWqm0UXFA=", - "requires": { - "delegate": "^3.1.2" - } - }, - "gopd": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", - "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==" - }, - "graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" - }, - "graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true - }, - "handle-thing": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", - "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==" - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "has-symbols": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", - "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==" - }, - "has-tostringtag": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", - "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "optional": true, - "requires": { - "has-symbols": "^1.0.3" - } - }, - "hasha": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", - "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==", - "optional": true, - "requires": { - "is-stream": "^2.0.0", - "type-fest": "^0.8.0" - }, - "dependencies": { - "type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "optional": true - } - } - }, - "hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "requires": { - "function-bind": "^1.1.2" - } - }, - "hono": { - "version": "4.12.8", - "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.8.tgz", - "integrity": "sha512-VJCEvtrezO1IAR+kqEYnxUOoStaQPGrCmX3j4wDTNOcD1uRPFpGlwQUIW8niPuvHXaTUxeOUl5MMDGrl+tmO9A==" - }, - "hosted-git-info": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-9.0.2.tgz", - "integrity": "sha512-M422h7o/BR3rmCQ8UHi7cyyMqKltdP9Uo+J2fXK+RSAY+wTcKOIRyhTuKv4qn+DJf3g+PL890AzId5KZpX+CBg==", - "requires": { - "lru-cache": "^11.1.0" - } - }, - "hpack.js": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", - "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", - "requires": { - "inherits": "^2.0.1", - "obuf": "^1.0.0", - "readable-stream": "^2.0.1", - "wbuf": "^1.1.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "html-encoding-sniffer": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-6.0.0.tgz", - "integrity": "sha512-CV9TW3Y3f8/wT0BRFc1/KAVQ3TUHiXmaAb6VW9vtiMFf7SLoMd1PdAc4W3KFOFETBJUb90KatHqlsZMWV+R9Gg==", - "devOptional": true, - "requires": { - "@exodus/bytes": "^1.6.0" - } - }, - "htmlparser2": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-10.1.0.tgz", - "integrity": "sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ==", - "requires": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3", - "domutils": "^3.2.2", - "entities": "^7.0.1" - }, - "dependencies": { - "entities": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz", - "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==" - } - } - }, - "http-cache-semantics": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", - "integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==" - }, - "http-deceiver": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", - "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==" - }, - "http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "requires": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, - "dependencies": { - "statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" - } - } - }, - "http-parser-js": { - "version": "0.5.10", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.10.tgz", - "integrity": "sha512-Pysuw9XpUq5dVc/2SMHpuTY01RFl8fttgcyunjL7eEMhGM3cI4eOmiCycJDVCo/7O7ClfQD3SaI6ftDzqOXYMA==" - }, - "http-proxy": { - "version": "1.18.1", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", - "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", - "requires": { - "eventemitter3": "^4.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" - } - }, - "http-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", - "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", - "requires": { - "agent-base": "^7.1.0", - "debug": "^4.3.4" - } - }, - "http-proxy-middleware": { - "version": "2.0.9", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.9.tgz", - "integrity": "sha512-c1IyJYLYppU574+YI7R4QyX2ystMtVXZwIdzazUIPIJsHuWNd+mho2j+bKoHftndicGj9yh+xjd+l0yj7VeT1Q==", - "requires": { - "@types/http-proxy": "^1.17.8", - "http-proxy": "^1.18.1", - "is-glob": "^4.0.1", - "is-plain-obj": "^3.0.0", - "micromatch": "^4.0.2" - } - }, - "http-signature": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.4.0.tgz", - "integrity": "sha512-G5akfn7eKbpDN+8nPS/cb57YeA1jLTVxjpCj7tmm3QKPdyDy7T+qSC40e9ptydSWvkwjSXw1VbkpyEm39ukeAg==", - "optional": true, - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^2.0.2", - "sshpk": "^1.18.0" - } - }, - "https-proxy-agent": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", - "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", - "requires": { - "agent-base": "^7.1.2", - "debug": "4" - } - }, - "human-signals": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", - "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", - "optional": true - }, - "hyperdyperid": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/hyperdyperid/-/hyperdyperid-1.2.0.tgz", - "integrity": "sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A==" - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "icss-utils": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", - "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", - "requires": {} - }, - "ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "optional": true - }, - "ignore": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", - "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", - "dev": true - }, - "ignore-walk": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-8.0.0.tgz", - "integrity": "sha512-FCeMZT4NiRQGh+YkeKMtWrOmBgWjHjMJ26WQWrRQyoyzqevdaGSakUaJW5xQYmjLlUVk2qUnCjYVBax9EKKg8A==", - "requires": { - "minimatch": "^10.0.3" - }, - "dependencies": { - "balanced-match": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", - "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==" - }, - "brace-expansion": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", - "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", - "requires": { - "balanced-match": "^4.0.2" - } - }, - "minimatch": { - "version": "10.2.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", - "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", - "requires": { - "brace-expansion": "^5.0.2" - } - } - } - }, - "image-size": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz", - "integrity": "sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==", - "optional": true - }, - "immutable": { - "version": "3.8.3", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.8.3.tgz", - "integrity": "sha512-AUY/VyX0E5XlibOmWt10uabJzam1zlYjwiEgQSDc5+UIkFNaF9WM0JxXKaNMGf+F/ffUF+7kRKXM9A7C0xXqMg==", - "devOptional": true - }, - "import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "dependencies": { - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" - } - } - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" - }, - "indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "optional": true - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "ini": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ini/-/ini-5.0.0.tgz", - "integrity": "sha512-+N0ngpO3e7cRUWOJAS7qw0IZIVc6XPrW4MlFBdD066F2L4k1L6ker3hLqSq7iXxU5tgS4WGkIUElWn5vogAEnw==" - }, - "ip-address": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.1.0.tgz", - "integrity": "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==" - }, - "ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-core-module": { - "version": "2.16.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", - "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", - "requires": { - "hasown": "^2.0.2" - } - }, - "is-docker": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", - "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==" - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" - }, - "is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-inside-container": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", - "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", - "requires": { - "is-docker": "^3.0.0" - } - }, - "is-installed-globally": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", - "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", - "optional": true, - "requires": { - "global-dirs": "^3.0.0", - "is-path-inside": "^3.0.2" - } - }, - "is-interactive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz", - "integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==" - }, - "is-network-error": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/is-network-error/-/is-network-error-1.3.1.tgz", - "integrity": "sha512-6QCxa49rQbmUWLfk0nuGqzql9U8uaV2H6279bRErPBHe/109hCzsLUBUHfbEtvLIHBd6hyXbgedBSHevm43Edw==" - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" - }, - "is-number-like": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/is-number-like/-/is-number-like-1.0.8.tgz", - "integrity": "sha512-6rZi3ezCyFcn5L71ywzz2bS5b2Igl1En3eTlZlvKjpz1n3IZLAYMbKYAIQgFmEu0GENg92ziU/faEOA/aixjbA==", - "devOptional": true, - "requires": { - "lodash.isfinite": "^3.3.2" - } - }, - "is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "optional": true - }, - "is-plain-obj": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", - "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==" - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "requires": { - "isobject": "^3.0.1" - } - }, - "is-potential-custom-element-name": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", - "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", - "devOptional": true - }, - "is-promise": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", - "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==" - }, - "is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "optional": true - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", - "optional": true - }, - "is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "optional": true - }, - "is-what": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/is-what/-/is-what-3.14.1.tgz", - "integrity": "sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==" - }, - "is-wsl": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.1.tgz", - "integrity": "sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==", - "requires": { - "is-inside-container": "^1.0.0" - } - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==" - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", - "optional": true - }, - "istanbul-lib-coverage": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", - "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==" - }, - "istanbul-lib-instrument": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", - "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", - "requires": { - "@babel/core": "^7.23.9", - "@babel/parser": "^7.23.9", - "@istanbuljs/schema": "^0.1.3", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^7.5.4" - } - }, - "jest-worker": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", - "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", - "requires": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "dependencies": { - "supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "jiti": { - "version": "1.21.0", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.0.tgz", - "integrity": "sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==" - }, - "joi": { - "version": "18.0.1", - "resolved": "https://registry.npmjs.org/joi/-/joi-18.0.1.tgz", - "integrity": "sha512-IiQpRyypSnLisQf3PwuN2eIHAsAIGZIrLZkd4zdvIar2bDyhM91ubRjy8a3eYablXsh9BeI/c7dmPYHca5qtoA==", - "optional": true, - "requires": { - "@hapi/address": "^5.1.1", - "@hapi/formula": "^3.0.2", - "@hapi/hoek": "^11.0.7", - "@hapi/pinpoint": "^2.0.1", - "@hapi/tlds": "^1.1.1", - "@hapi/topo": "^6.0.2", - "@standard-schema/spec": "^1.0.0" - } - }, - "jose": { - "version": "6.1.3", - "resolved": "https://registry.npmjs.org/jose/-/jose-6.1.3.tgz", - "integrity": "sha512-0TpaTfihd4QMNwrz/ob2Bp7X04yuxJkjRGi4aKmOqwhov54i6u79oCv7T+C7lo70MKH6BesI3vscD1yb/yzKXQ==" - }, - "jquery": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.0.tgz", - "integrity": "sha512-JVzAR/AjBvVt2BmYhxRCSYysDsPcssdmTFnzyLEts9qNwmjmu4JTAMYubEfwVOSwpQ1I1sKKFcxhZCI2buerfw==", - "peer": true - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" - }, - "js-yaml": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", - "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", - "requires": { - "argparse": "^2.0.1" - } - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", - "optional": true - }, - "jsdom": { - "version": "30.0.1", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-30.0.1.tgz", - "integrity": "sha512-52v7mUVUfNQVYYqE1lcdaymWL0njO7lTLUog6ZvW2U5KsbiLk/GnZlVJ+qx0xfNJZ6Gn+KSpPNE52vurbxZwrA==", - "devOptional": true, - "requires": { - "@asamuzakjp/css-color": "^6.0.5", - "@asamuzakjp/dom-selector": "^8.3.0", - "@bramus/specificity": "^2.4.2", - "@csstools/css-syntax-patches-for-csstree": "^1.1.7", - "@exodus/bytes": "^1.15.1", - "css-tree": "^3.2.1", - "data-urls": "^7.0.0", - "decimal.js": "^10.6.0", - "html-encoding-sniffer": "^6.0.0", - "is-potential-custom-element-name": "^1.0.1", - "lru-cache": "^11.5.2", - "parse5": "^8.0.1", - "saxes": "^6.0.0", - "symbol-tree": "^3.2.4", - "tough-cookie": "^6.0.2", - "undici": "^8.9.0", - "w3c-xmlserializer": "^5.0.0", - "webidl-conversions": "^8.0.1", - "whatwg-mimetype": "^5.0.0", - "whatwg-url": "^17.1.0", - "xml-name-validator": "^5.0.0" - }, - "dependencies": { - "tldts": { - "version": "7.4.11", - "resolved": "https://registry.npmjs.org/tldts/-/tldts-7.4.11.tgz", - "integrity": "sha512-aBiNayCfTQxuIJBm06M+xR14cYaYlDlSXZbgsnKzKNxDKUVq7KFwTjwBSsb7m9Y5xO8WfPnBc63WaYFMTGlvqw==", - "devOptional": true, - "requires": { - "tldts-core": "^7.4.11" - } - }, - "tldts-core": { - "version": "7.4.11", - "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-7.4.11.tgz", - "integrity": "sha512-CW3WN2rIIE/Of21mulhgnGOwoDyEFNygyIBOONSdyAuSATgMMUCpLeUlB+E8sAwA5xRV9hYPl+kyZ9citHCaKg==", - "devOptional": true - }, - "tough-cookie": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-6.0.2.tgz", - "integrity": "sha512-exgYmnmL/sJpR3upZfXG5PoatXQii55xAiXGXzY+sROLZ/Y+SLcp9PgJNI9Vz37HpQ74WvDcLT8eqm+kV3FzrA==", - "devOptional": true, - "requires": { - "tldts": "^7.0.5" - } - } - } - }, - "jsesc": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", - "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==" - }, - "json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true - }, - "json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" - }, - "json-schema": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", - "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", - "optional": true - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "json-schema-typed": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-8.0.2.tgz", - "integrity": "sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==" - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "optional": true - }, - "json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==" - }, - "jsonc-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", - "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==" - }, - "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "optional": true, - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" - } - }, - "jsonparse": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", - "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==" - }, - "jsprim": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-2.0.2.tgz", - "integrity": "sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ==", - "optional": true, - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.4.0", - "verror": "1.10.0" - } - }, - "just-extend": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz", - "integrity": "sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==", - "optional": true - }, - "karma-source-map-support": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/karma-source-map-support/-/karma-source-map-support-1.4.0.tgz", - "integrity": "sha512-RsBECncGO17KAoJCYXjv+ckIz+Ii9NCi+9enk+rq6XC81ezYkb4/RHE6CTXdA7IOJqoF3wcaLfVG0CPmE5ca6A==", - "requires": { - "source-map-support": "^0.5.5" - } - }, - "keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "dev": true, - "requires": { - "json-buffer": "3.0.1" - } - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" - }, - "launch-editor": { - "version": "2.13.2", - "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.13.2.tgz", - "integrity": "sha512-4VVDnbOpLXy/s8rdRCSXb+zfMeFR0WlJWpET1iA9CQdlZDfwyLjUuGQzXU4VeOoey6AicSAluWan7Etga6Kcmg==", - "requires": { - "picocolors": "^1.1.1", - "shell-quote": "^1.8.3" - } - }, - "lazy-ass": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/lazy-ass/-/lazy-ass-1.6.0.tgz", - "integrity": "sha1-eZllXoZGwX8In90YfRUNMyTVRRM=", - "optional": true - }, - "less": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/less/-/less-4.4.0.tgz", - "integrity": "sha512-kdTwsyRuncDfjEs0DlRILWNvxhDG/Zij4YLO4TMJgDLW+8OzpfkdPnRgrsRuY1o+oaxJGWsps5f/RVBgGmmN0w==", - "requires": { - "copy-anything": "^2.0.1", - "errno": "^0.1.1", - "graceful-fs": "^4.1.2", - "image-size": "~0.5.0", - "make-dir": "^2.1.0", - "mime": "^1.4.1", - "needle": "^3.1.0", - "parse-node-version": "^1.0.1", - "source-map": "~0.6.0", - "tslib": "^2.3.0" - }, - "dependencies": { - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "optional": true - } - } - }, - "less-loader": { - "version": "12.3.0", - "resolved": "https://registry.npmjs.org/less-loader/-/less-loader-12.3.0.tgz", - "integrity": "sha512-0M6+uYulvYIWs52y0LqN4+QM9TqWAohYSNTo4htE8Z7Cn3G/qQMEmktfHmyJT23k+20kU9zHH2wrfFXkxNLtVw==", - "requires": {} - }, - "levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - } - }, - "license-webpack-plugin": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/license-webpack-plugin/-/license-webpack-plugin-4.0.2.tgz", - "integrity": "sha512-771TFWFD70G1wLTC4oU2Cw4qvtmNrIw+wRvBtn+okgHl7slJVi7zfNcdmqDL72BojM30VNJ2UHylr1o77U37Jw==", - "requires": { - "webpack-sources": "^3.0.0" - } - }, - "limiter": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/limiter/-/limiter-1.1.5.tgz", - "integrity": "sha512-FWWMIEOxz3GwUI4Ts/IvgVy6LPvoMPgjMdQ185nN6psJyBJ4yOpzqm695/h5umdLJg2vW3GR5iG11MAkR2AzJA==", - "devOptional": true - }, - "lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" - }, - "listr2": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.14.0.tgz", - "integrity": "sha512-TyWI8G99GX9GjE54cJ+RrNMcIFBfwMPxc3XTFiAYGN4s10hWROGtOg7+O6u6LE3mNkyld7RSLE6nrKBvTfcs3g==", - "optional": true, - "requires": { - "cli-truncate": "^2.1.0", - "colorette": "^2.0.16", - "log-update": "^4.0.0", - "p-map": "^4.0.0", - "rfdc": "^1.3.0", - "rxjs": "^7.5.1", - "through": "^2.3.8", - "wrap-ansi": "^7.0.0" - }, - "dependencies": { - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "optional": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - } - } - }, - "lmdb": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/lmdb/-/lmdb-3.4.2.tgz", - "integrity": "sha512-nwVGUfTBUwJKXd6lRV8pFNfnrCC1+l49ESJRM19t/tFb/97QfJEixe5DYRvug5JO7DSFKoKaVy7oGMt5rVqZvg==", - "optional": true, - "requires": { - "@lmdb/lmdb-darwin-arm64": "3.4.2", - "@lmdb/lmdb-darwin-x64": "3.4.2", - "@lmdb/lmdb-linux-arm": "3.4.2", - "@lmdb/lmdb-linux-arm64": "3.4.2", - "@lmdb/lmdb-linux-x64": "3.4.2", - "@lmdb/lmdb-win32-arm64": "3.4.2", - "@lmdb/lmdb-win32-x64": "3.4.2", - "msgpackr": "^1.11.2", - "node-addon-api": "^6.1.0", - "node-gyp-build-optional-packages": "5.2.2", - "ordered-binary": "^1.5.3", - "weak-lru-cache": "^1.2.2" - } - }, - "loader-runner": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.1.tgz", - "integrity": "sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==" - }, - "loader-utils": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", - "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "requires": { - "p-locate": "^4.1.0" - } - }, - "lodash": { - "version": "4.17.23", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz", - "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==", - "devOptional": true - }, - "lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" - }, - "lodash.get": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", - "optional": true - }, - "lodash.isfinite": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/lodash.isfinite/-/lodash.isfinite-3.3.2.tgz", - "integrity": "sha512-7FGG40uhC8Mm633uKW1r58aElFlBlxCrg9JfSi3P6aYiWmfiWF0PgMd86ZUsxE5GwWPdHoS2+48bwTh2VPkIQA==", - "devOptional": true - }, - "lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "lodash.once": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", - "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=", - "optional": true - }, - "log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "optional": true, - "requires": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - } - }, - "log-update": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", - "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", - "optional": true, - "requires": { - "ansi-escapes": "^4.3.0", - "cli-cursor": "^3.1.0", - "slice-ansi": "^4.0.0", - "wrap-ansi": "^6.2.0" - }, - "dependencies": { - "slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", - "optional": true, - "requires": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - } - } - } - }, - "loupe": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", - "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", - "optional": true, - "requires": { - "get-func-name": "^2.0.1" - } - }, - "lru-cache": { - "version": "11.5.2", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.2.tgz", - "integrity": "sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g==" - }, - "magic-string": { - "version": "0.30.17", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", - "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", - "requires": { - "@jridgewell/sourcemap-codec": "^1.5.0" - } - }, - "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "optional": true, - "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" - }, - "dependencies": { - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "optional": true - }, - "semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "optional": true - } - } - }, - "make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, - "make-fetch-happen": { - "version": "15.0.3", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-15.0.3.tgz", - "integrity": "sha512-iyyEpDty1mwW3dGlYXAJqC/azFn5PPvgKVwXayOGBSmKLxhKZ9fg4qIan2ePpp1vJIwfFiO34LAPZgq9SZW9Aw==", - "requires": { - "@npmcli/agent": "^4.0.0", - "cacache": "^20.0.1", - "http-cache-semantics": "^4.1.1", - "minipass": "^7.0.2", - "minipass-fetch": "^5.0.0", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "negotiator": "^1.0.0", - "proc-log": "^6.0.0", - "promise-retry": "^2.0.1", - "ssri": "^13.0.0" - }, - "dependencies": { - "negotiator": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", - "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==" - }, - "proc-log": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-6.1.0.tgz", - "integrity": "sha512-iG+GYldRf2BQ0UDUAd6JQ/RwzaQy6mXmsk/IzlYyal4A4SNFw54MeH4/tLkF4I5WoWG9SQwuqWzS99jaFQHBuQ==" - } - } - }, - "map-stream": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz", - "integrity": "sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ=", - "optional": true - }, - "math-intrinsics": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", - "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==" - }, - "mdn-data": { - "version": "2.27.1", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.27.1.tgz", - "integrity": "sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==", - "devOptional": true - }, - "media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==" - }, - "memfs": { - "version": "4.57.1", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.57.1.tgz", - "integrity": "sha512-WvzrWPwMQT+PtbX2Et64R4qXKK0fj/8pO85MrUCzymX3twwCiJCdvntW3HdhG1teLJcHDDLIKx5+c3HckWYZtQ==", - "requires": { - "@jsonjoy.com/fs-core": "4.57.1", - "@jsonjoy.com/fs-fsa": "4.57.1", - "@jsonjoy.com/fs-node": "4.57.1", - "@jsonjoy.com/fs-node-builtins": "4.57.1", - "@jsonjoy.com/fs-node-to-fsa": "4.57.1", - "@jsonjoy.com/fs-node-utils": "4.57.1", - "@jsonjoy.com/fs-print": "4.57.1", - "@jsonjoy.com/fs-snapshot": "4.57.1", - "@jsonjoy.com/json-pack": "^1.11.0", - "@jsonjoy.com/util": "^1.9.0", - "glob-to-regex.js": "^1.0.1", - "thingies": "^2.5.0", - "tree-dump": "^1.0.3", - "tslib": "^2.0.0" - } - }, - "merge-descriptors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", - "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==" - }, - "merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" - }, - "merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==" - }, - "methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==" - }, - "micromatch": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", - "requires": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" - } - }, - "mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" - }, - "mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "requires": { - "mime-db": "1.52.0" - } - }, - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "optional": true - }, - "mimic-function": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", - "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==" - }, - "mini-css-extract-plugin": { - "version": "2.9.4", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.4.tgz", - "integrity": "sha512-ZWYT7ln73Hptxqxk2DxPU9MmapXRhxkJD6tkSR04dnQxm8BGu2hzgKLugK5yySD97u/8yy7Ma7E76k9ZdvtjkQ==", - "requires": { - "schema-utils": "^4.0.0", - "tapable": "^2.2.1" - } - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" - }, - "minimatch": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", - "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", - "devOptional": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "optional": true - }, - "minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==" - }, - "minipass-collect": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-2.0.1.tgz", - "integrity": "sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==", - "requires": { - "minipass": "^7.0.3" - } - }, - "minipass-fetch": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-5.0.0.tgz", - "integrity": "sha512-fiCdUALipqgPWrOVTz9fw0XhcazULXOSU6ie40DDbX1F49p1dBrSRBuswndTx1x3vEb/g0FT7vC4c4C2u/mh3A==", - "requires": { - "encoding": "^0.1.13", - "minipass": "^7.0.3", - "minipass-sized": "^1.0.3", - "minizlib": "^3.0.1" - } - }, - "minipass-flush": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", - "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", - "requires": { - "minipass": "^3.0.0" - }, - "dependencies": { - "minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "requires": { - "yallist": "^4.0.0" - } - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - } - } - }, - "minipass-pipeline": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", - "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", - "requires": { - "minipass": "^3.0.0" - }, - "dependencies": { - "minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "requires": { - "yallist": "^4.0.0" - } - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - } - } - }, - "minipass-sized": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", - "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", - "requires": { - "minipass": "^3.0.0" - }, - "dependencies": { - "minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "requires": { - "yallist": "^4.0.0" - } - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - } - } - }, - "minizlib": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz", - "integrity": "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==", - "requires": { - "minipass": "^7.1.2" - } - }, - "mitt": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mitt/-/mitt-1.2.0.tgz", - "integrity": "sha512-r6lj77KlwqLhIUku9UWYes7KJtsczvolZkzp8hbaDPPaE24OmWl5s539Mytlj22siEQKosZ26qCBgda2PKwoJw==", - "devOptional": true - }, - "mock-socket": { - "version": "9.3.1", - "resolved": "https://registry.npmjs.org/mock-socket/-/mock-socket-9.3.1.tgz", - "integrity": "sha512-qxBgB7Qa2sEQgHFjj0dSigq7fX4k6Saisd5Nelwp2q8mlbAFh5dHV9JTTlF8viYJLSSWgMCZFUom8PJcMNBoJw==", - "optional": true - }, - "mrmime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", - "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==" - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "msgpackr": { - "version": "1.11.9", - "resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.11.9.tgz", - "integrity": "sha512-FkoAAyyA6HM8wL882EcEyFZ9s7hVADSwG9xrVx3dxxNQAtgADTrJoEWivID82Iv1zWDsv/OtbrrcZAzGzOMdNw==", - "optional": true, - "requires": { - "msgpackr-extract": "^3.0.2" - } - }, - "msgpackr-extract": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/msgpackr-extract/-/msgpackr-extract-3.0.3.tgz", - "integrity": "sha512-P0efT1C9jIdVRefqjzOQ9Xml57zpOXnIuS+csaB4MdZbTdmGDLo8XhzBG1N7aO11gKDDkJvBLULeFTo46wwreA==", - "optional": true, - "requires": { - "@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.3", - "@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.3", - "@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.3", - "@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.3", - "@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.3", - "@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.3", - "node-gyp-build-optional-packages": "5.2.2" - } - }, - "multicast-dns": { - "version": "7.2.5", - "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", - "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", - "requires": { - "dns-packet": "^5.2.2", - "thunky": "^1.0.2" - } - }, - "mute-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-2.0.0.tgz", - "integrity": "sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==" - }, - "nanoid": { - "version": "3.3.11", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", - "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==" - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true - }, - "needle": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/needle/-/needle-3.3.1.tgz", - "integrity": "sha512-6k0YULvhpw+RoLNiQCRKOl09Rv1dPLr8hHnVjHqdolKwDrdNyk+Hmrthi4lIGPPz3r39dLx0hsF5s40sZ3Us4Q==", - "optional": true, - "requires": { - "iconv-lite": "^0.6.3", - "sax": "^1.2.4" - }, - "dependencies": { - "iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "optional": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - } - } - } - }, - "negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" - }, - "neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" - }, - "ngx-echarts": { - "version": "20.0.2", - "resolved": "https://registry.npmjs.org/ngx-echarts/-/ngx-echarts-20.0.2.tgz", - "integrity": "sha512-kDoIFp7SrWCPWG9nX9IX9ARnIh4f5p8VYtRWvhXwlf5gW+GxUbeDKYpvIvBVjaftudLZIMwZ/N4GADQSIus57Q==", - "requires": { - "tslib": "^2.3.0" - } - }, - "ngx-infinite-scroll": { - "version": "20.0.0", - "resolved": "https://registry.npmjs.org/ngx-infinite-scroll/-/ngx-infinite-scroll-20.0.0.tgz", - "integrity": "sha512-Mh7lg85jeDPzZirxPHjyMagCcC3vbk+yPO5uoXHNkmGer8MrO6vOydOX306qY4QYDyMJ+ngIQgpl5HJXfc590A==", - "requires": { - "tslib": "^2.3.0" - } - }, - "nise": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.5.tgz", - "integrity": "sha512-VJuPIfUFaXNRzETTQEEItTOP8Y171ijr+JLq42wHes3DiryR8vT+1TXQW/Rx8JNUhyYYWyIvjXTU6dOhJcs9Nw==", - "optional": true, - "requires": { - "@sinonjs/commons": "^2.0.0", - "@sinonjs/fake-timers": "^10.0.2", - "@sinonjs/text-encoding": "^0.7.1", - "just-extend": "^4.0.2", - "path-to-regexp": "^1.7.0" - }, - "dependencies": { - "@sinonjs/commons": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", - "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", - "optional": true, - "requires": { - "type-detect": "4.0.8" - } - }, - "@sinonjs/fake-timers": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", - "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", - "optional": true, - "requires": { - "@sinonjs/commons": "^3.0.0" - }, - "dependencies": { - "@sinonjs/commons": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz", - "integrity": "sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==", - "optional": true, - "requires": { - "type-detect": "4.0.8" - } - } - } - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", - "optional": true - }, - "path-to-regexp": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.9.0.tgz", - "integrity": "sha512-xIp7/apCFJuUHdDLWe8O1HIkb0kQrOMb/0u6FXQjemHn/ii5LrIzU6bdECnsiTF/GjZkMEKg1xdiZwNqDYlZ6g==", - "optional": true, - "requires": { - "isarray": "0.0.1" - } - } - } - }, - "node-addon-api": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-6.1.0.tgz", - "integrity": "sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==", - "optional": true - }, - "node-forge": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.4.0.tgz", - "integrity": "sha512-LarFH0+6VfriEhqMMcLX2F7SwSXeWwnEAJEsYm5QKWchiVYVvJyV9v7UDvUv+w5HO23ZpQTXDv/GxdDdMyOuoQ==" - }, - "node-gyp": { - "version": "12.2.0", - "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-12.2.0.tgz", - "integrity": "sha512-q23WdzrQv48KozXlr0U1v9dwO/k59NHeSzn6loGcasyf0UnSrtzs8kRxM+mfwJSf0DkX0s43hcqgnSO4/VNthQ==", - "requires": { - "env-paths": "^2.2.0", - "exponential-backoff": "^3.1.1", - "graceful-fs": "^4.2.6", - "make-fetch-happen": "^15.0.0", - "nopt": "^9.0.0", - "proc-log": "^6.0.0", - "semver": "^7.3.5", - "tar": "^7.5.5", - "tinyglobby": "^0.2.12", - "which": "^6.0.0" - }, - "dependencies": { - "isexe": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", - "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==" - }, - "proc-log": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-6.1.0.tgz", - "integrity": "sha512-iG+GYldRf2BQ0UDUAd6JQ/RwzaQy6mXmsk/IzlYyal4A4SNFw54MeH4/tLkF4I5WoWG9SQwuqWzS99jaFQHBuQ==" - }, - "which": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/which/-/which-6.0.0.tgz", - "integrity": "sha512-f+gEpIKMR9faW/JgAgPK1D7mekkFoqbmiwvNzuhsHetni20QSgzg9Vhn0g2JSJkkfehQnqdUAx7/e15qS1lPxg==", - "requires": { - "isexe": "^3.1.1" - } - } - } - }, - "node-gyp-build-optional-packages": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.2.2.tgz", - "integrity": "sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw==", - "optional": true, - "requires": { - "detect-libc": "^2.0.1" - } - }, - "node-releases": { - "version": "2.0.27", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", - "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==" - }, - "nopt": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-9.0.0.tgz", - "integrity": "sha512-Zhq3a+yFKrYwSBluL4H9XP3m3y5uvQkB/09CwDruCiRmR/UJYnn9W4R48ry0uGC70aeTPKLynBtscP9efFFcPw==", - "requires": { - "abbrev": "^4.0.0" - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" - }, - "normalize-range": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", - "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==" - }, - "npm-bundled": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-5.0.0.tgz", - "integrity": "sha512-JLSpbzh6UUXIEoqPsYBvVNVmyrjVZ1fzEFbqxKkTJQkWBO3xFzFT+KDnSKQWwOQNbuWRwt5LSD6HOTLGIWzfrw==", - "requires": { - "npm-normalize-package-bin": "^5.0.0" - } - }, - "npm-install-checks": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-8.0.0.tgz", - "integrity": "sha512-ScAUdMpyzkbpxoNekQ3tNRdFI8SJ86wgKZSQZdUxT+bj0wVFpsEMWnkXP0twVe1gJyNF5apBWDJhhIbgrIViRA==", - "requires": { - "semver": "^7.1.1" - } - }, - "npm-normalize-package-bin": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-5.0.0.tgz", - "integrity": "sha512-CJi3OS4JLsNMmr2u07OJlhcrPxCeOeP/4xq67aWNai6TNWWbTrlNDgl8NcFKVlcBKp18GPj+EzbNIgrBfZhsag==" - }, - "npm-package-arg": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-13.0.0.tgz", - "integrity": "sha512-+t2etZAGcB7TbbLHfDwooV9ppB2LhhcT6A+L9cahsf9mEUAoQ6CktLEVvEnpD0N5CkX7zJqnPGaFtoQDy9EkHQ==", - "requires": { - "hosted-git-info": "^9.0.0", - "proc-log": "^5.0.0", - "semver": "^7.3.5", - "validate-npm-package-name": "^6.0.0" - } - }, - "npm-packlist": { - "version": "10.0.3", - "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-10.0.3.tgz", - "integrity": "sha512-zPukTwJMOu5X5uvm0fztwS5Zxyvmk38H/LfidkOMt3gbZVCyro2cD/ETzwzVPcWZA3JOyPznfUN/nkyFiyUbxg==", - "requires": { - "ignore-walk": "^8.0.0", - "proc-log": "^6.0.0" - }, - "dependencies": { - "proc-log": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-6.1.0.tgz", - "integrity": "sha512-iG+GYldRf2BQ0UDUAd6JQ/RwzaQy6mXmsk/IzlYyal4A4SNFw54MeH4/tLkF4I5WoWG9SQwuqWzS99jaFQHBuQ==" - } - } - }, - "npm-pick-manifest": { - "version": "11.0.3", - "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-11.0.3.tgz", - "integrity": "sha512-buzyCfeoGY/PxKqmBqn1IUJrZnUi1VVJTdSSRPGI60tJdUhUoSQFhs0zycJokDdOznQentgrpf8LayEHyyYlqQ==", - "requires": { - "npm-install-checks": "^8.0.0", - "npm-normalize-package-bin": "^5.0.0", - "npm-package-arg": "^13.0.0", - "semver": "^7.3.5" - } - }, - "npm-registry-fetch": { - "version": "19.1.1", - "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-19.1.1.tgz", - "integrity": "sha512-TakBap6OM1w0H73VZVDf44iFXsOS3h+L4wVMXmbWOQroZgFhMch0juN6XSzBNlD965yIKvWg2dfu7NSiaYLxtw==", - "requires": { - "@npmcli/redact": "^4.0.0", - "jsonparse": "^1.3.1", - "make-fetch-happen": "^15.0.0", - "minipass": "^7.0.2", - "minipass-fetch": "^5.0.0", - "minizlib": "^3.0.1", - "npm-package-arg": "^13.0.0", - "proc-log": "^6.0.0" - }, - "dependencies": { - "proc-log": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-6.1.0.tgz", - "integrity": "sha512-iG+GYldRf2BQ0UDUAd6JQ/RwzaQy6mXmsk/IzlYyal4A4SNFw54MeH4/tLkF4I5WoWG9SQwuqWzS99jaFQHBuQ==" - } - } - }, - "npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "optional": true, - "requires": { - "path-key": "^3.0.0" - } - }, - "nth-check": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", - "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", - "requires": { - "boolbase": "^1.0.0" - } - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" - }, - "object-inspect": { - "version": "1.13.4", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", - "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==" - }, - "obuf": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", - "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==" - }, - "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "devOptional": true, - "requires": { - "ee-first": "1.1.1" - } - }, - "on-headers": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.1.0.tgz", - "integrity": "sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==" - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "optional": true, - "requires": { - "mimic-fn": "^2.1.0" - } - }, - "open": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/open/-/open-10.2.0.tgz", - "integrity": "sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==", - "requires": { - "default-browser": "^5.2.1", - "define-lazy-prop": "^3.0.0", - "is-inside-container": "^1.0.0", - "wsl-utils": "^0.1.0" - } - }, - "opn": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/opn/-/opn-5.3.0.tgz", - "integrity": "sha512-bYJHo/LOmoTd+pfiYhfZDnf9zekVJrY+cnS2a5F2x+w5ppvTqObojTP7WiFG+kVZs9Inw+qQ/lw7TroWwhdd2g==", - "devOptional": true, - "requires": { - "is-wsl": "^1.1.0" - }, - "dependencies": { - "is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha512-gfygJYZ2gLTDlmbWMI0CE2MwnFzSN/2SZfkMlItC4K/JBlsWVDB0bO6XhqcY13YXE7iMcAJnzTCJjPiTeJJ0Mw==", - "devOptional": true - } - } - }, - "optionator": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", - "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", - "dev": true, - "requires": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.5" - } - }, - "ora": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/ora/-/ora-8.2.0.tgz", - "integrity": "sha512-weP+BZ8MVNnlCm8c0Qdc1WSWq4Qn7I+9CJGm7Qali6g44e/PUzbjNqJX5NJ9ljlNMosfJvg1fKEGILklK9cwnw==", - "requires": { - "chalk": "^5.3.0", - "cli-cursor": "^5.0.0", - "cli-spinners": "^2.9.2", - "is-interactive": "^2.0.0", - "is-unicode-supported": "^2.0.0", - "log-symbols": "^6.0.0", - "stdin-discarder": "^0.2.2", - "string-width": "^7.2.0", - "strip-ansi": "^7.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", - "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==" - }, - "chalk": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", - "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==" - }, - "cli-cursor": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", - "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", - "requires": { - "restore-cursor": "^5.0.0" - } - }, - "emoji-regex": { - "version": "10.6.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", - "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==" - }, - "is-unicode-supported": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz", - "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==" - }, - "log-symbols": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-6.0.0.tgz", - "integrity": "sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw==", - "requires": { - "chalk": "^5.3.0", - "is-unicode-supported": "^1.3.0" - }, - "dependencies": { - "is-unicode-supported": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", - "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==" - } - } - }, - "onetime": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", - "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", - "requires": { - "mimic-function": "^5.0.0" - } - }, - "restore-cursor": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", - "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", - "requires": { - "onetime": "^7.0.0", - "signal-exit": "^4.1.0" - } - }, - "signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==" - }, - "string-width": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", - "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", - "requires": { - "emoji-regex": "^10.3.0", - "get-east-asian-width": "^1.0.0", - "strip-ansi": "^7.1.0" - } - }, - "strip-ansi": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", - "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", - "requires": { - "ansi-regex": "^6.0.1" - } - } - } - }, - "ordered-binary": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/ordered-binary/-/ordered-binary-1.6.1.tgz", - "integrity": "sha512-QkCdPooczexPLiXIrbVOPYkR3VO3T6v2OyKRkR1Xbhpy7/LAVXwahnRCgRp78Oe/Ehf0C/HATAxfSr6eA1oX+w==", - "optional": true - }, - "ospath": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/ospath/-/ospath-1.2.2.tgz", - "integrity": "sha1-EnZjl3Sj+O8lcvf+QoDg6kVQwHs=", - "optional": true - }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "requires": { - "p-limit": "^2.2.0" - }, - "dependencies": { - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "requires": { - "p-try": "^2.0.0" - } - } - } - }, - "p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "optional": true, - "requires": { - "aggregate-error": "^3.0.0" - } - }, - "p-retry": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-6.2.1.tgz", - "integrity": "sha512-hEt02O4hUct5wtwg4H4KcWgDdm+l1bOaEy/hWzd8xtXB9BqxTWBBhb+2ImAtH4Cv4rPjV76xN3Zumqk3k3AhhQ==", - "requires": { - "@types/retry": "0.12.2", - "is-network-error": "^1.0.0", - "retry": "^0.13.1" - }, - "dependencies": { - "retry": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", - "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==" - } - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" - }, - "pacote": { - "version": "21.0.4", - "resolved": "https://registry.npmjs.org/pacote/-/pacote-21.0.4.tgz", - "integrity": "sha512-RplP/pDW0NNNDh3pnaoIWYPvNenS7UqMbXyvMqJczosiFWTeGGwJC2NQBLqKf4rGLFfwCOnntw1aEp9Jiqm1MA==", - "requires": { - "@npmcli/git": "^7.0.0", - "@npmcli/installed-package-contents": "^4.0.0", - "@npmcli/package-json": "^7.0.0", - "@npmcli/promise-spawn": "^9.0.0", - "@npmcli/run-script": "^10.0.0", - "cacache": "^20.0.0", - "fs-minipass": "^3.0.0", - "minipass": "^7.0.2", - "npm-package-arg": "^13.0.0", - "npm-packlist": "^10.0.1", - "npm-pick-manifest": "^11.0.1", - "npm-registry-fetch": "^19.0.0", - "proc-log": "^6.0.0", - "promise-retry": "^2.0.1", - "sigstore": "^4.0.0", - "ssri": "^13.0.0", - "tar": "^7.5.5" - }, - "dependencies": { - "proc-log": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-6.1.0.tgz", - "integrity": "sha512-iG+GYldRf2BQ0UDUAd6JQ/RwzaQy6mXmsk/IzlYyal4A4SNFw54MeH4/tLkF4I5WoWG9SQwuqWzS99jaFQHBuQ==" - } - } - }, - "parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "requires": { - "callsites": "^3.0.0" - } - }, - "parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - } - }, - "parse-node-version": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz", - "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==" - }, - "parse5": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-8.0.1.tgz", - "integrity": "sha512-z1e/HMG90obSGeidlli3hj7cbocou0/wa5HacvI3ASx34PecNjNQeaHNo5WIZpWofN9kgkqV1q5YvXe3F0FoPw==", - "requires": { - "entities": "^8.0.0" - }, - "dependencies": { - "entities": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-8.0.0.tgz", - "integrity": "sha512-zwfzJecQ/Uej6tusMqwAqU/6KL2XaB2VZ2Jg54Je6ahNBGNH6Ek6g3jjNCF0fG9EWQKGZNddNjU5F1ZQn/sBnA==" - } - } - }, - "parse5-html-rewriting-stream": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/parse5-html-rewriting-stream/-/parse5-html-rewriting-stream-8.0.0.tgz", - "integrity": "sha512-wzh11mj8KKkno1pZEu+l2EVeWsuKDfR5KNWZOTsslfUX8lPDZx77m9T0kIoAVkFtD1nx6YF8oh4BnPHvxMtNMw==", - "requires": { - "entities": "^6.0.0", - "parse5": "^8.0.0", - "parse5-sax-parser": "^8.0.0" - }, - "dependencies": { - "entities": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", - "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==" - } - } - }, - "parse5-sax-parser": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/parse5-sax-parser/-/parse5-sax-parser-8.0.0.tgz", - "integrity": "sha512-/dQ8UzHZwnrzs3EvDj6IkKrD/jIZyTlB+8XrHJvcjNgRdmWruNdN9i9RK/JtxakmlUdPwKubKPTCqvbTgzGhrw==", - "requires": { - "parse5": "^8.0.0" - } - }, - "parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" - }, - "path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" - }, - "path-scurry": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.1.tgz", - "integrity": "sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==", - "requires": { - "lru-cache": "^11.0.0", - "minipass": "^7.1.2" - } - }, - "path-to-regexp": { - "version": "8.4.1", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.4.1.tgz", - "integrity": "sha512-fvU78fIjZ+SBM9YwCknCvKOUKkLVqtWDVctl0s7xIqfmfb38t2TT4ZU2gHm+Z8xGwgW+QWEU3oQSAzIbo89Ggw==" - }, - "pathe": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", - "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", - "devOptional": true - }, - "pathval": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", - "optional": true - }, - "pause-stream": { - "version": "0.0.11", - "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", - "integrity": "sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=", - "optional": true, - "requires": { - "through": "~2.3" - } - }, - "pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", - "optional": true - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", - "optional": true - }, - "picocolors": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==" - }, - "picomatch": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", - "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==" - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "optional": true - }, - "piscina": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/piscina/-/piscina-5.1.3.tgz", - "integrity": "sha512-0u3N7H4+hbr40KjuVn2uNhOcthu/9usKhnw5vT3J7ply79v3D3M8naI00el9Klcy16x557VsEkkUQaHCWFXC/g==", - "requires": { - "@napi-rs/nice": "^1.0.4" - } - }, - "pkce-challenge": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-5.0.1.tgz", - "integrity": "sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==" - }, - "pngjs": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-5.0.0.tgz", - "integrity": "sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==" - }, - "popper.js": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1.tgz", - "integrity": "sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ==", - "peer": true - }, - "portscanner": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/portscanner/-/portscanner-2.2.0.tgz", - "integrity": "sha512-IFroCz/59Lqa2uBvzK3bKDbDDIEaAY8XJ1jFxcLWTqosrsc32//P4VuSB2vZXoHiHqOmx8B5L5hnKOxL/7FlPw==", - "devOptional": true, - "requires": { - "async": "^2.6.0", - "is-number-like": "^1.0.3" - }, - "dependencies": { - "async": { - "version": "2.6.4", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", - "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", - "devOptional": true, - "requires": { - "lodash": "^4.17.14" - } - } - } - }, - "postcss": { - "version": "8.5.6", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", - "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", - "requires": { - "nanoid": "^3.3.11", - "picocolors": "^1.1.1", - "source-map-js": "^1.2.1" - } - }, - "postcss-loader": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-8.1.1.tgz", - "integrity": "sha512-0IeqyAsG6tYiDRCYKQJLAmgQr47DX6N7sFSWvQxt6AcupX8DIdmykuk/o/tx0Lze3ErGHJEp5OSRxrelC6+NdQ==", - "requires": { - "cosmiconfig": "^9.0.0", - "jiti": "^1.20.0", - "semver": "^7.5.4" - } - }, - "postcss-media-query-parser": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz", - "integrity": "sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==" - }, - "postcss-modules-extract-imports": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz", - "integrity": "sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==", - "requires": {} - }, - "postcss-modules-local-by-default": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.2.0.tgz", - "integrity": "sha512-5kcJm/zk+GJDSfw+V/42fJ5fhjL5YbFDl8nVdXkJPLLW+Vf9mTD5Xe0wqIaDnLuL2U6cDNpTr+UQ+v2HWIBhzw==", - "requires": { - "icss-utils": "^5.0.0", - "postcss-selector-parser": "^7.0.0", - "postcss-value-parser": "^4.1.0" - } - }, - "postcss-modules-scope": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.1.tgz", - "integrity": "sha512-m9jZstCVaqGjTAuny8MdgE88scJnCiQSlSrOWcTQgM2t32UBe+MUmFSO5t7VMSfAf/FJKImAxBav8ooCHJXCJA==", - "requires": { - "postcss-selector-parser": "^7.0.0" - } - }, - "postcss-modules-values": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", - "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", - "requires": { - "icss-utils": "^5.0.0" - } - }, - "postcss-selector-parser": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", - "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", - "requires": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - } - }, - "postcss-value-parser": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" - }, - "prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true - }, - "prettier": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.0.tgz", - "integrity": "sha512-zBf5eHpwHOGPC47h0zrPyNn+eAEIdEzfywMoYn2XPi0P44Zp0tSq64rq0xAREh4auw2cJZHo9QUob+NqCQky4g==", - "dev": true - }, - "pretty-bytes": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", - "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", - "optional": true - }, - "proc-log": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-5.0.0.tgz", - "integrity": "sha512-Azwzvl90HaF0aCz1JrDdXQykFakSSNPaPoiZ9fm5qJIMHioDZEi7OAdRwSm6rSoPtY3Qutnm3L7ogmg3dc+wbQ==" - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", - "optional": true - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" - }, - "promise-retry": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", - "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", - "requires": { - "err-code": "^2.0.2", - "retry": "^0.12.0" - } - }, - "proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "requires": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - } - }, - "proxy-from-env": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz", - "integrity": "sha512-F2JHgJQ1iqwnHDcQjVBsq3n/uoaFL+iPW/eAeL7kVxy/2RrWaN4WroKjjvbsoRtv0ftelNyC01bjRhn/bhcf4A==", - "optional": true - }, - "prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==", - "optional": true - }, - "ps-tree": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/ps-tree/-/ps-tree-1.2.0.tgz", - "integrity": "sha512-0VnamPPYHl4uaU/nSFeZZpR21QAWRz+sRv4iW9+v/GS/J5U5iZB5BNN6J0RMoOvdx2gWM2+ZFMIm58q24e4UYA==", - "optional": true, - "requires": { - "event-stream": "=3.3.4" - } - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "optional": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "devOptional": true - }, - "qrcode": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/qrcode/-/qrcode-1.5.1.tgz", - "integrity": "sha512-nS8NJ1Z3md8uTjKtP+SGGhfqmTCs5flU/xR623oI0JX+Wepz9R8UrRVCTBTJm3qGw3rH6jJ6MUHjkDx15cxSSg==", - "requires": { - "dijkstrajs": "^1.0.1", - "encode-utf8": "^1.0.3", - "pngjs": "^5.0.0", - "yargs": "^15.3.1" - }, - "dependencies": { - "yargs": { - "version": "15.4.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", - "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", - "requires": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.2" - } - } - } - }, - "qs": { - "version": "6.14.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.2.tgz", - "integrity": "sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q==", - "requires": { - "side-channel": "^1.1.0" - } - }, - "queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==" - }, - "range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" - }, - "raw-body": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.3.tgz", - "integrity": "sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==", - "requires": { - "bytes": "~3.1.2", - "http-errors": "~2.0.1", - "iconv-lite": "~0.4.24", - "unpipe": "~1.0.0" - }, - "dependencies": { - "http-errors": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", - "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", - "requires": { - "depd": "~2.0.0", - "inherits": "~2.0.4", - "setprototypeof": "~1.2.0", - "statuses": "~2.0.2", - "toidentifier": "~1.0.1" - } - }, - "statuses": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", - "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==" - } - } - }, - "readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "requires": { - "picomatch": "^2.2.1" - } - }, - "reflect-metadata": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz", - "integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==" - }, - "regenerate": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", - "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==" - }, - "regenerate-unicode-properties": { - "version": "10.2.2", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.2.tgz", - "integrity": "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g==", - "requires": { - "regenerate": "^1.4.2" - } - }, - "regex-parser": { - "version": "2.2.11", - "resolved": "https://registry.npmjs.org/regex-parser/-/regex-parser-2.2.11.tgz", - "integrity": "sha512-jbD/FT0+9MBU2XAZluI7w2OBs1RBi6p9M83nkoZayQXXU9e8Robt69FcZc7wU4eJD/YFTjn1JdCk3rbMJajz8Q==" - }, - "regexpu-core": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.4.0.tgz", - "integrity": "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA==", - "requires": { - "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^10.2.2", - "regjsgen": "^0.8.0", - "regjsparser": "^0.13.0", - "unicode-match-property-ecmascript": "^2.0.0", - "unicode-match-property-value-ecmascript": "^2.2.1" - } - }, - "regjsgen": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz", - "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==" - }, - "regjsparser": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.13.0.tgz", - "integrity": "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q==", - "requires": { - "jsesc": "~3.1.0" - } - }, - "request-progress": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-3.0.0.tgz", - "integrity": "sha1-TKdUCBx/7GP1BeT6qCWqBs1mnb4=", - "optional": true, - "requires": { - "throttleit": "^1.0.0" - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" - }, - "require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==" - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" - }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=" - }, - "resolve": { - "version": "1.22.10", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", - "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", - "requires": { - "is-core-module": "^2.16.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - } - }, - "resolve-url-loader": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-5.0.0.tgz", - "integrity": "sha512-uZtduh8/8srhBoMx//5bwqjQ+rfYOUq8zC9NrMUGtjBiGTtFJM42s58/36+hTqeqINcnYe08Nj3LkK9lW4N8Xg==", - "requires": { - "adjust-sourcemap-loader": "^4.0.0", - "convert-source-map": "^1.7.0", - "loader-utils": "^2.0.0", - "postcss": "^8.2.14", - "source-map": "0.6.1" - } - }, - "resp-modifier": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/resp-modifier/-/resp-modifier-6.0.2.tgz", - "integrity": "sha512-U1+0kWC/+4ncRFYqQWTx/3qkfE6a4B/h3XXgmXypfa0SPZ3t7cbbaFk297PjQS/yov24R18h6OZe6iZwj3NSLw==", - "devOptional": true, - "requires": { - "debug": "^2.2.0", - "minimatch": "^3.0.2" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "devOptional": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "devOptional": true - } - } - }, - "restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "optional": true, - "requires": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - } - }, - "retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==" - }, - "reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==" - }, - "rfdc": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", - "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==" - }, - "rollup": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.59.0.tgz", - "integrity": "sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==", - "requires": { - "@rollup/rollup-android-arm-eabi": "4.59.0", - "@rollup/rollup-android-arm64": "4.59.0", - "@rollup/rollup-darwin-arm64": "4.59.0", - "@rollup/rollup-darwin-x64": "4.59.0", - "@rollup/rollup-freebsd-arm64": "4.59.0", - "@rollup/rollup-freebsd-x64": "4.59.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.59.0", - "@rollup/rollup-linux-arm-musleabihf": "4.59.0", - "@rollup/rollup-linux-arm64-gnu": "4.59.0", - "@rollup/rollup-linux-arm64-musl": "4.59.0", - "@rollup/rollup-linux-loong64-gnu": "4.59.0", - "@rollup/rollup-linux-loong64-musl": "4.59.0", - "@rollup/rollup-linux-ppc64-gnu": "4.59.0", - "@rollup/rollup-linux-ppc64-musl": "4.59.0", - "@rollup/rollup-linux-riscv64-gnu": "4.59.0", - "@rollup/rollup-linux-riscv64-musl": "4.59.0", - "@rollup/rollup-linux-s390x-gnu": "4.59.0", - "@rollup/rollup-linux-x64-gnu": "4.59.0", - "@rollup/rollup-linux-x64-musl": "4.59.0", - "@rollup/rollup-openbsd-x64": "4.59.0", - "@rollup/rollup-openharmony-arm64": "4.59.0", - "@rollup/rollup-win32-arm64-msvc": "4.59.0", - "@rollup/rollup-win32-ia32-msvc": "4.59.0", - "@rollup/rollup-win32-x64-gnu": "4.59.0", - "@rollup/rollup-win32-x64-msvc": "4.59.0", - "@types/estree": "1.0.8", - "fsevents": "~2.3.2" - } - }, - "router": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", - "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==", - "requires": { - "debug": "^4.4.0", - "depd": "^2.0.0", - "is-promise": "^4.0.0", - "parseurl": "^1.3.3", - "path-to-regexp": "^8.0.0" - }, - "dependencies": { - "debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "requires": { - "ms": "^2.1.3" - } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - } - } - }, - "run-applescript": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.1.0.tgz", - "integrity": "sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==" - }, - "run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "requires": { - "queue-microtask": "^1.2.2" - } - }, - "rx": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/rx/-/rx-4.1.0.tgz", - "integrity": "sha512-CiaiuN6gapkdl+cZUr67W6I8jquN4lkak3vtIsIWCl4XIPP8ffsoyN6/+PuGXnQy8Cu8W2y9Xxh31Rq4M6wUug==", - "devOptional": true - }, - "rxjs": { - "version": "7.8.2", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", - "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", - "requires": { - "tslib": "^2.1.0" - } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "sass": { - "version": "1.90.0", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.90.0.tgz", - "integrity": "sha512-9GUyuksjw70uNpb1MTYWsH9MQHOHY6kwfnkafC24+7aOMZn9+rVMBxRbLvw756mrBFbIsFg6Xw9IkR2Fnn3k+Q==", - "requires": { - "@parcel/watcher": "^2.4.1", - "chokidar": "^4.0.0", - "immutable": "^5.0.2", - "source-map-js": ">=0.6.2 <2.0.0" - }, - "dependencies": { - "chokidar": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", - "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", - "requires": { - "readdirp": "^4.0.1" - } - }, - "immutable": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.5.tgz", - "integrity": "sha512-t7xcm2siw+hlUM68I+UEOK+z84RzmN59as9DZ7P1l0994DKUWV7UXBMQZVxaoMSRQ+PBZbHCOoBt7a2wxOMt+A==" - }, - "readdirp": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", - "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==" - } - } - }, - "sass-loader": { - "version": "16.0.5", - "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-16.0.5.tgz", - "integrity": "sha512-oL+CMBXrj6BZ/zOq4os+UECPL+bWqt6OAC6DWS8Ln8GZRcMDjlJ4JC3FBDuHJdYaFWIdKNIBYmtZtK2MaMkNIw==", - "requires": { - "neo-async": "^2.6.2" - } - }, - "sax": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", - "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==", - "optional": true - }, - "saxes": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", - "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", - "devOptional": true, - "requires": { - "xmlchars": "^2.2.0" - } - }, - "schema-utils": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.3.tgz", - "integrity": "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==", - "requires": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.9.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.1.0" - }, - "dependencies": { - "ajv": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", - "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", - "requires": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - } - }, - "ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "requires": { - "fast-deep-equal": "^3.1.3" - } - }, - "json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" - } - } - }, - "select": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz", - "integrity": "sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0=" - }, - "select-hose": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", - "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==" - }, - "selfsigned": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz", - "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", - "requires": { - "@types/node-forge": "^1.3.0", - "node-forge": "^1" - } - }, - "semver": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", - "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==" - }, - "send": { - "version": "0.19.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", - "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", - "requires": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - }, - "dependencies": { - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - } - } - }, - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "requires": { - "ee-first": "1.1.1" - } - }, - "statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" - } - } - }, - "serialize-javascript": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-7.0.5.tgz", - "integrity": "sha512-F4LcB0UqUl1zErq+1nYEEzSHJnIwb3AF2XWB94b+afhrekOUijwooAYqFyRbjYkm2PAKBabx6oYv/xDxNi8IBw==" - }, - "serve-index": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", - "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", - "requires": { - "accepts": "~1.3.4", - "batch": "0.6.1", - "debug": "2.6.9", - "escape-html": "~1.0.3", - "http-errors": "~1.6.2", - "mime-types": "~2.1.17", - "parseurl": "~1.3.2" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==" - }, - "http-errors": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": ">= 1.4.0 < 2" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==" - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "setprototypeof": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" - } - } - }, - "serve-static": { - "version": "1.16.2", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", - "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", - "requires": { - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.19.0" - }, - "dependencies": { - "encodeurl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", - "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==" - } - } - }, - "server-destroy": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/server-destroy/-/server-destroy-1.0.1.tgz", - "integrity": "sha512-rb+9B5YBIEzYcD6x2VKidaa+cqYBJQKnU4oe4E3ANwRRN56yk/ua1YCJT1n21NTS8w6CcOclAKNP3PhdCXKYtQ==", - "devOptional": true - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" - }, - "setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" - }, - "shallow-clone": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", - "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", - "requires": { - "kind-of": "^6.0.2" - } - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" - }, - "shell-quote": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.3.tgz", - "integrity": "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==" - }, - "side-channel": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", - "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", - "requires": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.3", - "side-channel-list": "^1.0.0", - "side-channel-map": "^1.0.1", - "side-channel-weakmap": "^1.0.2" - } - }, - "side-channel-list": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", - "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", - "requires": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.3" - } - }, - "side-channel-map": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", - "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", - "requires": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3" - } - }, - "side-channel-weakmap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", - "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", - "requires": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3", - "side-channel-map": "^1.0.1" - } - }, - "siginfo": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", - "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", - "devOptional": true - }, - "signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "optional": true - }, - "sigstore": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/sigstore/-/sigstore-4.1.0.tgz", - "integrity": "sha512-/fUgUhYghuLzVT/gaJoeVehLCgZiUxPCPMcyVNY0lIf/cTCz58K/WTI7PefDarXxp9nUKpEwg1yyz3eSBMTtgA==", - "requires": { - "@sigstore/bundle": "^4.0.0", - "@sigstore/core": "^3.1.0", - "@sigstore/protobuf-specs": "^0.5.0", - "@sigstore/sign": "^4.1.0", - "@sigstore/tuf": "^4.0.1", - "@sigstore/verify": "^3.1.0" - } - }, - "sinon": { - "version": "17.0.1", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-17.0.1.tgz", - "integrity": "sha512-wmwE19Lie0MLT+ZYNpDymasPHUKTaZHUH/pKEubRXIzySv9Atnlw+BUMGCzWgV7b7wO+Hw6f1TEOr0IUnmU8/g==", - "optional": true, - "requires": { - "@sinonjs/commons": "^3.0.0", - "@sinonjs/fake-timers": "^11.2.2", - "@sinonjs/samsam": "^8.0.0", - "diff": "^5.1.0", - "nise": "^5.1.5", - "supports-color": "^7.2.0" - }, - "dependencies": { - "diff": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.2.tgz", - "integrity": "sha512-vtcDfH3TOjP8UekytvnHH1o1P4FcUdt4eQ1Y+Abap1tk/OB2MWQvcwS2ClCd1zuIhc3JKOx6p3kod8Vfys3E+A==", - "optional": true - } - } - }, - "sinon-chai": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/sinon-chai/-/sinon-chai-3.7.0.tgz", - "integrity": "sha512-mf5NURdUaSdnatJx3uhoBOrY9dtL19fiOtAdT1Azxg3+lNJFiuN0uzaU3xX1LeAfL17kHQhTAJgpsfhbMJMY2g==", - "optional": true, - "requires": {} - }, - "slice-ansi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", - "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", - "optional": true, - "requires": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - } - }, - "smart-buffer": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", - "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==" - }, - "socket.io": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.8.0.tgz", - "integrity": "sha512-8U6BEgGjQOfGz3HHTYaC/L1GaxDCJ/KM0XTkJly0EhZ5U/du9uNEZy4ZgYzEzIqlx2CMm25CrCqr1ck899eLNA==", - "devOptional": true, - "requires": { - "accepts": "~1.3.4", - "base64id": "~2.0.0", - "cors": "~2.8.5", - "debug": "~4.3.2", - "engine.io": "~6.6.0", - "socket.io-adapter": "~2.5.2", - "socket.io-parser": "~4.2.4" - } - }, - "socket.io-adapter": { - "version": "2.5.5", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.5.tgz", - "integrity": "sha512-eLDQas5dzPgOWCk9GuuJC2lBqItuhKI4uxGgo9aIV7MYbk2h9Q6uULEh8WBzThoI7l+qU9Ast9fVUmkqPP9wYg==", - "devOptional": true, - "requires": { - "debug": "~4.3.4", - "ws": "~8.17.1" - } - }, - "socket.io-client": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.8.0.tgz", - "integrity": "sha512-C0jdhD5yQahMws9alf/yvtsMGTaIDBnZ8Rb5HU56svyq0l5LIrGzIDZZD5pHQlmzxLuU91Gz+VpQMKgCTNYtkw==", - "devOptional": true, - "requires": { - "@socket.io/component-emitter": "~3.1.0", - "debug": "~4.3.2", - "engine.io-client": "~6.6.1", - "socket.io-parser": "~4.2.4" - } - }, - "socket.io-parser": { - "version": "4.2.6", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.6.tgz", - "integrity": "sha512-asJqbVBDsBCJx0pTqw3WfesSY0iRX+2xzWEWzrpcH7L6fLzrhyF8WPI8UaeM4YCuDfpwA/cgsdugMsmtz8EJeg==", - "devOptional": true, - "requires": { - "@socket.io/component-emitter": "~3.1.0", - "debug": "~4.4.1" - }, - "dependencies": { - "debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "devOptional": true, - "requires": { - "ms": "^2.1.3" - } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "devOptional": true - } - } - }, - "sockjs": { - "version": "0.3.24", - "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", - "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", - "requires": { - "faye-websocket": "^0.11.3", - "uuid": "^8.3.2", - "websocket-driver": "^0.7.4" - } - }, - "socks": { - "version": "2.8.7", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.7.tgz", - "integrity": "sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==", - "requires": { - "ip-address": "^10.0.1", - "smart-buffer": "^4.2.0" - } - }, - "socks-proxy-agent": { - "version": "8.0.5", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz", - "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==", - "requires": { - "agent-base": "^7.1.2", - "debug": "^4.3.4", - "socks": "^2.8.3" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - }, - "source-map-js": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", - "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==" - }, - "source-map-loader": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/source-map-loader/-/source-map-loader-5.0.0.tgz", - "integrity": "sha512-k2Dur7CbSLcAH73sBcIkV5xjPV4SzqO1NJ7+XaQl8if3VODDUj3FNchNGpqgJSKbvUfJuhVdv8K2Eu8/TNl2eA==", - "requires": { - "iconv-lite": "^0.6.3", - "source-map-js": "^1.0.2" - }, - "dependencies": { - "iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "requires": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - } - } - } - }, - "source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "spdx-correct": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", - "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", - "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==" - }, - "spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.22", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.22.tgz", - "integrity": "sha512-4PRT4nh1EImPbt2jASOKHX7PB7I+e4IWNLvkKFDxNhJlfjbYlleYQh285Z/3mPTHSAK/AvdMmw5BNNuYH8ShgQ==" - }, - "spdy": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", - "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", - "requires": { - "debug": "^4.1.0", - "handle-thing": "^2.0.0", - "http-deceiver": "^1.2.7", - "select-hose": "^2.0.0", - "spdy-transport": "^3.0.0" - } - }, - "spdy-transport": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", - "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", - "requires": { - "debug": "^4.1.0", - "detect-node": "^2.0.4", - "hpack.js": "^2.1.6", - "obuf": "^1.1.2", - "readable-stream": "^3.0.6", - "wbuf": "^1.7.3" - } - }, - "split": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz", - "integrity": "sha1-zQ7qXmOiEd//frDwkcQTPi0N0o8=", - "optional": true, - "requires": { - "through": "2" - } - }, - "sshpk": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", - "integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==", - "optional": true, - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - } - }, - "ssri": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-13.0.0.tgz", - "integrity": "sha512-yizwGBpbCn4YomB2lzhZqrHLJoqFGXihNbib3ozhqF/cIp5ue+xSmOQrjNasEE62hFxsCcg/V/z23t4n8jMEng==", - "requires": { - "minipass": "^7.0.3" - } - }, - "stackback": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", - "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", - "devOptional": true - }, - "start-server-and-test": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/start-server-and-test/-/start-server-and-test-2.1.2.tgz", - "integrity": "sha512-OIjfo3G6QV9Sh6IlMqj58oZwVhPVuU/l6uVACG7YNE9kAfDvcYoPThtb0NNT3tZMMC3wOYbXnC15yiCSNFkdRg==", - "optional": true, - "requires": { - "arg": "^5.0.2", - "bluebird": "3.7.2", - "check-more-types": "2.24.0", - "debug": "4.4.3", - "execa": "5.1.1", - "lazy-ass": "1.6.0", - "ps-tree": "1.2.0", - "wait-on": "8.0.5" - }, - "dependencies": { - "arg": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", - "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", - "optional": true - }, - "debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "optional": true, - "requires": { - "ms": "^2.1.3" - } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "optional": true - } - } - }, - "statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" - }, - "std-env": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz", - "integrity": "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==", - "devOptional": true - }, - "stdin-discarder": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/stdin-discarder/-/stdin-discarder-0.2.2.tgz", - "integrity": "sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==" - }, - "stream-throttle": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/stream-throttle/-/stream-throttle-0.1.3.tgz", - "integrity": "sha512-889+B9vN9dq7/vLbGyuHeZ6/ctf5sNuGWsDy89uNxkFTAgzy0eK7+w5fL3KLNRTkLle7EgZGvHUphZW0Q26MnQ==", - "devOptional": true, - "requires": { - "commander": "^2.2.0", - "limiter": "^1.0.5" - } - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "optional": true - }, - "strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true - }, - "strip-literal": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-3.1.0.tgz", - "integrity": "sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==", - "devOptional": true, - "requires": { - "js-tokens": "^9.0.1" - }, - "dependencies": { - "js-tokens": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz", - "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==", - "devOptional": true - } - } - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "devOptional": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" - }, - "symbol-tree": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", - "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", - "devOptional": true - }, - "systeminformation": { - "version": "5.31.1", - "resolved": "https://registry.npmjs.org/systeminformation/-/systeminformation-5.31.1.tgz", - "integrity": "sha512-6pRwxoGeV/roJYpsfcP6tN9mep6pPeCtXbUOCdVa0nme05Brwcwdge/fVNhIZn2wuUitAKZm4IYa7QjnRIa9zA==", - "optional": true - }, - "tapable": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz", - "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==" - }, - "tar": { - "version": "7.5.12", - "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.12.tgz", - "integrity": "sha512-9TsuLcdhOn4XztcQqhNyq1KOwOOED/3k58JAvtULiYqbO8B/0IBAAIE1hj0Svmm58k27TmcigyDI0deMlgG3uw==", - "requires": { - "@isaacs/fs-minipass": "^4.0.0", - "chownr": "^3.0.0", - "minipass": "^7.1.2", - "minizlib": "^3.1.0", - "yallist": "^5.0.0" - } - }, - "terser": { - "version": "5.46.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.46.0.tgz", - "integrity": "sha512-jTwoImyr/QbOWFFso3YoU3ik0jBBDJ6JTOQiy/J2YxVJdZCc+5u7skhNwiOR3FQIygFqVUPHl7qbbxtjW2K3Qg==", - "requires": { - "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.15.0", - "commander": "^2.20.0", - "source-map-support": "~0.5.20" - } - }, - "terser-webpack-plugin": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.4.0.tgz", - "integrity": "sha512-Bn5vxm48flOIfkdl5CaD2+1CiUVbonWQ3KQPyP7/EuIl9Gbzq/gQFOzaMFUEgVjB1396tcK0SG8XcNJ/2kDH8g==", - "requires": { - "@jridgewell/trace-mapping": "^0.3.25", - "jest-worker": "^27.4.5", - "schema-utils": "^4.3.0", - "terser": "^5.31.1" - }, - "dependencies": { - "@jridgewell/trace-mapping": { - "version": "0.3.31", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", - "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", - "requires": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - } - } - }, - "thingies": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/thingies/-/thingies-2.6.0.tgz", - "integrity": "sha512-rMHRjmlFLM1R96UYPvpmnc3LYtdFrT33JIB7L9hetGue1qAPfn1N2LJeEjxUSidu1Iku+haLZXDuEXUHNGO/lg==", - "requires": {} - }, - "throttleit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.0.tgz", - "integrity": "sha1-nnhYNtr0Z0MUWlmEtiaNgoUorGw=", - "optional": true - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "optional": true - }, - "thunky": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", - "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==" - }, - "tiny-emitter": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz", - "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==" - }, - "tinybench": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", - "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", - "devOptional": true - }, - "tinyexec": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", - "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", - "devOptional": true - }, - "tinyglobby": { - "version": "0.2.14", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz", - "integrity": "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==", - "requires": { - "fdir": "^6.4.4", - "picomatch": "^4.0.2" - }, - "dependencies": { - "fdir": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", - "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", - "requires": {} - }, - "picomatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==" - } - } - }, - "tinypool": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.1.1.tgz", - "integrity": "sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==", - "devOptional": true - }, - "tinyrainbow": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-2.0.0.tgz", - "integrity": "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==", - "devOptional": true - }, - "tinyspy": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-4.0.4.tgz", - "integrity": "sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q==", - "devOptional": true - }, - "tldts": { - "version": "6.1.86", - "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.86.tgz", - "integrity": "sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==", - "optional": true, - "requires": { - "tldts-core": "^6.1.86" - } - }, - "tldts-core": { - "version": "6.1.86", - "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.86.tgz", - "integrity": "sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==", - "optional": true - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "requires": { - "is-number": "^7.0.0" - } - }, - "toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" - }, - "tough-cookie": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.1.2.tgz", - "integrity": "sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==", - "optional": true, - "requires": { - "tldts": "^6.1.32" - } - }, - "tr46": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-6.0.0.tgz", - "integrity": "sha512-bLVMLPtstlZ4iMQHpFHTR7GAGj2jxi8Dg0s2h2MafAE4uSWF98FC/3MomU51iQAMf8/qDUbKWf5GxuvvVcXEhw==", - "devOptional": true, - "requires": { - "punycode": "^2.3.1" - } - }, - "tree-dump": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/tree-dump/-/tree-dump-1.1.0.tgz", - "integrity": "sha512-rMuvhU4MCDbcbnleZTFezWsaZXRFemSqAM+7jPnzUl1fo9w3YEKOxAeui0fz3OI4EU4hf23iyA7uQRVko+UaBA==", - "requires": {} - }, - "tree-kill": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", - "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==" - }, - "ts-api-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", - "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==", - "dev": true, - "requires": {} - }, - "ts-node": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", - "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", - "dev": true, - "requires": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - }, - "dependencies": { - "acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "dev": true - } - } - }, - "tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" - }, - "tuf-js": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/tuf-js/-/tuf-js-4.1.0.tgz", - "integrity": "sha512-50QV99kCKH5P/Vs4E2Gzp7BopNV+KzTXqWeaxrfu5IQJBOULRsTIS9seSsOVT8ZnGXzCyx55nYWAi4qJzpZKEQ==", - "requires": { - "@tufjs/models": "4.1.0", - "debug": "^4.4.3", - "make-fetch-happen": "^15.0.1" - }, - "dependencies": { - "debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "requires": { - "ms": "^2.1.3" - } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - } - } - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", - "optional": true, - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", - "optional": true - }, - "type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1" - } - }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "optional": true - }, - "type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "optional": true - }, - "type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "requires": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - } - }, - "typed-assert": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/typed-assert/-/typed-assert-1.0.9.tgz", - "integrity": "sha512-KNNZtayBCtmnNmbo5mG47p1XsCyrx6iVqomjcZnec/1Y5GGARaxPs6r49RnSPeUP3YjNYiU9sQHAtY4BBvnZwg==" - }, - "typescript": { - "version": "5.8.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", - "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==" - }, - "undici": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-8.10.0.tgz", - "integrity": "sha512-HvltHd7avK13QIw/oLe4qoOLyoVSoafqJ2jYOrtMRBkbYT31eiBQ8O0ehRKZiEZCMEyLFQNIADpgCWC5fALvYQ==", - "devOptional": true - }, - "undici-types": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", - "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==" - }, - "unicode-canonical-property-names-ecmascript": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", - "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==" - }, - "unicode-match-property-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", - "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", - "requires": { - "unicode-canonical-property-names-ecmascript": "^2.0.0", - "unicode-property-aliases-ecmascript": "^2.0.0" - } - }, - "unicode-match-property-value-ecmascript": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.1.tgz", - "integrity": "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg==" - }, - "unicode-property-aliases-ecmascript": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.2.0.tgz", - "integrity": "sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ==" - }, - "unique-filename": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-5.0.0.tgz", - "integrity": "sha512-2RaJTAvAb4owyjllTfXzFClJ7WsGxlykkPvCr9pA//LD9goVq+m4PPAeBgNodGZ7nSrntT/auWpJ6Y5IFXcfjg==", - "requires": { - "unique-slug": "^6.0.0" - } - }, - "unique-slug": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-6.0.0.tgz", - "integrity": "sha512-4Lup7Ezn8W3d52/xBhZBVdx323ckxa7DEvd9kPQHppTkLoJXw6ltrBCyj5pnrxj0qKDxYMJ56CoxNuFCscdTiw==", - "requires": { - "imurmurhash": "^0.1.4" - } - }, - "universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "optional": true - }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" - }, - "untildify": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", - "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", - "optional": true - }, - "update-browserslist-db": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", - "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", - "requires": { - "escalade": "^3.2.0", - "picocolors": "^1.1.1" - } - }, - "uri-js": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.0.tgz", - "integrity": "sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g==", - "dev": true, - "requires": { - "punycode": "^2.1.0" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" - }, - "uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" - }, - "v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true - }, - "validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "validate-npm-package-name": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-6.0.2.tgz", - "integrity": "sha512-IUoow1YUtvoBBC06dXs8bR8B9vuA3aJfmQNKMoaPG/OFsPmoQvw8xh+6Ye25Gx9DQhoEom3Pcu9MKHerm/NpUQ==" - }, - "vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", - "optional": true, - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "vite": { - "version": "7.1.11", - "resolved": "https://registry.npmjs.org/vite/-/vite-7.1.11.tgz", - "integrity": "sha512-uzcxnSDVjAopEUjljkWh8EIrg6tlzrjFUfMcR1EVsRDGwf/ccef0qQPRyOrROwhrTDaApueq+ja+KLPlzR/zdg==", - "requires": { - "esbuild": "^0.25.0", - "fdir": "^6.5.0", - "fsevents": "~2.3.3", - "picomatch": "^4.0.3", - "postcss": "^8.5.6", - "rollup": "^4.43.0", - "tinyglobby": "^0.2.15" - }, - "dependencies": { - "fdir": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", - "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", - "requires": {} - }, - "picomatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==" - }, - "tinyglobby": { - "version": "0.2.15", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", - "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", - "requires": { - "fdir": "^6.5.0", - "picomatch": "^4.0.3" - } - } - } - }, - "vite-node": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.2.4.tgz", - "integrity": "sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==", - "devOptional": true, - "requires": { - "cac": "^6.7.14", - "debug": "^4.4.1", - "es-module-lexer": "^1.7.0", - "pathe": "^2.0.3", - "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" - }, - "dependencies": { - "debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "devOptional": true, - "requires": { - "ms": "^2.1.3" - } - }, - "es-module-lexer": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", - "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", - "devOptional": true - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "devOptional": true - } - } - }, - "vitest": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.2.7.tgz", - "integrity": "sha512-KrxIJ62Fd89gfysR4WotlgZABiz2dqFPgqGzX7s+CwsqLFomRH7777ZcrOD6+WVAh7khPQP41A+BKbpcJFrdEg==", - "devOptional": true, - "requires": { - "@types/chai": "^5.2.2", - "@vitest/expect": "3.2.7", - "@vitest/mocker": "3.2.7", - "@vitest/pretty-format": "^3.2.7", - "@vitest/runner": "3.2.7", - "@vitest/snapshot": "3.2.7", - "@vitest/spy": "3.2.7", - "@vitest/utils": "3.2.7", - "chai": "^5.2.0", - "debug": "^4.4.1", - "expect-type": "^1.2.1", - "magic-string": "^0.30.17", - "pathe": "^2.0.3", - "picomatch": "^4.0.2", - "std-env": "^3.9.0", - "tinybench": "^2.9.0", - "tinyexec": "^0.3.2", - "tinyglobby": "^0.2.14", - "tinypool": "^1.1.1", - "tinyrainbow": "^2.0.0", - "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0", - "vite-node": "3.2.4", - "why-is-node-running": "^2.3.0" - }, - "dependencies": { - "assertion-error": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", - "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", - "devOptional": true - }, - "chai": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/chai/-/chai-5.3.3.tgz", - "integrity": "sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==", - "devOptional": true, - "requires": { - "assertion-error": "^2.0.1", - "check-error": "^2.1.1", - "deep-eql": "^5.0.1", - "loupe": "^3.1.0", - "pathval": "^2.0.0" - } - }, - "check-error": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.3.tgz", - "integrity": "sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==", - "devOptional": true - }, - "debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "devOptional": true, - "requires": { - "ms": "^2.1.3" - } - }, - "deep-eql": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", - "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", - "devOptional": true - }, - "loupe": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.1.tgz", - "integrity": "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==", - "devOptional": true - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "devOptional": true - }, - "pathval": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz", - "integrity": "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==", - "devOptional": true - }, - "picomatch": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz", - "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==", - "devOptional": true - } - } - }, - "w3c-xmlserializer": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", - "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", - "devOptional": true, - "requires": { - "xml-name-validator": "^5.0.0" - } - }, - "wait-on": { - "version": "8.0.5", - "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-8.0.5.tgz", - "integrity": "sha512-J3WlS0txVHkhLRb2FsmRg3dkMTCV1+M6Xra3Ho7HzZDHpE7DCOnoSoCJsZotrmW3uRMhvIJGSKUKrh/MeF4iag==", - "optional": true, - "requires": { - "axios": "^1.12.1", - "joi": "^18.0.1", - "lodash": "^4.17.21", - "minimist": "^1.2.8", - "rxjs": "^7.8.2" - } - }, - "watchpack": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.4.tgz", - "integrity": "sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA==", - "requires": { - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.1.2" + "node_modules/webpack-dev-server/node_modules/ipaddr.js": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.5.0.tgz", + "integrity": "sha512-aq+t5NAc+cS6rZQQVWC2x98CPqGtKKTMDd4Gaodv0wShnItdKg/51djkGJ1hqH+Oy0ivDftCbSLCQob8zso01w==", + "license": "MIT", + "engines": { + "node": ">= 10" } }, - "wbuf": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", - "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", - "requires": { - "minimalistic-assert": "^1.0.0" + "node_modules/webpack-dev-server/node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" } }, - "weak-lru-cache": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/weak-lru-cache/-/weak-lru-cache-1.2.2.tgz", - "integrity": "sha512-DEAoo25RfSYMuTGc9vPJzZcZullwIqRDSI9LOy+fkCJPi6hykCnfKaXTuPBDuXAUcqHXyOgFtHNp/kB2FjYHbw==", - "optional": true + "node_modules/webpack-dev-server/node_modules/merge-descriptors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "webidl-conversions": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-8.0.1.tgz", - "integrity": "sha512-BMhLD/Sw+GbJC21C/UgyaZX41nPt8bUTg+jWyDeg7e7YN4xOM05YPSIXceACnXVtqyEw/LMClUQMtMZ+PGGpqQ==", - "devOptional": true + "node_modules/webpack-dev-server/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" }, - "webpack": { - "version": "5.105.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.105.0.tgz", - "integrity": "sha512-gX/dMkRQc7QOMzgTe6KsYFM7DxeIONQSui1s0n/0xht36HvrgbxtM1xBlgx596NbpHuQU8P7QpKwrZYwUX48nw==", - "requires": { - "@types/eslint-scope": "^3.7.7", - "@types/estree": "^1.0.8", - "@types/json-schema": "^7.0.15", - "@webassemblyjs/ast": "^1.14.1", - "@webassemblyjs/wasm-edit": "^1.14.1", - "@webassemblyjs/wasm-parser": "^1.14.1", - "acorn": "^8.15.0", - "acorn-import-phases": "^1.0.3", - "browserslist": "^4.28.1", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.19.0", - "es-module-lexer": "^2.0.0", - "eslint-scope": "5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.11", - "json-parse-even-better-errors": "^2.3.1", - "loader-runner": "^4.3.1", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "schema-utils": "^4.3.3", - "tapable": "^2.3.0", - "terser-webpack-plugin": "^5.3.16", - "watchpack": "^2.5.1", - "webpack-sources": "^3.3.3" - }, + "node_modules/webpack-dev-server/node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "license": "MIT", "dependencies": { - "acorn-import-phases": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz", - "integrity": "sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==", - "requires": {} - }, - "watchpack": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.5.1.tgz", - "integrity": "sha512-Zn5uXdcFNIA1+1Ei5McRd+iRzfhENPCe7LeABkJtNulSxjma+l7ltNx55BWZkRlwRnpOgHqxnjyaDgJnNXnqzg==", - "requires": { - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.1.2" - } - } + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" } }, - "webpack-dev-middleware": { - "version": "7.4.2", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-7.4.2.tgz", - "integrity": "sha512-xOO8n6eggxnwYpy1NlzUKpvrjfJTvae5/D6WOK0S2LSo7vjmo5gCM1DbLUmFqrMTJP+W/0YZNctm7jasWvLuBA==", - "requires": { - "colorette": "^2.0.10", - "memfs": "^4.6.0", - "mime-types": "^2.1.31", - "on-finished": "^2.4.1", - "range-parser": "^1.2.1", - "schema-utils": "^4.0.0" - }, - "dependencies": { - "on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "requires": { - "ee-first": "1.1.1" - } - } + "node_modules/webpack-dev-server/node_modules/path-to-regexp": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.13.tgz", + "integrity": "sha512-A/AGNMFN3c8bOlvV9RreMdrv7jsmF9XIfDeCd87+I8RNg6s78BhJxMu69NEMHBSJFxKidViTEdruRwEk/WIKqA==", + "license": "MIT" + }, + "node_modules/webpack-dev-server/node_modules/statuses": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" } }, - "webpack-dev-server": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-5.2.2.tgz", - "integrity": "sha512-QcQ72gh8a+7JO63TAx/6XZf/CWhgMzu5m0QirvPfGvptOusAxG12w2+aua1Jkjr7hzaWDnJ2n6JFeexMHI+Zjg==", - "requires": { - "@types/bonjour": "^3.5.13", - "@types/connect-history-api-fallback": "^1.5.4", - "@types/express": "^4.17.21", - "@types/express-serve-static-core": "^4.17.21", - "@types/serve-index": "^1.9.4", - "@types/serve-static": "^1.15.5", - "@types/sockjs": "^0.3.36", - "@types/ws": "^8.5.10", - "ansi-html-community": "^0.0.8", - "bonjour-service": "^1.2.1", - "chokidar": "^3.6.0", - "colorette": "^2.0.10", - "compression": "^1.7.4", - "connect-history-api-fallback": "^2.0.0", - "express": "^4.21.2", - "graceful-fs": "^4.2.6", - "http-proxy-middleware": "^2.0.9", - "ipaddr.js": "^2.1.0", - "launch-editor": "^2.6.1", - "open": "^10.0.3", - "p-retry": "^6.2.0", - "schema-utils": "^4.2.0", - "selfsigned": "^2.4.1", - "serve-index": "^1.9.1", - "sockjs": "^0.3.24", - "spdy": "^4.0.2", - "webpack-dev-middleware": "^7.4.2", - "ws": "^8.18.0" - }, + "node_modules/webpack-dev-server/node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "license": "MIT", "dependencies": { - "connect-history-api-fallback": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", - "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==" - }, - "content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "requires": { - "safe-buffer": "5.2.1" - } - }, - "cookie-signature": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.7.tgz", - "integrity": "sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==" - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "encodeurl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", - "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==" - }, - "express": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.22.1.tgz", - "integrity": "sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==", - "requires": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "~1.20.3", - "content-disposition": "~0.5.4", - "content-type": "~1.0.4", - "cookie": "~0.7.1", - "cookie-signature": "~1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "~1.3.1", - "fresh": "~0.5.2", - "http-errors": "~2.0.0", - "merge-descriptors": "1.0.3", - "methods": "~1.1.2", - "on-finished": "~2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "~0.1.12", - "proxy-addr": "~2.0.7", - "qs": "~6.14.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "~0.19.0", - "serve-static": "~1.16.2", - "setprototypeof": "1.2.0", - "statuses": "~2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - } - }, - "finalhandler": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.2.tgz", - "integrity": "sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==", - "requires": { - "debug": "2.6.9", - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "on-finished": "~2.4.1", - "parseurl": "~1.3.3", - "statuses": "~2.0.2", - "unpipe": "~1.0.0" - } - }, - "ipaddr.js": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.3.0.tgz", - "integrity": "sha512-Zv/pA+ciVFbCSBBjGfaKUya/CcGmUHzTydLMaTwrUUEM2DIEO3iZvueGxmacvmN50fGpGVKeTXpb2LcYQxeVdg==" - }, - "merge-descriptors": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", - "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==" - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "requires": { - "ee-first": "1.1.1" - } - }, - "path-to-regexp": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.13.tgz", - "integrity": "sha512-A/AGNMFN3c8bOlvV9RreMdrv7jsmF9XIfDeCd87+I8RNg6s78BhJxMu69NEMHBSJFxKidViTEdruRwEk/WIKqA==" - }, - "statuses": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", - "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==" - }, - "ws": { - "version": "8.20.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.20.0.tgz", - "integrity": "sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==", - "requires": {} - } + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" } }, - "webpack-merge": { + "node_modules/webpack-merge": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-6.0.1.tgz", "integrity": "sha512-hXXvrjtx2PLYx4qruKl+kyRSLc52V+cCvMxRjmKwoA+CBbbF5GfIBtR6kCvl0fYGqTUPKB+1ktVmTHqMOzgCBg==", - "requires": { + "license": "MIT", + "dependencies": { "clone-deep": "^4.0.1", "flat": "^5.0.2", "wildcard": "^2.0.1" + }, + "engines": { + "node": ">=18.0.0" } }, - "webpack-sources": { + "node_modules/webpack-sources": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.3.tgz", - "integrity": "sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==" + "integrity": "sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==", + "license": "MIT", + "engines": { + "node": ">=10.13.0" + } }, - "webpack-subresource-integrity": { + "node_modules/webpack-subresource-integrity": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/webpack-subresource-integrity/-/webpack-subresource-integrity-5.1.0.tgz", "integrity": "sha512-sacXoX+xd8r4WKsy9MvH/q/vBtEHr86cpImXwyg74pFIpERKt6FmB8cXpeuh0ZLgclOlHI4Wcll7+R5L02xk9Q==", - "requires": { + "dependencies": { "typed-assert": "^1.0.8" + }, + "engines": { + "node": ">= 12" + }, + "peerDependencies": { + "html-webpack-plugin": ">= 5.0.0-beta.1 < 6", + "webpack": "^5.12.0" + }, + "peerDependenciesMeta": { + "html-webpack-plugin": { + "optional": true + } + } + }, + "node_modules/webpack/node_modules/acorn-import-phases": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz", + "integrity": "sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==", + "license": "MIT", + "engines": { + "node": ">=10.13.0" + }, + "peerDependencies": { + "acorn": "^8.14.0" + } + }, + "node_modules/webpack/node_modules/watchpack": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.5.1.tgz", + "integrity": "sha512-Zn5uXdcFNIA1+1Ei5McRd+iRzfhENPCe7LeABkJtNulSxjma+l7ltNx55BWZkRlwRnpOgHqxnjyaDgJnNXnqzg==", + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" } }, - "websocket-driver": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", - "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", - "requires": { + "node_modules/websocket-driver": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.5.tgz", + "integrity": "sha512-ZL2+3c7kMBdIRCMz6l8jQMHyGVxj+UL+xVk74Ombiciboca8rHa15L86B19E5oh1pL9Ii/uj54gtsIrZGMo6zA==", + "license": "Apache-2.0", + "dependencies": { "http-parser-js": ">=0.5.1", "safe-buffer": ">=5.1.0", "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" } }, - "websocket-extensions": { + "node_modules/websocket-extensions": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", - "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==" + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "license": "Apache-2.0", + "engines": { + "node": ">=0.8.0" + } }, - "whatwg-mimetype": { + "node_modules/whatwg-mimetype": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-5.0.0.tgz", "integrity": "sha512-sXcNcHOC51uPGF0P/D4NVtrkjSU2fNsm9iog4ZvZJsL3rjoDAzXZhkm2MWt1y+PUdggKAYVoMAIYcs78wJ51Cw==", - "devOptional": true + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=20" + } }, - "whatwg-url": { + "node_modules/whatwg-url": { "version": "17.1.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-17.1.0.tgz", "integrity": "sha512-3GeworPmc2ZfEEHP7lEbUfBX/L75wdEsi0rLNhXcXxnoN5jyq0SL5gCy06SGW2cyTIZdTvWIDQNQoza++vKeaw==", "devOptional": true, - "requires": { + "license": "MIT", + "dependencies": { "@exodus/bytes": "^1.15.1", "tr46": "^6.0.0", "webidl-conversions": "^8.0.1" + }, + "engines": { + "node": "^22.14.0 || >=24.0.0" } }, - "which": { + "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "requires": { + "dependencies": { "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" } }, - "which-module": { + "node_modules/which-module": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" }, - "why-is-node-running": { + "node_modules/why-is-node-running": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", "devOptional": true, - "requires": { + "license": "MIT", + "dependencies": { "siginfo": "^2.0.0", "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" } }, - "wildcard": { + "node_modules/wildcard": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", - "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==" + "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", + "license": "MIT" }, - "word-wrap": { + "node_modules/word-wrap": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } }, - "wrap-ansi": { + "node_modules/wrap-ansi": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "requires": { + "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" } }, - "wrappy": { + "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, - "ws": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", - "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", - "devOptional": true, - "requires": {} + "node_modules/ws": { + "version": "8.21.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.3.tgz", + "integrity": "sha512-201TZ/kPWxoPr/OKWjquZR1SWKXcvxdH+e1xrx89b3YbmzLMFCLfnaG1HFIgWzJOEWZ7MvpK++odZufgYR50Rw==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } }, - "wsl-utils": { + "node_modules/wsl-utils": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/wsl-utils/-/wsl-utils-0.1.0.tgz", "integrity": "sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==", - "requires": { + "license": "MIT", + "dependencies": { "is-wsl": "^3.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "xhr2": { + "node_modules/xhr2": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/xhr2/-/xhr2-0.2.1.tgz", - "integrity": "sha512-sID0rrVCqkVNUn8t6xuv9+6FViXjUVXq8H5rWOH2rz9fDNQEd4g0EA2XlcEdJXRz5BMEn4O1pJFdT+z4YHhoWw==" + "integrity": "sha512-sID0rrVCqkVNUn8t6xuv9+6FViXjUVXq8H5rWOH2rz9fDNQEd4g0EA2XlcEdJXRz5BMEn4O1pJFdT+z4YHhoWw==", + "license": "MIT", + "engines": { + "node": ">= 6" + } }, - "xml-name-validator": { + "node_modules/xml-name-validator": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==", - "devOptional": true + "devOptional": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18" + } }, - "xmlchars": { + "node_modules/xmlchars": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", - "devOptional": true + "devOptional": true, + "license": "MIT" }, - "xmlhttprequest-ssl": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.1.1.tgz", - "integrity": "sha512-ptjR8YSJIXoA3Mbv5po7RtSYHO6mZr8s7i5VGmEk7QY2pQWyT1o0N+W1gKbOyJPUCGXGnuw0wqe8f0L6Y0ny7g==", - "devOptional": true + "node_modules/xmlhttprequest-ssl": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.1.2.tgz", + "integrity": "sha512-TEU+nJVUUnA4CYJFLvK5X9AOeH4KvDvhIfm0vV1GaQRtchnG0hgK5p8hw/xjv8cunWYCsiPCSDzObPyhEwq3KQ==", + "devOptional": true, + "engines": { + "node": ">=0.4.0" + } }, - "y18n": { + "node_modules/y18n": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==" }, - "yallist": { + "node_modules/yallist": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", - "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==" + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } }, - "yargs": { + "node_modules/yargs": { "version": "18.0.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-18.0.0.tgz", "integrity": "sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg==", - "requires": { + "license": "MIT", + "dependencies": { "cliui": "^9.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", @@ -31173,137 +20500,217 @@ "y18n": "^5.0.5", "yargs-parser": "^22.0.0" }, - "dependencies": { - "ansi-regex": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", - "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==" - }, - "ansi-styles": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", - "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==" - }, - "cliui": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-9.0.1.tgz", - "integrity": "sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==", - "requires": { - "string-width": "^7.2.0", - "strip-ansi": "^7.1.0", - "wrap-ansi": "^9.0.0" - } - }, - "emoji-regex": { - "version": "10.6.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", - "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==" - }, - "string-width": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", - "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", - "requires": { - "emoji-regex": "^10.3.0", - "get-east-asian-width": "^1.0.0", - "strip-ansi": "^7.1.0" - } - }, - "strip-ansi": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", - "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", - "requires": { - "ansi-regex": "^6.2.2" - } - }, - "wrap-ansi": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", - "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", - "requires": { - "ansi-styles": "^6.2.1", - "string-width": "^7.0.0", - "strip-ansi": "^7.1.0" - } - }, - "y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" - }, - "yargs-parser": { - "version": "22.0.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-22.0.0.tgz", - "integrity": "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==" - } + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=23" } }, - "yargs-parser": { + "node_modules/yargs-parser": { "version": "18.1.3", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "requires": { + "dependencies": { "camelcase": "^5.0.0", "decamelize": "^1.2.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/yargs/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/yargs/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/yargs/node_modules/cliui": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-9.0.1.tgz", + "integrity": "sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==", + "license": "ISC", + "dependencies": { + "string-width": "^7.2.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=20" } }, - "yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "node_modules/yargs/node_modules/emoji-regex": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "license": "MIT" + }, + "node_modules/yargs/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yargs/node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/yargs/node_modules/wrap-ansi": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/yargs/node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs/node_modules/yargs-parser": { + "version": "22.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-22.0.0.tgz", + "integrity": "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==", + "license": "ISC", + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=23" + } + }, + "node_modules/yauzl": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-3.4.0.tgz", + "integrity": "sha512-jIH9yLR9wqr0wOS0TpBvo/g/2UgZH5qePVbjgRliiF0BYvOZyaBknKsF+x9Iht0O6sqgnB93rCICdOZFecJuDw==", + "license": "MIT", "optional": true, - "requires": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" + "dependencies": { + "pend": "~1.2.0" + }, + "engines": { + "node": ">=12" } }, - "yn": { + "node_modules/yn": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } }, - "yocto-queue": { + "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==" + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "yoctocolors-cjs": { + "node_modules/yoctocolors-cjs": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/yoctocolors-cjs/-/yoctocolors-cjs-2.1.3.tgz", - "integrity": "sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw==" + "integrity": "sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "zod": { + "node_modules/zod": { "version": "4.1.13", "resolved": "https://registry.npmjs.org/zod/-/zod-4.1.13.tgz", - "integrity": "sha512-AvvthqfqrAhNH9dnfmrfKzX5upOdjUVJYFqNSlkmGf64gRaTzlPwz99IHYnVs28qYAybvAlBV+H7pn0saFY4Ig==" + "integrity": "sha512-AvvthqfqrAhNH9dnfmrfKzX5upOdjUVJYFqNSlkmGf64gRaTzlPwz99IHYnVs28qYAybvAlBV+H7pn0saFY4Ig==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } }, - "zod-to-json-schema": { - "version": "3.25.1", - "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.25.1.tgz", - "integrity": "sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA==", - "requires": {} + "node_modules/zod-to-json-schema": { + "version": "3.25.2", + "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.25.2.tgz", + "integrity": "sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA==", + "license": "ISC", + "peerDependencies": { + "zod": "^3.25.28 || ^4" + } }, - "zone.js": { + "node_modules/zone.js": { "version": "0.15.1", "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.15.1.tgz", - "integrity": "sha512-XE96n56IQpJM7NAoXswY3XRLcWFW83xe0BiAOeMD7K5k5xecOeul3Qcpx6GqEeeHNkW5DWL5zOyTbEfB4eti8w==" + "integrity": "sha512-XE96n56IQpJM7NAoXswY3XRLcWFW83xe0BiAOeMD7K5k5xecOeul3Qcpx6GqEeeHNkW5DWL5zOyTbEfB4eti8w==", + "license": "MIT" }, - "zrender": { + "node_modules/zrender": { "version": "5.4.4", "resolved": "https://registry.npmjs.org/zrender/-/zrender-5.4.4.tgz", "integrity": "sha512-0VxCNJ7AGOMCWeHVyTrGzUgrK4asT4ml9PEkeGirAkKNYXYzoPJCLvmyfdoOXcjTHPs10OZVMfD1Rwg16AZyYw==", - "requires": { - "tslib": "2.3.0" - }, + "license": "BSD-3-Clause", "dependencies": { - "tslib": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", - "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==" - } + "tslib": "2.3.0" } + }, + "node_modules/zrender/node_modules/tslib": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", + "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==", + "license": "0BSD" } } } diff --git a/frontend/package.json b/frontend/package.json index 910ff640bc0..ab13a7afe96 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -3,7 +3,7 @@ "version": "3.3.1", "description": "Bitcoin mempool visualizer and blockchain explorer backend", "license": "GNU Affero General Public License v3.0", - "homepage": "https://mempool.space", + "homepage": "https://explorer.bitcoinuniverse.io", "repository": { "type": "git", "url": "git+https://github.com/mempool/mempool" @@ -58,22 +58,24 @@ "cypress:open:ci:parameterized": "node update-config.js TESTNET_ENABLED=true TESTNET4_ENABLED=true SIGNET_ENABLED=true LIQUID_ENABLED=true ITEMS_PER_PAGE=25 && npm run generate-config && start-server-and-test serve:parameterized 4200 cypress:open", "cypress:run:ci:parameterized": "node update-config.js TESTNET_ENABLED=true TESTNET4_ENABLED=true SIGNET_ENABLED=true LIQUID_ENABLED=true ITEMS_PER_PAGE=25 && npm run generate-config && start-server-and-test serve:parameterized 4200 cypress:run:record", "test:watch": "vitest", - "test:ci": "vitest run --reporter=default" + "test:ci": "vitest run --reporter=default", + "build:universe": "npm run generate-themes && npm run generate-config && npm run ng -- build --configuration production && npm run copy-themes && rsync -a ./src/resources ./dist/mempool/browser/", + "universe:check-bundle": "node ../scripts/universe/check-branding.mjs frontend/dist && node ../scripts/universe/check-origins.mjs frontend/dist" }, "dependencies": { - "@angular-devkit/build-angular": "^20.3.20", - "@angular/animations": "^20.3.18", - "@angular/cli": "^20.3.20", - "@angular/common": "^20.3.18", - "@angular/compiler": "^20.3.18", - "@angular/core": "^20.3.18", - "@angular/forms": "^20.3.18", - "@angular/localize": "^20.3.18", - "@angular/platform-browser": "^20.3.18", - "@angular/platform-browser-dynamic": "^20.3.18", - "@angular/platform-server": "^20.3.18", - "@angular/router": "^20.3.18", - "@angular/ssr": "^20.3.18", + "@angular-devkit/build-angular": "^20.3.35", + "@angular/animations": "^20.3.29", + "@angular/cli": "^20.3.35", + "@angular/common": "^20.3.29", + "@angular/compiler": "^20.3.29", + "@angular/core": "^20.3.29", + "@angular/forms": "^20.3.29", + "@angular/localize": "^20.3.29", + "@angular/platform-browser": "^20.3.29", + "@angular/platform-browser-dynamic": "^20.3.29", + "@angular/platform-server": "^20.3.29", + "@angular/router": "^20.3.29", + "@angular/ssr": "^20.3.35", "@fortawesome/angular-fontawesome": "^3.0.0", "@fortawesome/fontawesome-common-types": "~6.7.2", "@fortawesome/fontawesome-svg-core": "~6.7.2", @@ -93,7 +95,7 @@ "zone.js": "~0.15.1" }, "devDependencies": { - "@angular/compiler-cli": "^20.3.18", + "@angular/compiler-cli": "^20.3.29", "@angular/language-service": "^20.3.18", "@types/node": "^24.9.2", "@typescript-eslint/eslint-plugin": "^8.46.2", diff --git a/frontend/proxy.conf.js b/frontend/proxy.conf.js index 1ef2f693430..7ed200a77af 100644 --- a/frontend/proxy.conf.js +++ b/frontend/proxy.conf.js @@ -26,14 +26,14 @@ PROXY_CONFIG = [ '!/liquidtestnet', '!/liquidtestnet/**', '!/liquidtestnet/', '/testnet/api/**', '/signet/api/**', '/testnet4/api/**', '/regtest/api/**' ], - target: "https://mempool.space", + target: "https://explorer.bitcoinuniverse.io", ws: true, secure: false, changeOrigin: true }, { context: ['/api/v1/ws'], - target: "https://mempool.space", + target: "https://explorer.bitcoinuniverse.io", ws: true, secure: false, changeOrigin: true, @@ -57,7 +57,7 @@ PROXY_CONFIG = [ }, { context: ['/resources/mining-pools/**'], - target: "https://mempool.space", + target: "https://explorer.bitcoinuniverse.io", secure: false, changeOrigin: true } @@ -75,7 +75,7 @@ if (configContent && configContent.BASE_MODULE == "liquid") { } else { PROXY_CONFIG.push({ context: ['/resources/assets.json', '/resources/assets.minimal.json', '/resources/worldmap.json'], - target: "https://mempool.space", + target: "https://explorer.bitcoinuniverse.io", secure: false, changeOrigin: true, }); diff --git a/frontend/proxy.conf.local-esplora.js b/frontend/proxy.conf.local-esplora.js index 34acd1cb0b7..0bb7e0cdb5a 100644 --- a/frontend/proxy.conf.local-esplora.js +++ b/frontend/proxy.conf.local-esplora.js @@ -102,7 +102,7 @@ PROXY_CONFIG.push(...[ /* Optional proxy to route dev to official acceleration services { context: ['/api/v1/services/accelerator/**'], - target: `https://mempool.space/api/v1/services/accelerator/`, + target: `https://explorer.bitcoinuniverse.io/api/v1/services/accelerator/`, secure: false, changeOrigin: true, proxyTimeout: 30000, diff --git a/frontend/proxy.conf.mixed.js b/frontend/proxy.conf.mixed.js index 799ce337ea1..9645c599be2 100644 --- a/frontend/proxy.conf.mixed.js +++ b/frontend/proxy.conf.mixed.js @@ -101,7 +101,7 @@ PROXY_CONFIG.push(...[ }, { context: ['/api/**'], - target: `https://mempool.space`, + target: `https://explorer.bitcoinuniverse.io`, secure: false, changeOrigin: true, proxyTimeout: 30000, diff --git a/frontend/proxy.conf.parameterized.js b/frontend/proxy.conf.parameterized.js index 95ec26ddcea..250feb42a34 100644 --- a/frontend/proxy.conf.parameterized.js +++ b/frontend/proxy.conf.parameterized.js @@ -9,13 +9,13 @@ const addApiKeyHeader = (proxyReq) => { PROXY_CONFIG.forEach((entry) => { const mempoolHostname = process.env.MEMPOOL_HOSTNAME ? process.env.MEMPOOL_HOSTNAME - : 'mempool.space'; + : 'explorer.bitcoinuniverse.io'; const liquidHostname = process.env.LIQUID_HOSTNAME ? process.env.LIQUID_HOSTNAME : 'liquid.network'; - entry.target = entry.target.replace('mempool.space', mempoolHostname); + entry.target = entry.target.replace('explorer.bitcoinuniverse.io', mempoolHostname); entry.target = entry.target.replace('liquid.network', liquidHostname); if (entry.onProxyReq) { diff --git a/frontend/src/app/bitcoin.utils.ts b/frontend/src/app/bitcoin.utils.ts index b949cde3c24..47b5177f1a5 100644 --- a/frontend/src/app/bitcoin.utils.ts +++ b/frontend/src/app/bitcoin.utils.ts @@ -73,7 +73,7 @@ export function calcSegwitFeeGains(tx: Transaction) { if (isP2tr) { // every valid taproot input has at least one witness item, however transactions // created before taproot activation don't need to have any witness data - // (see https://mempool.space/tx/b10c007c60e14f9d087e0291d4d0c7869697c6681d979c6639dbd960792b4d41) + // (see /tx/b10c007c60e14f9d087e0291d4d0c7869697c6681d979c6639dbd960792b4d41) if (vin.witness?.length) { if (vin.witness.length === 1) { // key path spend diff --git a/frontend/src/app/components/about/about-sponsors.component.html b/frontend/src/app/components/about/about-sponsors.component.html deleted file mode 100644 index 9471fc78f90..00000000000 --- a/frontend/src/app/components/about/about-sponsors.component.html +++ /dev/null @@ -1,16 +0,0 @@ -
-
-

If you're an individual...

- Become a Community Sponsor - - - -
-
-

If you're a business...

- Become an Enterprise Sponsor - - - -
-
diff --git a/frontend/src/app/components/about/about-sponsors.component.scss b/frontend/src/app/components/about/about-sponsors.component.scss deleted file mode 100644 index 0ee27d1f54f..00000000000 --- a/frontend/src/app/components/about/about-sponsors.component.scss +++ /dev/null @@ -1,50 +0,0 @@ -#become-sponsor-container { - display: flex; - flex-direction: row; - flex-wrap: nowrap; - justify-content: center; - align-items: center; - gap: 20px; - margin: 68px auto; - text-align: center; -} - -#become-sponsor-container.account { - margin: 20px auto; -} - -.become-sponsor { - background-color: var(--bg); - border-radius: 16px; - padding: 12px 20px; - width: 400px; - padding: 40px 20px; -} - -.become-sponsor a { - margin-top: 10px; -} - -#become-sponsor-container .btn { - margin-bottom: 24px; -} - -#become-sponsor-container .ng-fa-icon { - color: #2ecc71; - margin-right: 5px; -} - -#become-sponsor-container .sponsor-feature { - text-align: left; - width: 250px; - margin: 12px auto; - white-space: nowrap; -} - -@media (max-width: 992px) { - - #become-sponsor-container { - flex-wrap: wrap; - } - -} diff --git a/frontend/src/app/components/about/about-sponsors.component.ts b/frontend/src/app/components/about/about-sponsors.component.ts deleted file mode 100644 index be86a9d9325..00000000000 --- a/frontend/src/app/components/about/about-sponsors.component.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { Component, Input } from '@angular/core'; -import { EnterpriseService } from '@app/services/enterprise.service'; - -@Component({ - selector: 'app-about-sponsors', - templateUrl: './about-sponsors.component.html', - styleUrls: ['./about-sponsors.component.scss'], - standalone: false, -}) -export class AboutSponsorsComponent { - @Input() host = 'https://mempool.space'; - @Input() context = 'about'; - - constructor(private enterpriseService: EnterpriseService) { - } - - onSponsorClick(e): boolean { - this.enterpriseService.goal(5); - return true; - } - - onEnterpriseClick(e): boolean { - this.enterpriseService.goal(6); - return true; - } -} diff --git a/frontend/src/app/components/about/about.component.html b/frontend/src/app/components/about/about.component.html deleted file mode 100644 index e52cb5f63b7..00000000000 --- a/frontend/src/app/components/about/about.component.html +++ /dev/null @@ -1,489 +0,0 @@ -
- -
- ® - -
- v{{ packetJsonVersion }} [{{ frontendGitCommitHash }}] - [{{ stateService.env.GIT_COMMIT_HASH_MEMPOOL_SPACE }}] -
-
- -
-
The Mempool Open Source Project ®
-

Our mempool and blockchain explorer for the Bitcoin community, focusing on the transaction fee market and multi-layer ecosystem, completely self-hosted without any trusted third-parties.

-
Be your own explorer™
-
- - - - - - - - - - -
-
-

Whale Sponsors

-
- - - - - - - -
-
- -
-

Chad Sponsors

-
- - - - - -
-
-
-
- -
-

OG Sponsors ❤️

-
- - - - - -
-
- - - -
-

Community Alliances

- -
- - -
-

Project Translators

-
- - - - - -
-
-
-
- - -
-

Project Contributors

- -
- -
-

Project Members

- -
-
- -
-

Powered By

-
- - - -
-
-
-

Managed By

-
- - - -
-
- - - -
-
- - - -
-
-
- diff --git a/frontend/src/app/components/about/about.component.scss b/frontend/src/app/components/about/about.component.scss deleted file mode 100644 index cb0babd612d..00000000000 --- a/frontend/src/app/components/about/about.component.scss +++ /dev/null @@ -1,277 +0,0 @@ - -.about-page { - text-align: center; - - .image { - width: 80px; - height: 80px; - background-size: 100%, 100%; - border-radius: 50%; - margin: 25px; - line-height: 32px; - } - - .image.not-rounded { - border-radius: 0; - } - - .intro { - margin: 25px auto 30px; - margin-top: 25px; - width: 250px; - display: flex; - flex-direction: column; - .logo { - height: 62.5px; - width: 250px; - margin: auto; - } - .version { - text-align: right; - font-size: 10px; - margin-top: -10px; - } - } - - .about-text { - max-width: 550px; - margin: auto; - padding: 10px 15px 15px; - } - - video { - width: 640px; - max-width: 90%; - margin-top: 0; - @media (min-width: 768px) { - height: 360px; - } - } - - .social-icons { - a { - margin: auto 10px; - } - } - - .alliances, - .enterprise-sponsor, - .community-integrations-sponsor, - .maintainers, - .managers { - margin-top: 30px; - margin-bottom: 68px; - scroll-margin: 30px; - - @media (min-width: 768px) { - margin-top: 68px; - } - } - - .maintainers, - .managers { - margin-bottom: 50px; - } - - .community-sponsor, .project-translators { - display: flex; - flex-direction: column; - .wrapper { - margin: 20px auto; - } - .btn-primary { - max-width: 250px; - margin: auto; - height: 45px; - width: 100%; - } - } - - .community-sponsor { - img { - width: 57px; - height: 57px; - } - } - - .whale-sponsor { - img { - width: 70px; - height: 70px; - } - } - - .alliances { - margin-bottom: 100px; - a { - &:nth-child(3) { - position: relative; - top: 10px; - } - } - img { - display: inline-block; - margin: 15px auto; - height: 62px; - @media (min-width: 425px) { - margin: 15px 60px; - } - @media (min-width: 576px) { - margin: 15px 120px; - } - @media (min-width: 850px) { - margin: 50px 30px 0px; - } - } - .liquid { - top: 7px; - position: relative; - } - .copa { - height: auto; - top: 23px; - position: relative; - width: 300px; - } - .sv { - height: 85px; - width: auto; - position: relative; - } - } - - .enterprise-sponsor, - .contributors, - .community-sponsor, - .project-translators, - .community-integrations-sponsor, - .maintainers { - scroll-margin: 30px; - .wrapper { - display: inline-block; - a { - display: inline-block; - &:hover { - text-decoration: none; - img, svg { - transform: scale(1.1); - } - } - img, svg, span { - display: block; - transition: 150ms all; - } - img, svg { - margin: 40px 29px 10px; - &.image.coldcard { - border-radius: 0; - height: auto; - margin: 20px 29px 20px; - } - } - } - } - } - - .community-sponsor .wrapper, .project-translators .wrapper { - margin: 10px auto 20px; - a img { - margin: 6px; - } - } - - .project-translators .wrapper { - a img { - width: 72px; - height: 72px; - } - } - - #project-members a.project-member-avatar img { - margin: 40px 20px 10px; - } - - .copyright { - text-align: left; - max-width: 620px; - padding: 0px 15px; - margin: auto; - line-height: 1.8; - font-size: 87.5%; - color: #e83e8c; - word-wrap: break-word; - font-family: SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace; - ul { - list-style: none; - padding-left: 30px; - li { - margin-bottom: 20px; - margin-top: 20px; - } - } - .title { - text-align: center; - margin-bottom: 25px; - } - } - - .footer-links { - display: flex; - flex-direction: column; - a { - display: inline-block; - margin: 15px auto 0px; - &:last-child { - margin: 20px auto 30px; - } - } - .social-icons { - a { - margin: 45px 10px; - } - .bitcointv svg { - width: 36px; - height: auto; - vertical-align: bottom; - margin-bottom: 2px; - margin-left: 5px; - } - .bitcointv svg:hover { - opacity: 0.75; - } - } - } - - .footer-version { - font-size: 12px; - } -} - -.no-about-margin { - height: 10px; -} - -.community-integrations-sponsor { - max-width: 1110px; - margin: auto; -} - -.community-integrations-sponsor img.image { - width: 64px; - height: 64px; -} - -.wiz-logo { - width: 260px; - max-width: 90vw; - margin: auto; -} - -.enterprise-sponsor { - .wrapper { - display: flex; - flex-wrap: wrap; - justify-content: center; - max-width: 1050px; - } -} diff --git a/frontend/src/app/components/about/about.component.ts b/frontend/src/app/components/about/about.component.ts deleted file mode 100644 index 8b5a21bd2ac..00000000000 --- a/frontend/src/app/components/about/about.component.ts +++ /dev/null @@ -1,140 +0,0 @@ -import { ChangeDetectionStrategy, Component, ElementRef, Inject, LOCALE_ID, OnInit, ViewChild } from '@angular/core'; -import { WebsocketService } from '@app/services/websocket.service'; -import { SeoService } from '@app/services/seo.service'; -import { OpenGraphService } from '@app/services/opengraph.service'; -import { StateService } from '@app/services/state.service'; -import { Observable } from 'rxjs'; -import { ApiService } from '@app/services/api.service'; -import { IBackendInfo } from '@interfaces/websocket.interface'; -import { Router, ActivatedRoute } from '@angular/router'; -import { map, share, tap } from 'rxjs/operators'; -import { ITranslators } from '@interfaces/node-api.interface'; -import { DOCUMENT } from '@angular/common'; -import { EnterpriseService } from '@app/services/enterprise.service'; - -@Component({ - selector: 'app-about', - templateUrl: './about.component.html', - styleUrls: ['./about.component.scss'], - standalone: false, - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class AboutComponent implements OnInit { - @ViewChild('promoVideo') promoVideo: ElementRef; - backendInfo$: Observable; - frontendGitCommitHash = this.stateService.env.GIT_COMMIT_HASH; - packetJsonVersion = this.stateService.env.PACKAGE_JSON_VERSION; - officialMempoolSpace = this.stateService.env.OFFICIAL_MEMPOOL_SPACE; - showNavigateToSponsor = false; - - profiles$: Observable; - translators$: Observable; - allContributors$: Observable; - ogs$: Observable; - - constructor( - private websocketService: WebsocketService, - private seoService: SeoService, - private ogService: OpenGraphService, - public stateService: StateService, - private enterpriseService: EnterpriseService, - private apiService: ApiService, - private router: Router, - private route: ActivatedRoute, - @Inject(LOCALE_ID) public locale: string, - @Inject(DOCUMENT) private document: Document, - ) { } - - ngOnInit() { - this.backendInfo$ = this.stateService.backendInfo$; - this.seoService.setTitle($localize`:@@004b222ff9ef9dd4771b777950ca1d0e4cd4348a:About`); - this.seoService.setDescription($localize`:@@meta.description.about:Learn more about The Mempool Open Source Project®\: enterprise sponsors, individual sponsors, integrations, who contributes, FOSS licensing, and more.`); - this.ogService.setManualOgImage('about.jpg'); - this.websocketService.want(['blocks']); - - this.profiles$ = this.apiService.getAboutPageProfiles$().pipe( - tap((profiles: any) => { - const scrollToSponsors = this.route.snapshot.fragment === 'community-sponsors'; - if (scrollToSponsors && !profiles?.whales?.length && !profiles?.chads?.length) { - return; - } else { - this.goToAnchor(scrollToSponsors); - } - }), - share(), - ); - - this.translators$ = this.apiService.getTranslators$() - .pipe( - map((translators) => { - for (const t in translators) { - if (translators[t] === '') { - delete translators[t]; - } - } - return translators; - }), - tap(() => this.goToAnchor()) - ); - - this.ogs$ = this.apiService.getOgs$(); - - this.allContributors$ = this.apiService.getContributor$().pipe( - map((contributors) => { - return { - regular: contributors.filter((user) => !user.core_constributor), - core: contributors.filter((user) => user.core_constributor), - }; - }), - tap(() => this.goToAnchor()) - ); - } - - ngAfterViewInit() { - this.goToAnchor(); - } - - goToAnchor(scrollToSponsor = false) { - if (!scrollToSponsor) { - return; - } - setTimeout(() => { - if (this.route.snapshot.fragment) { - const el = scrollToSponsor ? this.document.getElementById('community-sponsors-anchor') : this.document.getElementById(this.route.snapshot.fragment); - if (el) { - if (scrollToSponsor) { - el.scrollIntoView({behavior: 'smooth', block: 'center', inline: 'center'}); - } else { - el.scrollIntoView({behavior: 'smooth'}); - } - } - } - }, 1); - } - - sponsor(): void { - if (this.officialMempoolSpace && this.stateService.env.BASE_MODULE === 'mempool') { - this.router.navigateByUrl('/enterprise'); - } else { - this.showNavigateToSponsor = true; - } - } - - showSubtitles(language): boolean { - return ( this.locale.startsWith( language ) && !this.locale.startsWith('en') ); - } - - unmutePromoVideo(): void { - this.promoVideo.nativeElement.muted = false; - } - - onSponsorClick(e): boolean { - this.enterpriseService.goal(5); - return true; - } - - onEnterpriseClick(e): boolean { - this.enterpriseService.goal(6); - return true; - } -} diff --git a/frontend/src/app/components/about/about.module.ts b/frontend/src/app/components/about/about.module.ts deleted file mode 100644 index 8324876b15e..00000000000 --- a/frontend/src/app/components/about/about.module.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { NgModule } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { Routes, RouterModule } from '@angular/router'; -import { AboutComponent } from '@components/about/about.component'; -import { AboutSponsorsComponent } from '@components/about/about-sponsors.component'; -import { SharedModule } from '@app/shared/shared.module'; - -const routes: Routes = [ - { - path: '', - component: AboutComponent, - } -]; - -@NgModule({ - imports: [ - RouterModule.forChild(routes) - ], - exports: [ - RouterModule - ] -}) -export class AboutRoutingModule { } - -@NgModule({ - imports: [ - CommonModule, - AboutRoutingModule, - SharedModule, - ], - declarations: [ - AboutComponent, - AboutSponsorsComponent, - ], - exports: [ - AboutSponsorsComponent, - ] -}) -export class AboutModule { } - - - - - - diff --git a/frontend/src/app/components/accelerate-checkout/accelerate-checkout.component.html b/frontend/src/app/components/accelerate-checkout/accelerate-checkout.component.html deleted file mode 100644 index 339a0a196fc..00000000000 --- a/frontend/src/app/components/accelerate-checkout/accelerate-checkout.component.html +++ /dev/null @@ -1,643 +0,0 @@ -
- @if (accelerateError) { - @if (accelerateError.includes('Payment declined')) { -
-
-

{{ accelerateError }}

-
-
- } @else { -
-
-

Sorry, something went wrong!

-
-
- } -
-
-
- We were not able to accelerate this transaction. Please try again later. -
-
-
-
-
-
- -
-
- } @else if (step === 'quote') { -
- - - - - -
- @if (showDetails) { -
Your transaction
-
-
- - Plus {{ estimate.txSummary.ancestorCount - 1 }} unconfirmed ancestor(s) - - - - - - - - - - - - - - - - - - -
Virtual size
- Size in vbytes of this transaction (including unconfirmed ancestors) -
In-band fees - {{ estimate.txSummary.effectiveFee | number : '1.0-0' }} sats -
- Fees already paid by this transaction (including unconfirmed ancestors) -
-
-
-
- } -
How much faster?
-
-
- - - This will reduce your expected waiting time until the first confirmation to - -
-
- -
-
-
-
-
-
-
- - - -
-
-
-
-
- -
Summary
-
-
- - - - - @if (hasAccessToBalanceMode) { - - - - - - - - - - - } - @else { - - - - - - - - - - - - } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Next block market rate - {{ estimate.targetFeeRate | number : '1.0-0' }} - sat/vB
- Estimated extra fee required - - {{ math.max(0, estimate.nextBlockFee - estimate.txSummary.effectiveFee) | number }} - - sats - -
Target rate - {{ maxRateOptions[selectFeeRateIndex].rate | number : '1.0-0' }} - sat/vB
- Extra fee required - - {{ maxRateOptions[selectFeeRateIndex].fee | number }} - - sats - -
Mempool Accelerator® fees
- Accelerator Service Fee - - +{{ estimate.mempoolBaseFee | number }} - - sats - -
- Transaction Size Surcharge - - +{{ estimate.vsizeFee | number }} - - sats - -
- Estimated acceleration cost ~{{ estimate.targetFeeRate | number : '1.0-0' }} sat/vB - - - {{ estimate.cost + estimate.mempoolBaseFee + estimate.vsizeFee | number }} - - - sats - -
- @if (hasAccessToBalanceMode) { - Maximum acceleration cost - } @else { - Acceleration cost - } - - - {{ cost | number }} - - - sats - - - -
Available balance - {{ estimate.userBalance | number }} - - sats - - - -
-
- -
-
-
-
-
-
-
- -
-
-
- -
-
- - -
-
-
- } - @else if (step === 'summary') { - - - @if (!noCTA) { -
-
-

Accelerate your Bitcoin transaction?

-
-
- } - - @if (!advancedEnabled) { -
-
-
-
- - -
-
- - -
-
-
-
-
- -
-
-
- } @else { -
-
-
-
-
- -
-
-
-
- - -
- -
-
- } -
- -
-
-
-
-
-
-
-
- } @else if (step === 'checkout') { - -
-
-
- - - @if (!calculating) { - For an additional ({{ cost | number }} sats) - } @else { - Calculating cost... - } - - - Reducing expected confirmation time to - -
-
-
- - -
-
-
-
- Payment to mempool.space for acceleration of txid {{ tx.txid.substr(0, 10) }}..{{ tx.txid.substr(-10) }} -
- @if (canPayWithBalance || !(canPayWithBitcoin || canPayWithCashapp || canPayWithApplePay || canPayWithGooglePay)) { -
-
-

Your account will be debited no more than {{ cost | number }} sats

-
- -
-
-
- } @else { -
- @if (canPayWithBitcoin) { -
- @if (invoice) { -

Pay {{ ((invoice.btcDue * 100_000_000) || cost) | number }} sats

- - } @else if (btcpayInvoiceFailed) { -
- - Failed to load invoice - @if (!loadingBtcpayInvoice) { - - } -
- } @else { -

Loading invoice...

-
-
-
- } -
- @if (canPayWithCashapp || canPayWithApplePay || canPayWithGooglePay || canPayWithCardOnFile) { -
-

—— OR ——

-
- } - } - @if (canPayWithCashapp || canPayWithApplePay || canPayWithGooglePay || canPayWithCardOnFile) { -
-

Pay  with

- @if (canPayWithCashapp) { - - } - @if (canPayWithApplePay) { - @if (canPayWithCashapp) { } -
- -
- } - @if (canPayWithGooglePay) { - @if (canPayWithCashapp || canPayWithApplePay) { } -
- -
- } - @if (canPayWithCardOnFile) { - @if (canPayWithCashapp || canPayWithApplePay || canPayWithGooglePay) { } -
- @if (['VISA', 'MASTERCARD', 'JCB', 'DISCOVER', 'DISCOVER_DINERS', 'AMERICAN_EXPRESS'].includes(estimate?.availablePaymentMethods?.cardOnFile?.card?.brand)) { - - } @else { - - } - {{ estimate?.availablePaymentMethods?.cardOnFile?.card?.last_4 }} -
- } -
- } -
- } -
-
- -
-
-
-
-
-
-
-
- -
-
-
- -
-
- } @else if (step === 'cashapp' || step === 'applepay' || step === 'googlepay' || step === 'cardonfile') { - -
-
-

Confirm your payment

-
-
- -
-
-
- Payment to mempool.space for acceleration of txid {{ tx.txid.substr(0, 10) }}..{{ tx.txid.substr(-10) }} -
-
-
- - @if (step === 'cashapp' && !loadingCashapp || step === 'applepay' && !loadingApplePay || step === 'googlepay' && !loadingGooglePay || step === 'cardonfile' && !loadingCardOnFile) { -
-
-
- Total additional cost
- - Pay - - with - -
-
-
-
- } - -
-
-
- @if (step === 'applepay') { -
- } @else if (step === 'cashapp') { -
- } @else if (step === 'googlepay') { -
- } @else if (step === 'cardonfile') { -
- @if (['VISA', 'MASTERCARD', 'JCB', 'DISCOVER', 'DISCOVER_DINERS', 'AMERICAN_EXPRESS'].includes(estimate?.availablePaymentMethods?.cardOnFile?.card?.brand)) { - - } @else { - - } - {{ estimate?.availablePaymentMethods?.cardOnFile?.card?.last_4 }} -
- } - @if (loadingCashapp || loadingApplePay || loadingGooglePay || loadingCardOnFile) { -
- Loading payment method... -
-
- } -
- @if (isTokenizing > 0) { -
-
-
- } -
-
- -
-
-
- -
-
- } - @else if (step === 'processing') { -
-
-

Confirming your payment

-
-
- -
-
-
- -
-
- We are processing your payment... -
-
-
-
-
- } - @else if (step === 'paid') { -
-
-

Accelerating your transaction

-
-
- -
-
-
- Confirming your acceleration with our mining pool partners... - @if (timeSincePaid > 30000) { - ...sorry, this is taking longer than expected... - } -
-
-
-
- } @else if (step === 'success') { -
-
-

- Transaction is being accelerated! -

-
-
-
-
-
- Transaction has been accepted for acceleration by our mining pool partners. -
- @if (accelerationResponse?.receiptUrl) { - - } -
-
-
-
-
- -
-
- } -
- - - - Confirmation expected 
- @if (!calculating) { - ({{ cost | number }} sats) - } @else { - Calculating cost... - } -
-
- - - - - -Accelerate to ~{{ x | number : '1.0-0' }} sat/vB - - -
- - @if (quoteError || cantPayReason) { -
- } -
-
- - - @if (hasAccessToBalanceMode) { - - } @else { - - } - - -Your transaction will be prioritized by up to {{ i | number : '1.1-1' }}% of miners. diff --git a/frontend/src/app/components/accelerate-checkout/accelerate-checkout.component.scss b/frontend/src/app/components/accelerate-checkout/accelerate-checkout.component.scss deleted file mode 100644 index 27a7e0e9051..00000000000 --- a/frontend/src/app/components/accelerate-checkout/accelerate-checkout.component.scss +++ /dev/null @@ -1,240 +0,0 @@ -.close-button { - position: absolute; - top: 0.5em; - right: 0.5em; -} - -.estimating { - color: var(--green) -} - -.accelerate-checkout-inner { - &.input-disabled { - pointer-events: none; - opacity: 0.75; - } -} - -.paymentMethod { - padding: 10px; - background-color: var(--secondary); - border-radius: 10px; - cursor: pointer; -} - -.default-slot:not(:only-child) { - display: none; -} - -.pie { - display: flex; - align-items: center; - max-width: 330px; -} - -.fee-card { - padding: 15px; - background-color: var(--bg); - - .feerate { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - - .rate { - font-size: 0.9em; - .symbol { - color: white; - } - } - } -} - -.btn-border { - border: solid 1px black; - background-color: #0c4a87; -} - -.feerate.active { - background-color: var(--primary) !important; - opacity: 1; - border: 1px solid #007fff !important; -} -.feerate:focus { - box-shadow: none !important; -} - -.grayOut { - opacity: 0.5; -} - -.disabled { - opacity: 0.5; - pointer-events: none; -} - -.table-toggle { - width: 100%; - margin-top: 0.5em; -} - -.tab { - &:first-child { - margin-right: 1px; - } - border: solid 1px black; - border-bottom: none; - background-color: #323655; - border-top-left-radius: 10px !important; - border-top-right-radius: 10px !important; -} -.tab.active { - background-color: #5d659d !important; - opacity: 1; -} -.tab:focus { - box-shadow: none !important; -} - -.table-accelerator { - tr { - td { - padding-top: 0; - padding-bottom: 0; - vertical-align: baseline; - } - - &.group-first { - td { - padding-top: 0.75rem; - } - } - &.group-last, &:last-child { - td { - padding-bottom: 0.75rem; - } - } - &.dashed-top { - border-top: 1px dashed grey; - } - &.dashed-bottom { - border-bottom: 1px dashed grey - } - } - td { - &:first-child { - width: 100vw; - } - &.info { - color: #6c757d; - white-space: initial; - } - &.amt { - text-align: right; - padding-right: 0.2em; - } - &.units { - padding-left: 0.2em; - white-space: nowrap; - display: flex; - justify-content: space-between; - align-items: center; - } - } -} - -.accelerate-cols { - display: flex; - flex-direction: row; - align-items: stretch; - margin-top: 1em; -} - -.payment-area { - background: var(--bg); - margin-top: 0.5rem; - padding: 0.5rem; - @media (max-width: 575px) { - padding-bottom: 1.25rem; - } -} - -.col.pie { - flex-grow: 0; - padding: 0 1em; - position: relative; - top: -15px; -} - -.item { - white-space: initial; -} - -.table-background { - background-color: var(--bg); -} - -.checkout-text { - color: rgb(186, 186, 186); - font-size: 14px; -} - -.btn-accelerate { - background-color: var(--tertiary); -} - -.summary-row { - display: flex; - flex-direction: row; - justify-content: space-between; - align-items: center; - padding: 0 2em; - flex-wrap: wrap; - - @media (max-width: 640px) { - flex-direction: column; - } -} - -.btn-error { - position: absolute; - right: 0; - font-size: 12px; - color: var(--red); - text-align: center; - width: 200px; - white-space: normal; -} - -.btn-error-wrapper { - height: 26px; -} - -.apple-pay-button { - display: inline-block; - -webkit-appearance: -apple-pay-button; - -apple-pay-button-type: plain; /* Use any supported button type. */ -} -.apple-pay-button-black { - -apple-pay-button-style: black; -} -.apple-pay-button-white { - -apple-pay-button-style: white; -} -.apple-pay-button-white-with-line { - -apple-pay-button-style: white-outline; -} - -.btcpay-invoice { - display: flex; - height: 292px; - flex-direction: column; - justify-content: center; - align-items: center; - @media (max-width: 575px) { - height: 75px; - flex-direction: row; - gap: 5px; - } -} \ No newline at end of file diff --git a/frontend/src/app/components/accelerate-checkout/accelerate-checkout.component.ts b/frontend/src/app/components/accelerate-checkout/accelerate-checkout.component.ts deleted file mode 100644 index 7231b25a9b8..00000000000 --- a/frontend/src/app/components/accelerate-checkout/accelerate-checkout.component.ts +++ /dev/null @@ -1,1093 +0,0 @@ -/* eslint-disable no-console */ -import { Component, OnInit, OnDestroy, Output, EventEmitter, Input, ChangeDetectorRef, SimpleChanges, HostListener } from '@angular/core'; -import { Subscription, tap, of, catchError, Observable, switchMap } from 'rxjs'; -import { ServicesApiServices } from '@app/services/services-api.service'; -import { md5 } from '@app/shared/common.utils'; -import { StateService } from '@app/services/state.service'; -import { AudioService } from '@app/services/audio.service'; -import { ETA, EtaService } from '@app/services/eta.service'; -import { Transaction } from '@interfaces/electrs.interface'; -import { MiningStats } from '@app/services/mining.service'; -import { IAuth, AuthServiceMempool } from '@app/services/auth.service'; -import { EnterpriseService } from '@app/services/enterprise.service'; -import { ApiService } from '@app/services/api.service'; -import { isDevMode } from '@angular/core'; -import { StorageService } from '@app/services/storage.service'; - -export type PaymentMethod = 'balance' | 'bitcoin' | 'cashapp' | 'applePay' | 'googlePay' | 'cardOnFile'; - -export type AccelerationEstimate = { - hasAccess: boolean; - txSummary: TxSummary; - nextBlockFee: number; - targetFeeRate: number; - userBalance: number; - enoughBalance: boolean; - cost: number; - mempoolBaseFee: number; - vsizeFee: number; - pools: number[]; - availablePaymentMethods: Record; - unavailable?: boolean; - options: { // recommended bid options - fee: number; // recommended userBid in sats - }[]; -} -export type TxSummary = { - txid: string; // txid of the current transaction - effectiveVsize: number; // Total vsize of the dependency tree - effectiveFee: number; // Total fee of the dependency tree in sats - ancestorCount: number; // Number of ancestors -} - -export interface RateOption { - fee: number; - rate: number; - index: number; -} - -export const MIN_BID_RATIO = 1; -export const DEFAULT_BID_RATIO = 2; -export const MAX_BID_RATIO = 4; - -type CheckoutStep = 'quote' | 'summary' | 'checkout' | 'cashapp' | 'applepay' | 'googlepay' | 'cardonfile' | 'processing' | 'paid' | 'success'; - -@Component({ - selector: 'app-accelerate-checkout', - templateUrl: './accelerate-checkout.component.html', - styleUrls: ['./accelerate-checkout.component.scss'], - standalone: false, -}) -export class AccelerateCheckout implements OnInit, OnDestroy { - @Input() tx: Transaction; - @Input() accelerating: boolean = false; - @Input() miningStats: MiningStats; - @Input() eta: ETA; - @Input() applePayEnabled: boolean = false; - @Input() googlePayEnabled: boolean = true; - @Input() cardOnFileEnabled: boolean = true; - @Input() advancedEnabled: boolean = false; - @Input() forceMobile: boolean = false; - @Input() showDetails: boolean = false; - @Input() noCTA: boolean = false; - @Input() referralCode: string | undefined; - @Output() unavailable = new EventEmitter(); - @Output() completed = new EventEmitter(); - @Output() hasDetails = new EventEmitter(); - @Output() changeMode = new EventEmitter(); - @Output() paymentReceipt = new EventEmitter(); - - calculating = true; - processing = false; - isCheckoutLocked = 0; // reference counter, 0 = unlocked, >0 = locked - isTokenizing = 0; // reference counter, 0 = false, >0 = true - selectedOption: 'wait' | 'accel'; - cantPayReason = ''; - quoteError = ''; // error fetching estimate or initial data - accelerateError = ''; // error executing acceleration - btcpayInvoiceFailed = false; - timePaid: number = 0; // time acceleration requested - math = Math; - isMobile: boolean = window.innerWidth <= 767.98; - isProdDomain = false; - accelerationResponse: { receiptUrl: string | null } | undefined; - - private _step: CheckoutStep = 'summary'; - simpleMode: boolean = true; - timeoutTimer: any; - - authSubscription$: Subscription; - auth: IAuth | null = null; - - // accelerator stuff - accelerationSubscription: Subscription; - difficultySubscription: Subscription; - estimateSubscription: Subscription; - estimate: AccelerationEstimate; - maxBidBoost: number; // sats - cost: number; // sats - etaInfo$: Observable<{ hashratePercentage: number, ETA: number, acceleratedETA: number }>; - showSuccess = false; - hasAncestors: boolean = false; - minExtraCost = 0; - minBidAllowed = 0; - maxBidAllowed = 0; - defaultBid = 0; - userBid = 0; - selectFeeRateIndex = 1; - maxRateOptions: RateOption[] = []; - - // square - loadingCashapp = false; - loadingApplePay = false; - loadingGooglePay = false; - loadingCardOnFile = false; - payments: any; - cashAppPay: any; - applePay: any; - googlePay: any; - conversionsSubscription: Subscription; - conversions: Record; - - // btcpay - loadingBtcpayInvoice = false; - invoice = undefined; - - constructor( - public stateService: StateService, - private apiService: ApiService, - private servicesApiService: ServicesApiServices, - private etaService: EtaService, - private audioService: AudioService, - private cd: ChangeDetectorRef, - private authService: AuthServiceMempool, - private enterpriseService: EnterpriseService, - private storageService: StorageService - ) { - this.isProdDomain = this.stateService.isProdDomain; - - // Check if Apple Pay available - // https://developer.apple.com/documentation/apple_pay_on_the_web/apple_pay_js_api/checking_for_apple_pay_availability#overview - if (window['ApplePaySession']) { - this.applePayEnabled = true; - } - } - - ngOnInit(): void { - this.authSubscription$ = this.authService.getAuth$().subscribe((auth) => { - if (this.auth?.user?.userId !== auth?.user?.userId) { - this.auth = auth; - this.estimate = null; - this.quoteError = null; - this.accelerateError = null; - this.timePaid = 0; - this.btcpayInvoiceFailed = false; - this.moveToStep('summary', true); - } else { - this.auth = auth; - } - }); - this.authService.refreshAuth$().subscribe(); - - const urlParams = new URLSearchParams(window.location.search); - if (urlParams.get('cash_request_id')) { // Redirected from cashapp - this.moveToStep('processing', true); - this.insertSquare(); - this.setupSquare(); - } else { - this.moveToStep('summary', true); - } - - this.conversionsSubscription = this.stateService.conversions$.subscribe( - async (conversions) => { - this.conversions = conversions; - } - ); - } - - ngOnDestroy(): void { - if (this.estimateSubscription) { - this.estimateSubscription.unsubscribe(); - } - if (this.authSubscription$) { - this.authSubscription$.unsubscribe(); - } - } - - ngOnChanges(changes: SimpleChanges): void { - if (changes.accelerating && this.accelerating) { - this.moveToStep('success', true); - } - } - - moveToStep(step: CheckoutStep, force: boolean = false): void { - if (this.isCheckoutLocked > 0 && !force || this.step === 'success') { - return; - } - this.processing = false; - this._step = step; - if (this.timeoutTimer) { - clearTimeout(this.timeoutTimer); - } - if (!this.estimate && ['quote', 'summary', 'checkout', 'processing'].includes(this.step)) { - this.fetchEstimate(); - } - if (this._step === 'checkout') { - this.insertSquare(); - this.enterpriseService.goal(8); - this.scrollToElementWithTimeout('acceleratePreviewAnchor', 'start', 100); - } - if (this._step === 'checkout' && this.canPayWithBitcoin) { - this.btcpayInvoiceFailed = false; - this.invoice = undefined; - this.requestBTCPayInvoice(); - this.scrollToElementWithTimeout('acceleratePreviewAnchor', 'start', 100); - } else if (this._step === 'cashapp') { - this.loadingCashapp = true; - this.setupSquare(); - this.scrollToElementWithTimeout('confirm-title', 'center', 100); - } else if (this._step === 'applepay' && this.applePayEnabled) { - this.loadingApplePay = true; - this.setupSquare(); - this.scrollToElementWithTimeout('confirm-title', 'center', 100); - } else if (this._step === 'googlepay' && this.googlePayEnabled) { - this.loadingGooglePay = true; - this.setupSquare(); - this.scrollToElementWithTimeout('confirm-title', 'center', 100); - } else if (this._step === 'cardonfile' && this.cardOnFileEnabled) { - this.loadingCardOnFile = true; - this.setupSquare(); - this.scrollToElementWithTimeout('confirm-title', 'center', 100); - } else if (this._step === 'paid') { - this.timePaid = Date.now(); - this.timeoutTimer = setTimeout(() => { - if (this.step === 'paid') { - this.accelerateError = 'internal_server_error'; - } - }, 120000); - } - this.hasDetails.emit(this._step === 'quote'); - } - - closeModal(): void { - this.completed.emit(true); - this.moveToStep('summary', true); - } - - /** - * Scroll to element id with or without setTimeout - */ - scrollToElementWithTimeout(id: string, position: ScrollLogicalPosition, timeout: number = 1000): void { - setTimeout(() => { - this.scrollToElement(id, position); - }, timeout); - } - scrollToElement(id: string, position: ScrollLogicalPosition): void { - const acceleratePreviewAnchor = document.getElementById(id); - if (acceleratePreviewAnchor) { - this.cd.markForCheck(); - acceleratePreviewAnchor.scrollIntoView({ - behavior: 'smooth', - inline: position, - block: position, - }); - } - } - - /** - * Accelerator - */ - fetchEstimate(): void { - if (this.estimateSubscription) { - this.estimateSubscription.unsubscribe(); - } - this.calculating = true; - this.quoteError = null; - this.accelerateError = null; - this.estimateSubscription = this.servicesApiService.estimate$(this.tx.txid).pipe( - tap((response) => { - if (response.status === 204) { - this.quoteError = `cannot_accelerate_tx`; - if (this.step === 'summary') { - this.unavailable.emit(true); - } - } else { - this.estimate = response.body; - if (!this.estimate) { - this.quoteError = `cannot_accelerate_tx`; - if (this.step === 'summary') { - this.unavailable.emit(true); - } - return; - } - if (this.estimate.hasAccess === true && this.estimate.userBalance <= 0) { - if (this.isLoggedIn()) { - this.quoteError = `not_enough_balance`; - } - } - if (this.estimate.unavailable) { - this.quoteError = `temporarily_unavailable`; - } - this.hasAncestors = this.estimate.txSummary.ancestorCount > 1; - this.etaInfo$ = this.etaService.getProjectedEtaObservable(this.estimate, this.miningStats); - - this.maxRateOptions = this.estimate.options.map((option, index) => ({ - fee: option.fee, - rate: (this.estimate.txSummary.effectiveFee + option.fee) / this.estimate.txSummary.effectiveVsize, - index - })); - - this.defaultBid = this.maxRateOptions[1].fee; - this.userBid = this.defaultBid; - this.cost = this.userBid + this.estimate.mempoolBaseFee + this.estimate.vsizeFee; - - this.validateChoice(); - - if (!this.couldPay) { - this.quoteError = `cannot_accelerate_tx`; - if (this.step === 'summary') { - this.unavailable.emit(true); - } - return; - } - - if (this.step === 'checkout' && this.canPayWithBitcoin && !this.loadingBtcpayInvoice) { - this.requestBTCPayInvoice(); - } - - this.calculating = false; - this.cd.markForCheck(); - } - }), - - catchError(() => { - this.estimate = undefined; - this.quoteError = `cannot_accelerate_tx`; - this.estimateSubscription.unsubscribe(); - if (this.step === 'summary') { - this.unavailable.emit(true); - } else { - this.accelerateError = 'cannot_accelerate_tx'; - } - return of(null); - }) - ).subscribe(); - } - - validateChoice(): void { - if (!this.canPay) { - if (this.estimate?.availablePaymentMethods?.balance) { - if (this.cost >= this.estimate?.userBalance) { - this.cantPayReason = 'not_enough_balance'; - } - } else { - this.cantPayReason = 'cannot_accelerate_tx'; - } - } else { - this.cantPayReason = ''; - } - } - - /** - * User changed his bid - */ - setUserBid({ fee, index }: { fee: number, index: number}): void { - if (this.estimate) { - this.selectFeeRateIndex = index; - this.userBid = Math.max(0, fee); - this.cost = this.userBid + this.estimate.mempoolBaseFee + this.estimate.vsizeFee; - this.validateChoice(); - } - } - - /** - * Account-based acceleration request - */ - accelerateWithMempoolAccount(): void { - if (!this.canPay || this.calculating || this.processing) { - return; - } - this.processing = true; - if (this.accelerationSubscription) { - this.accelerationSubscription.unsubscribe(); - } - this.accelerationSubscription = this.servicesApiService.accelerate$( - this.tx.txid, - this.userBid, - ).subscribe({ - next: () => { - this.processing = false; - this.apiService.logAccelerationRequest$(this.tx.txid).subscribe(); - this.audioService.playSound('ascend-chime-cartoon'); - this.showSuccess = true; - this.estimateSubscription.unsubscribe(); - this.moveToStep('paid', true); - }, - error: (response) => { - this.processing = false; - this.accelerateError = response.error; - } - }); - } - - /** - * Square - */ - insertSquare(): void { - if (!this.isProdDomain && !isDevMode()) { - return; - } - if (window['Square']) { - return; - } - let statsUrl = 'https://sandbox.web.squarecdn.com/v1/square.js'; - if (this.isProdDomain) { - statsUrl = '/square/v1/square.js'; - } - - (function(): void { - const d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0]; - g.type='text/javascript'; g.src=statsUrl; s.parentNode.insertBefore(g, s); - })(); - } - setupSquare(): void { - if (!this.isProdDomain && !isDevMode()) { - return; - } - const init = (): void => { - this.initSquare(); - }; - - if (!window['Square']) { - console.debug('Square.js failed to load properly. Retrying.'); - setTimeout(this.setupSquare.bind(this), 100); - } else { - init(); - } - } - async initSquare(): Promise { - try { - this.servicesApiService.setupSquare$().subscribe({ - next: async (ids) => { - this.payments = window['Square'].payments(ids.squareAppId, ids.squareLocationId); - const urlParams = new URLSearchParams(window.location.search); - if (this._step === 'cashapp' || urlParams.get('cash_request_id')) { - await this.requestCashAppPayment(); - } else if (this._step === 'applepay') { - await this.requestApplePayPayment(); - } else if (this._step === 'googlepay') { - await this.requestGooglePayPayment(); - } else if (this._step === 'cardonfile') { - this.loadingCardOnFile = false; - } - }, - error: () => { - console.debug('Error loading Square Payments'); - this.accelerateError = 'cannot_setup_square'; - } - }); - } catch (e) { - console.debug('Error loading Square Payments', e); - this.accelerateError = 'cannot_setup_square'; - } - } - - /** - * APPLE PAY - */ - async requestApplePayPayment(): Promise { - if (this.processing) { - return; - } - - this.processing = true; - - if (this.applePay) { - this.applePay.destroy(); - } - - const costUSD = this.cost / 100_000_000 * this.conversions.USD; - const paymentRequest = this.payments.paymentRequest({ - countryCode: 'US', - currencyCode: 'USD', - total: { - amount: costUSD.toFixed(2), - label: 'Total', - }, - }); - - try { - this.applePay = await this.payments.applePay(paymentRequest); - const applePayButton = document.getElementById('apple-pay-button'); - if (!applePayButton) { - console.error(`Unable to find apple pay button id='apple-pay-button'`); - // Try again - setTimeout(this.requestApplePayPayment.bind(this), 500); - this.processing = false; - return; - } - this.loadingApplePay = false; - applePayButton.addEventListener('click', async event => { - if (this.isCheckoutLocked > 0 || this.isTokenizing > 0) { - return; - } - event.preventDefault(); - try { - // lock the checkout UI and show a loading spinner until the square modals are finished - this.isCheckoutLocked++; - this.isTokenizing++; - const tokenResult = await this.applePay.tokenize(); - if (tokenResult?.status === 'OK') { - const card = tokenResult.details?.card; - if (!card || !card.brand || !card.expMonth || !card.expYear || !card.last4) { - console.error(`Cannot retrieve payment card details`); - this.accelerateError = 'apple_pay_no_card_details'; - this.processing = false; - return; - } - const cardTag = md5(`${card.brand}${card.expMonth}${card.expYear}${card.last4}`.toLowerCase()); - // keep checkout in loading state until the acceleration request completes - this.isTokenizing++; - this.isCheckoutLocked++; - this.servicesApiService.accelerateWithApplePay$( - this.tx.txid, - tokenResult.token, - cardTag, - `accelerator-${this.tx.txid.substring(0, 15)}-${Math.round(new Date().getTime() / 1000)}`, - costUSD, - this.referralCode - ).subscribe({ - next: (response) => { - this.storageService.removeItem('referralCode'); // Consume localStorage referralCode - this.accelerationResponse = response; - this.processing = false; - this.apiService.logAccelerationRequest$(this.tx.txid).subscribe(); - this.audioService.playSound('ascend-chime-cartoon'); - if (this.applePay) { - this.applePay.destroy(); - } - this.paymentReceipt.emit(this.accelerationResponse?.receiptUrl); - setTimeout(() => { - this.isTokenizing--; - this.isCheckoutLocked--; - this.moveToStep('paid', true); - }, 1000); - }, - error: (response) => { - this.processing = false; - this.accelerateError = response.error; - if (!(response.status === 403 && response.error === 'not_available')) { - setTimeout(() => { - this.isTokenizing--; - this.isCheckoutLocked--; - // Reset everything by reloading the page :D, can be improved - const urlParams = new URLSearchParams(window.location.search); - window.location.assign(window.location.toString().replace(`?cash_request_id=${urlParams.get('cash_request_id')}`, ``)); - }, 10000); - } - } - }); - } else { - this.processing = false; - let errorMessage = `Tokenization failed with status: ${tokenResult.status}`; - if (tokenResult.errors) { - errorMessage += ` and errors: ${JSON.stringify( - tokenResult.errors, - )}`; - } - throw new Error(errorMessage); - } - } finally { - // always unlock the checkout once we're finished - this.isTokenizing--; - this.isCheckoutLocked--; - } - }); - } catch (e) { - this.processing = false; - console.error(e); - } - } - - /** - * GOOGLE PAY - */ - async requestGooglePayPayment(): Promise { - if (this.processing) { - return; - } - - this.processing = true; - - if (this.googlePay) { - this.googlePay.destroy(); - } - - const costUSD = this.cost / 100_000_000 * this.conversions.USD; - const paymentRequest = this.payments.paymentRequest({ - countryCode: 'US', - currencyCode: 'USD', - total: { - amount: costUSD.toFixed(2), - label: 'Total' - } - }); - this.googlePay = await this.payments.googlePay(paymentRequest , { - referenceId: `accelerator-${this.tx.txid.substring(0, 15)}-${Math.round(new Date().getTime() / 1000)}`, - }); - - await this.googlePay.attach(`#google-pay-button`, { - buttonType: 'pay', - buttonSizeMode: 'fill', - }); - this.loadingGooglePay = false; - - document.getElementById('google-pay-button').addEventListener('click', async event => { - if (this.isCheckoutLocked > 0 || this.isTokenizing > 0) { - return; - } - event.preventDefault(); - try { - // lock the checkout UI and show a loading spinner until the square modals are finished - this.isCheckoutLocked++; - this.isTokenizing++; - const tokenResult = await this.googlePay.tokenize(); - if (tokenResult?.status === 'OK') { - const card = tokenResult.details?.card; - if (!card || !card.brand || !card.expMonth || !card.expYear || !card.last4) { - console.error(`Cannot retrieve payment card details`); - this.accelerateError = 'apple_pay_no_card_details'; - this.processing = false; - return; - } - const verificationToken = await this.$verifyBuyer(this.payments, tokenResult.token, tokenResult.details, costUSD.toFixed(2)); - if (!verificationToken || !verificationToken.token) { - console.error(`SCA verification failed`); - this.accelerateError = 'SCA Verification Failed. Payment Declined.'; - this.processing = false; - return; - } - const cardTag = md5(`${card.brand}${card.expMonth}${card.expYear}${card.last4}`.toLowerCase()); - // keep checkout in loading state until the acceleration request completes - this.isCheckoutLocked++; - this.isTokenizing++; - this.servicesApiService.accelerateWithGooglePay$( - this.tx.txid, - tokenResult.token, - verificationToken.token, - cardTag, - `accelerator-${this.tx.txid.substring(0, 15)}-${Math.round(new Date().getTime() / 1000)}`, - costUSD, - verificationToken.userChallenged, - this.referralCode - ).subscribe({ - next: (response) => { - this.storageService.removeItem('referralCode'); // Consume localStorage referralCode - this.accelerationResponse = response; - this.processing = false; - this.apiService.logAccelerationRequest$(this.tx.txid).subscribe(); - this.audioService.playSound('ascend-chime-cartoon'); - if (this.googlePay) { - this.googlePay.destroy(); - } - this.paymentReceipt.emit(this.accelerationResponse?.receiptUrl); - setTimeout(() => { - this.isTokenizing--; - this.isCheckoutLocked--; - this.moveToStep('paid', true); - }, 1000); - }, - error: (response) => { - this.processing = false; - this.accelerateError = response.error; - this.isTokenizing--; - this.isCheckoutLocked--; - if (!(response.status === 403 && response.error === 'not_available')) { - setTimeout(() => { - // Reset everything by reloading the page :D, can be improved - const urlParams = new URLSearchParams(window.location.search); - window.location.assign(window.location.toString().replace(`?cash_request_id=${urlParams.get('cash_request_id')}`, ``)); - }, 10000); - } - } - }); - } else { - this.processing = false; - let errorMessage = `Tokenization failed with status: ${tokenResult.status}`; - if (tokenResult.errors) { - errorMessage += ` and errors: ${JSON.stringify( - tokenResult.errors, - )}`; - } - throw new Error(errorMessage); - } - } finally { - // always unlock the checkout once we're finished - this.isTokenizing--; - this.isCheckoutLocked--; - } - }); - } - - /** - * Card On File - */ - async requestCardOnFilePayment(): Promise { - if (this.processing) { - return; - } - - this.processing = true; - - const costUSD = this.cost / 100_000_000 * this.conversions.USD; - if (this.isCheckoutLocked > 0) { - return; - } - const cardOnFile = this.estimate?.availablePaymentMethods?.cardOnFile; - if (!cardOnFile?.card) { - this.accelerateError = 'card_on_file_not_found'; - return; - } - this.loadingCardOnFile = false; - - try { - this.isCheckoutLocked += 2; - this.isTokenizing += 2; - - const nameParts = cardOnFile.card.name.split(' '); - const assumedGivenName = nameParts[0]; - const assumedFamilyName = nameParts.length > 1 ? nameParts[1] : undefined; - const verificationDetails = { - card: { - billing: { - givenName: assumedGivenName, - familyName: assumedFamilyName, - addressLines: [cardOnFile.card.billing.addressLine1 ?? ''], - city: cardOnFile.card.billing.locality ?? '', - state: cardOnFile.card.billing.administrativeDistrictLevel1 ?? '', - countyCode: cardOnFile.card.billing.country, - } - } - }; - const verificationToken = await this.$verifyBuyer(this.payments, cardOnFile.card.card_id, verificationDetails, costUSD.toFixed(2)); - if (!verificationToken || !verificationToken.token) { - console.error(`SCA verification failed`); - this.accelerateError = 'SCA Verification Failed. Payment Declined.'; - this.processing = false; - return; - } - - this.servicesApiService.accelerateWithCardOnFile$( - this.tx.txid, - cardOnFile.card.card_id, - verificationToken.token, - `accelerator-${this.tx.txid.substring(0, 15)}-${Math.round(new Date().getTime() / 1000)}`, - costUSD, - verificationToken.userChallenged, - this.referralCode - ).subscribe({ - next: (response) => { - this.storageService.removeItem('referralCode'); // Consume localStorage referralCode - this.accelerationResponse = response; - this.processing = false; - this.apiService.logAccelerationRequest$(this.tx.txid).subscribe(); - this.audioService.playSound('ascend-chime-cartoon'); - this.paymentReceipt.emit(this.accelerationResponse?.receiptUrl); - setTimeout(() => { - this.isCheckoutLocked--; - this.isTokenizing--; - this.moveToStep('paid', true); - }, 1000); - }, - error: (response) => { - this.processing = false; - this.accelerateError = response.error; - this.isCheckoutLocked--; - this.isTokenizing--; - if (!(response.status === 403 && response.error === 'not_available')) { - setTimeout(() => { - // Reset everything by reloading the page :D, can be improved - const urlParams = new URLSearchParams(window.location.search); - window.location.assign(window.location.toString().replace(`?cash_request_id=${urlParams.get('cash_request_id')}`, ``)); - }, 3000); - } - } - }); - - } catch (e) { - console.log(e); - this.isCheckoutLocked--; - this.isTokenizing--; - this.processing = false; - this.accelerateError = e.message; - - } finally { - // always unlock the checkout once we're finished - this.isCheckoutLocked--; - this.isTokenizing--; - } - } - - /** - * CASHAPP - */ - async requestCashAppPayment(): Promise { - if (this.processing) { - return; - } - - this.processing = true; - - if (this.cashAppPay) { - this.cashAppPay.destroy(); - } - - const redirectHostname = document.location.hostname === 'localhost' ? `http://localhost:4200`: `https://${document.location.hostname}`; - const costUSD = this.cost / 100_000_000 * this.conversions.USD; - const paymentRequest = this.payments.paymentRequest({ - countryCode: 'US', - currencyCode: 'USD', - total: { - amount: costUSD.toFixed(2), - label: 'Total', - pending: true, - productUrl: `${redirectHostname}/tx/${this.tx.txid}`, - } - }); - this.cashAppPay = await this.payments.cashAppPay(paymentRequest, { - redirectURL: `${redirectHostname}/tx/${this.tx.txid}`, - referenceId: `accelerator-${this.tx.txid.substring(0, 15)}-${Math.round(new Date().getTime() / 1000)}` - }); - - await this.cashAppPay.attach(`#cash-app-pay`, { theme: 'dark' }); - this.loadingCashapp = false; - - this.cashAppPay.addEventListener('ontokenization', event => { - const { tokenResult, error } = event.detail; - if (error) { - this.processing = false; - this.accelerateError = error; - } else if (tokenResult.status === 'OK') { - this.servicesApiService.accelerateWithCashApp$( - this.tx.txid, - tokenResult.token, - tokenResult.details.cashAppPay.cashtag, - tokenResult.details.cashAppPay.referenceId, - costUSD, - this.referralCode - ).subscribe({ - next: (response) => { - this.storageService.removeItem('referralCode'); // Consume localStorage referralCode - this.accelerationResponse = response; - this.processing = false; - this.apiService.logAccelerationRequest$(this.tx.txid).subscribe(); - this.audioService.playSound('ascend-chime-cartoon'); - if (this.cashAppPay) { - this.cashAppPay.destroy(); - } - this.paymentReceipt.emit(this.accelerationResponse?.receiptUrl); - setTimeout(() => { - this.moveToStep('paid', true); - if (window.history.replaceState) { - const urlParams = new URLSearchParams(window.location.search); - window.history.replaceState(null, null, window.location.toString().replace(`?cash_request_id=${urlParams.get('cash_request_id')}`, '')); - } - }, 1000); - }, - error: (response) => { - this.processing = false; - this.accelerateError = response.error; - if (!(response.status === 403 && response.error === 'not_available')) { - setTimeout(() => { - // Reset everything by reloading the page :D, can be improved - const urlParams = new URLSearchParams(window.location.search); - window.location.assign(window.location.toString().replace(`?cash_request_id=${urlParams.get('cash_request_id')}`, ``)); - }, 10000); - } - } - }); - } - }); - } - - /** - * https://developer.squareup.com/docs/sca-overview - */ - async $verifyBuyer(payments, token, details, amount): Promise<{token: string, userChallenged: boolean}> { - const verificationDetails = { - amount: amount, - currencyCode: 'USD', - intent: 'CHARGE', - billingContact: { - givenName: details.card?.billing?.givenName, - familyName: details.card?.billing?.familyName, - phone: details.card?.billing?.phone, - addressLines: details.card?.billing?.addressLines, - city: details.card?.billing?.city, - state: details.card?.billing?.state, - countryCode: details.card?.billing?.countryCode, - }, - }; - - const verificationResults = await payments.verifyBuyer( - token, - verificationDetails, - ); - return verificationResults; - } - - /** - * BTCPay - */ - async requestBTCPayInvoice(): Promise { - this.loadingBtcpayInvoice = true; - this.servicesApiService.generateBTCPayAcceleratorInvoice$(this.tx.txid, this.userBid, this.referralCode).pipe( - switchMap(response => { - return this.servicesApiService.retrieveInvoice$(response.btcpayInvoiceId); - }), - catchError(error => { - console.log(error); - this.loadingBtcpayInvoice = false; - this.btcpayInvoiceFailed = true; - return of(null); - }) - ).subscribe((invoice) => { - this.loadingBtcpayInvoice = false; - this.invoice = invoice; - this.cd.markForCheck(); - }); - } - - bitcoinPaymentCompleted(): void { - this.apiService.logAccelerationRequest$(this.tx.txid).subscribe(); - this.audioService.playSound('ascend-chime-cartoon'); - this.estimateSubscription.unsubscribe(); - this.moveToStep('paid', true); - } - - isLoggedIn(): boolean { - return this.auth !== null; - } - - /** - * UI events - */ - selectedOptionChanged(event): void { - this.selectedOption = event.target.id; - } - - get step(): CheckoutStep { - return this._step; - } - - get paymentMethods(): PaymentMethod[] { - return Object.keys(this.estimate?.availablePaymentMethods || {}) as PaymentMethod[]; - } - - get couldPayWithBitcoin(): boolean { - return !!this.estimate?.availablePaymentMethods?.bitcoin; - } - - get couldPayWithCashapp(): boolean { - return !!this.estimate?.availablePaymentMethods?.cashapp; - } - - get couldPayWithApplePay(): boolean { - if (!this.applePayEnabled) { - return false; - } - return !!this.estimate?.availablePaymentMethods?.applePay; - } - - get couldPayWithGooglePay(): boolean { - if (!this.googlePayEnabled) { - return false; - } - return !!this.estimate?.availablePaymentMethods?.googlePay; - } - - get couldPayWithBalance(): boolean { - if (!this.hasAccessToBalanceMode) { - return false; - } - return !!this.estimate?.availablePaymentMethods?.balance; - } - - get couldPay(): boolean { - return this.couldPayWithBalance || this.couldPayWithBitcoin || this.couldPayWithCashapp || this.couldPayWithApplePay || this.couldPayWithGooglePay; - } - - get canPayWithBitcoin(): boolean { - const paymentMethod = this.estimate?.availablePaymentMethods?.bitcoin; - return paymentMethod && this.cost >= paymentMethod.min && this.cost <= paymentMethod.max; - } - - get canPayWithCashapp(): boolean { - if (!this.conversions || (!this.isProdDomain && !isDevMode())) { - return false; - } - - const paymentMethod = this.estimate?.availablePaymentMethods?.cashapp; - if (paymentMethod) { - const costUSD = (this.cost / 100_000_000 * this.conversions.USD); - if (costUSD >= paymentMethod.min && costUSD <= paymentMethod.max) { - return true; - } - } - - return false; - } - - get canPayWithApplePay(): boolean { - if (!this.applePayEnabled || !this.conversions || (!this.isProdDomain && !isDevMode())) { - return false; - } - - const paymentMethod = this.estimate?.availablePaymentMethods?.applePay; - if (paymentMethod) { - const costUSD = (this.cost / 100_000_000 * this.conversions.USD); - if (costUSD >= paymentMethod.min && costUSD <= paymentMethod.max) { - return true; - } - } - - return false; - } - - get canPayWithGooglePay(): boolean { - if (!this.googlePayEnabled || !this.conversions || (!this.isProdDomain && !isDevMode())) { - return false; - } - - const paymentMethod = this.estimate?.availablePaymentMethods?.googlePay; - if (paymentMethod) { - const costUSD = (this.cost / 100_000_000 * this.conversions.USD); - if (costUSD >= paymentMethod.min && costUSD <= paymentMethod.max) { - return true; - } - } - - return false; - } - - get canPayWithCardOnFile(): boolean { - if (!this.cardOnFileEnabled || !this.conversions || (!this.isProdDomain && !isDevMode())) { - return false; - } - - const paymentMethod = this.estimate?.availablePaymentMethods?.cardOnFile; - if (paymentMethod) { - const costUSD = (this.cost / 100_000_000 * this.conversions.USD); - if (costUSD >= paymentMethod.min && costUSD <= paymentMethod.max) { - return true; - } - } - - return false; - } - - get canPayWithBalance(): boolean { - if (!this.hasAccessToBalanceMode) { - return false; - } - const paymentMethod = this.estimate?.availablePaymentMethods?.balance; - return paymentMethod && this.cost >= paymentMethod.min && this.cost <= paymentMethod.max && this.cost <= this.estimate?.userBalance; - } - - get canPay(): boolean { - return this.canPayWithBalance || this.canPayWithBitcoin || this.canPayWithCashapp || this.canPayWithApplePay || this.canPayWithGooglePay; - } - - get hasAccessToBalanceMode(): boolean { - return this.isLoggedIn() && this.estimate?.hasAccess; - } - - get timeSincePaid(): number { - return Date.now() - this.timePaid; - } - - @HostListener('window:resize', ['$event']) - onResize(): void { - this.isMobile = window.innerWidth <= 767.98; - } -} diff --git a/frontend/src/app/components/accelerate-checkout/accelerate-fee-graph.component.html b/frontend/src/app/components/accelerate-checkout/accelerate-fee-graph.component.html deleted file mode 100644 index 564ee0ad1f0..00000000000 --- a/frontend/src/app/components/accelerate-checkout/accelerate-fee-graph.component.html +++ /dev/null @@ -1,21 +0,0 @@ -
-
- -
-
-
-

- {{ bar.label }} - - - -

-
-
- {{ bar.class === 'tx' ? '' : '+' }}{{ bar.fee | number }} sats -
-
-
-
-
-
diff --git a/frontend/src/app/components/accelerate-checkout/accelerate-fee-graph.component.scss b/frontend/src/app/components/accelerate-checkout/accelerate-fee-graph.component.scss deleted file mode 100644 index 919fdec4a18..00000000000 --- a/frontend/src/app/components/accelerate-checkout/accelerate-fee-graph.component.scss +++ /dev/null @@ -1,156 +0,0 @@ -.fee-graph { - height: 100%; - min-width: 120px; - width: 120px; - margin-left: 4em; - margin-right: 1.5em; - - .column { - width: 100%; - height: 100%; - position: relative; - background: var(--stat-box-bg); - - .bar { - position: absolute; - bottom: 0; - left: 0; - right: 0; - min-height: 30px; - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - - .fill { - position: absolute; - left: 0; - right: 0; - top: 0; - bottom: 0; - opacity: 0.75; - pointer-events: none; - } - - .fee { - font-size: 0.9em; - opacity: 0; - pointer-events: none; - } - - .spacer { - width: 100%; - height: 1px; - flex-grow: 1; - pointer-events: none; - } - - .line { - position: absolute; - right: 0; - top: 0; - left: -4.5em; - border-top: dashed white 1.5px; - - .fee-rate { - width: 100%; - position: absolute; - left: 0; - right: 0.2em; - font-size: 0.8em; - display: flex; - flex-direction: row-reverse; - justify-content: space-between; - margin: 0; - - .label { - margin-right: .2em; - } - - .rate .symbol { - color: white; - } - } - } - - &.tx { - .fill { - background: var(--green); - } - .line { - .fee-rate { - top: 0; - } - } - .fee { - position: absolute; - opacity: 1; - z-index: 11; - } - } - - &.target { - .fill { - background: var(--tertiary); - } - .fee { - position: absolute; - opacity: 1; - z-index: 11; - } - .line .fee-rate { - bottom: 2px; - } - } - - &.max { - cursor: pointer; - .line .fee-rate { - .label { - opacity: 0; - } - bottom: 2px; - } - &.active, &:hover { - .fill { - background: var(--primary); - } - .line { - .fee-rate .label { - opacity: 1; - } - } - } - } - - &:hover { - .fill { - z-index: 10; - } - .line { - z-index: 11; - } - .fee { - opacity: 1; - z-index: 12; - } - } - } - - &:hover > .bar:not(:hover) { - &.target, &.max { - .fee { - opacity: 0; - } - .line .fee-rate .label { - opacity: 0; - } - } - &.max { - .fill { - background: none; - } - } - } - } -} \ No newline at end of file diff --git a/frontend/src/app/components/accelerate-checkout/accelerate-fee-graph.component.ts b/frontend/src/app/components/accelerate-checkout/accelerate-fee-graph.component.ts deleted file mode 100644 index e0d0d1a2b1e..00000000000 --- a/frontend/src/app/components/accelerate-checkout/accelerate-fee-graph.component.ts +++ /dev/null @@ -1,153 +0,0 @@ -import { Component, Input, Output, OnChanges, EventEmitter, HostListener, OnInit, ViewChild, ElementRef, AfterViewInit, OnDestroy, ChangeDetectorRef } from '@angular/core'; -import { Transaction } from '@interfaces/electrs.interface'; -import { AccelerationEstimate, RateOption } from '@components/accelerate-checkout/accelerate-checkout.component'; - -interface GraphBar { - rate: number; - style?: Record; - class: 'tx' | 'target' | 'max'; - label: string; - active?: boolean; - rateIndex?: number; - fee?: number; - height?: number; -} - -@Component({ - selector: 'app-accelerate-fee-graph', - templateUrl: './accelerate-fee-graph.component.html', - styleUrls: ['./accelerate-fee-graph.component.scss'], - standalone: false, -}) -export class AccelerateFeeGraphComponent implements OnInit, AfterViewInit, OnChanges, OnDestroy { - @Input() tx: Transaction; - @Input() estimate: AccelerationEstimate; - @Input() showEstimate = false; - @Input() maxRateOptions: RateOption[] = []; - @Input() maxRateIndex: number = 0; - @Output() setUserBid = new EventEmitter<{ fee: number, index: number }>(); - - @ViewChild('feeGraph') - container: ElementRef; - height: number; - observer: ResizeObserver; - stopResizeLoop = false; - - bars: GraphBar[] = []; - tooltipPosition = { x: 0, y: 0 }; - - constructor( - private cd: ChangeDetectorRef, - ) {} - - ngOnInit(): void { - this.initGraph(); - } - - ngAfterViewInit(): void { - if (ResizeObserver) { - this.observer = new ResizeObserver(entries => { - for (const entry of entries) { - this.height = entry.contentRect.height; - this.initGraph(); - } - }); - this.observer.observe(this.container.nativeElement); - } else { - this.startResizeFallbackLoop(); - } - } - - ngOnChanges(): void { - this.initGraph(); - } - - initGraph(): void { - if (!this.tx || !this.estimate) { - return; - } - const hasNextBlockRate = (this.estimate.nextBlockFee > this.estimate.txSummary.effectiveFee); - const numBars = hasNextBlockRate ? 4 : 3; - const maxRate = Math.max(...this.maxRateOptions.map(option => option.rate)); - const baseRate = this.estimate.txSummary.effectiveFee / this.estimate.txSummary.effectiveVsize; - let baseHeight = Math.max(this.height - (numBars * 30), this.height * (baseRate / maxRate)); - const bars: GraphBar[] = []; - let lastHeight = 0; - if (hasNextBlockRate) { - lastHeight = Math.max(lastHeight + 30, (this.height * ((this.estimate.targetFeeRate - baseRate) / maxRate))); - bars.push({ - rate: this.estimate.targetFeeRate, - height: lastHeight, - class: 'target', - label: $localize`:@@bdf0e930eb22431140a2eaeacd809cc5f8ebd38c:Next Block`.toLowerCase(), - fee: this.estimate.nextBlockFee - this.estimate.txSummary.effectiveFee - }); - } - this.maxRateOptions.forEach((option, index) => { - lastHeight = Math.max(lastHeight + 30, (this.height * ((option.rate - baseRate) / maxRate))); - bars.push({ - rate: option.rate, - height: lastHeight, - class: 'max', - label: this.showEstimate ? $localize`maximum` : $localize`:@@b484583f0ce10f3341ab36750d05271d9d22c9a1:Accelerated`.toLowerCase(), - active: option.index === this.maxRateIndex, - rateIndex: option.index, - fee: option.fee, - }); - }); - - bars.reverse(); - - baseHeight = this.height - lastHeight; - - for (const bar of bars) { - bar.style = this.getStyle(bar.height, baseHeight); - } - - bars.push({ - rate: baseRate, - style: this.getStyle(baseHeight, 0), - height: baseHeight, - class: 'tx', - label: '', - fee: this.estimate.txSummary.effectiveFee, - }); - - this.bars = bars; - this.cd.detectChanges(); - } - - getStyle(height: number, base: number): Record { - return { - height: `${height}px`, - bottom: base ? `${base}px` : '0', - }; - } - - onClick(event, bar): void { - if (bar.rateIndex != null) { - this.setUserBid.emit({ fee: bar.fee, index: bar.rateIndex }); - } - } - - @HostListener('pointermove', ['$event']) - onPointerMove(event) { - this.tooltipPosition = { x: event.offsetX, y: event.offsetY }; - } - - startResizeFallbackLoop(): void { - if (this.stopResizeLoop) { - return; - } - requestAnimationFrame(() => { - this.height = this.container?.nativeElement?.clientHeight || 0; - this.initGraph(); - this.startResizeFallbackLoop(); - }); - } - - ngOnDestroy(): void { - this.stopResizeLoop = true; - this.observer.disconnect(); - } -} diff --git a/frontend/src/app/components/acceleration/accelerator-dashboard/accelerator-dashboard.component.html b/frontend/src/app/components/acceleration/accelerator-dashboard/accelerator-dashboard.component.html index b45b185268a..0c546bf72d3 100644 --- a/frontend/src/app/components/acceleration/accelerator-dashboard/accelerator-dashboard.component.html +++ b/frontend/src/app/components/acceleration/accelerator-dashboard/accelerator-dashboard.component.html @@ -64,7 +64,7 @@
-
Mempool Goggles™ : Accelerations
+
Accelerations
 
diff --git a/frontend/src/app/components/acceleration/accelerator-dashboard/accelerator-dashboard.component.ts b/frontend/src/app/components/acceleration/accelerator-dashboard/accelerator-dashboard.component.ts index f45b4c91fb5..d42f07b33dc 100644 --- a/frontend/src/app/components/acceleration/accelerator-dashboard/accelerator-dashboard.component.ts +++ b/frontend/src/app/components/acceleration/accelerator-dashboard/accelerator-dashboard.component.ts @@ -55,7 +55,6 @@ export class AcceleratorDashboardComponent implements OnInit, OnDestroy { ) { this.webGlEnabled = this.stateService.isBrowser && detectWebGL(); this.seoService.setTitle($localize`:@@6b867dc61c6a92f3229f1950f9f2d414790cce95:Accelerator Dashboard`); - this.ogService.setManualOgImage('accelerator.jpg'); } ngOnInit(): void { @@ -154,7 +153,7 @@ export class AcceleratorDashboardComponent implements OnInit, OnDestroy { } else { const rate = tx.fee / tx.vsize; // color by simple single-tx fee rate const feeLevelIndex = feeLevels.findIndex((feeLvl) => Math.max(0, rate) < feeLvl) - 1; - return this.theme.theme === 'contrast' || this.theme.theme === 'bukele' ? contrastColors[feeLevelIndex] || contrastColors[contrastColors.length - 1] : normalColors[feeLevelIndex] || normalColors[normalColors.length - 1]; + return this.theme.theme === 'contrast' ? contrastColors[feeLevelIndex] || contrastColors[contrastColors.length - 1] : normalColors[feeLevelIndex] || normalColors[normalColors.length - 1]; } } diff --git a/frontend/src/app/components/address/address.component.html b/frontend/src/app/components/address/address.component.html index 4f8a93a6a14..cfdd80dbfc7 100644 --- a/frontend/src/app/components/address/address.component.html +++ b/frontend/src/app/components/address/address.component.html @@ -144,6 +144,8 @@

+ +
diff --git a/frontend/src/app/components/block-filters/block-filters.component.html b/frontend/src/app/components/block-filters/block-filters.component.html index 69f072b7107..b63e91223e0 100644 --- a/frontend/src/app/components/block-filters/block-filters.component.html +++ b/frontend/src/app/components/block-filters/block-filters.component.html @@ -1,10 +1,10 @@
- +
@@ -15,27 +15,27 @@
-
Match
+
Match
-
Tint
+
Tint
diff --git a/frontend/src/app/components/block-filters/block-filters.component.ts b/frontend/src/app/components/block-filters/block-filters.component.ts index d71e01ab94a..69878bf3e45 100644 --- a/frontend/src/app/components/block-filters/block-filters.component.ts +++ b/frontend/src/app/components/block-filters/block-filters.component.ts @@ -32,7 +32,7 @@ export class BlockFiltersComponent implements OnInit, OnChanges, OnDestroy { ) {} ngOnInit(): void { - this.filterSubscription = this.stateService.activeGoggles$.subscribe((active: ActiveFilter) => { + this.filterSubscription = this.stateService.activeLens$.subscribe((active: ActiveFilter) => { this.filterMode = active.mode; this.gradientMode = active.gradient; for (const key of Object.keys(this.filterFlags)) { @@ -61,13 +61,13 @@ export class BlockFiltersComponent implements OnInit, OnChanges, OnDestroy { setFilterMode(mode): void { this.filterMode = mode; this.onFilterChanged.emit({ mode: this.filterMode, filters: this.activeFilters, gradient: this.gradientMode }); - this.stateService.activeGoggles$.next({ mode: this.filterMode, filters: [...this.activeFilters], gradient: this.gradientMode }); + this.stateService.activeLens$.next({ mode: this.filterMode, filters: [...this.activeFilters], gradient: this.gradientMode }); } setGradientMode(mode): void { this.gradientMode = mode; this.onFilterChanged.emit({ mode: this.filterMode, filters: this.activeFilters, gradient: this.gradientMode }); - this.stateService.activeGoggles$.next({ mode: this.filterMode, filters: [...this.activeFilters], gradient: this.gradientMode }); + this.stateService.activeLens$.next({ mode: this.filterMode, filters: [...this.activeFilters], gradient: this.gradientMode }); } toggleFilter(key): void { @@ -91,7 +91,7 @@ export class BlockFiltersComponent implements OnInit, OnChanges, OnDestroy { } const booleanFlags = this.getBooleanFlags(); this.onFilterChanged.emit({ mode: this.filterMode, filters: this.activeFilters, gradient: this.gradientMode }); - this.stateService.activeGoggles$.next({ mode: this.filterMode, filters: [...this.activeFilters], gradient: this.gradientMode }); + this.stateService.activeLens$.next({ mode: this.filterMode, filters: [...this.activeFilters], gradient: this.gradientMode }); } getBooleanFlags(): bigint | null { diff --git a/frontend/src/app/components/block-overview-graph/block-overview-graph.component.ts b/frontend/src/app/components/block-overview-graph/block-overview-graph.component.ts index 58f3c809684..947754b645a 100644 --- a/frontend/src/app/components/block-overview-graph/block-overview-graph.component.ts +++ b/frontend/src/app/components/block-overview-graph/block-overview-graph.component.ts @@ -161,10 +161,10 @@ export class BlockOverviewGraphComponent implements AfterViewInit, OnDestroy, On } } - setFilterFlags(goggle?: ActiveFilter): void { - this.filterMode = goggle?.mode || this.filterMode; - this.gradientMode = goggle?.gradient || this.gradientMode; - this.activeFilterFlags = goggle?.filters ? toFlags(goggle.filters) : this.filterFlags; + setFilterFlags(lens?: ActiveFilter): void { + this.filterMode = lens?.mode || this.filterMode; + this.gradientMode = lens?.gradient || this.gradientMode; + this.activeFilterFlags = lens?.filters ? toFlags(lens.filters) : this.filterFlags; if (this.scene) { if (this.activeFilterFlags != null && this.filtersAvailable) { this.scene.setColorFunction(this.getFilterColorFunction(this.activeFilterFlags, this.gradientMode)); @@ -675,13 +675,13 @@ export class BlockOverviewGraphComponent implements AfterViewInit, OnDestroy, On break; } if (matches) { - if (this.loadedTheme !== 'contrast' && this.loadedTheme !== 'bukele') { + if (this.loadedTheme !== 'contrast') { return (gradient === 'age') ? ageColorFunction(tx, defaultColors.fee, defaultAuditColors, this.relativeTime || (Date.now() / 1000)) : defaultColorFunction(tx, defaultColors.fee, defaultAuditColors, this.relativeTime || (Date.now() / 1000)); } else { return (gradient === 'age') ? ageColorFunction(tx, contrastColors.fee, contrastAuditColors, this.relativeTime || (Date.now() / 1000)) : contrastColorFunction(tx, contrastColors.fee, contrastAuditColors, this.relativeTime || (Date.now() / 1000)); } } else { - if (this.loadedTheme !== 'contrast' && this.loadedTheme !== 'bukele') { + if (this.loadedTheme !== 'contrast') { return (gradient === 'age') ? { r: 1, g: 1, b: 1, a: 0.05 } : defaultColorFunction( tx, defaultColors.unmatchedfee, diff --git a/frontend/src/app/components/block-overview-graph/block-scene.ts b/frontend/src/app/components/block-overview-graph/block-scene.ts index 575f45bd623..fd049ee1289 100644 --- a/frontend/src/app/components/block-overview-graph/block-scene.ts +++ b/frontend/src/app/components/block-overview-graph/block-scene.ts @@ -69,7 +69,7 @@ export default class BlockScene { } setColorFunction(colorFunction: ((tx: TxView) => Color) | null): void { - this.theme.theme === 'contrast' || this.theme.theme === 'bukele' ? this.getColor = colorFunction || contrastColorFunction : this.getColor = colorFunction || defaultColorFunction; + this.theme.theme === 'contrast' ? this.getColor = colorFunction || contrastColorFunction : this.getColor = colorFunction || defaultColorFunction; this.updateAllColors(); } @@ -249,7 +249,7 @@ export default class BlockScene { this.flip = flip; this.vertexArray = vertexArray; this.highlightingEnabled = highlighting; - theme.theme === 'contrast' || theme.theme === 'bukele' ? this.getColor = colorFunction || contrastColorFunction : this.getColor = colorFunction || defaultColorFunction; + theme.theme === 'contrast' ? this.getColor = colorFunction || contrastColorFunction : this.getColor = colorFunction || defaultColorFunction; this.theme = theme; this.scene = { diff --git a/frontend/src/app/components/block-overview-graph/utils.ts b/frontend/src/app/components/block-overview-graph/utils.ts index 05fb9931fde..be4029a3211 100644 --- a/frontend/src/app/components/block-overview-graph/utils.ts +++ b/frontend/src/app/components/block-overview-graph/utils.ts @@ -206,7 +206,7 @@ export function ageColorFunction( return auditColors.accelerated; } - const color = theme !== 'contrast' && theme !== 'bukele' ? defaultColorFunction(tx, colors, auditColors, relativeTime) : contrastColorFunction(tx, colors, auditColors, relativeTime); + const color = theme !== 'contrast' ? defaultColorFunction(tx, colors, auditColors, relativeTime) : contrastColorFunction(tx, colors, auditColors, relativeTime); const ageLevel = (!tx.time ? 0 : (0.8 * Math.tanh((1 / 15) * Math.log2((Math.max(1, 0.6 * ((relativeTime - tx.time) - 60))))))); return { diff --git a/frontend/src/app/components/block/block.component.html b/frontend/src/app/components/block/block.component.html index 0c78081edb9..c172022dd1c 100644 --- a/frontend/src/app/components/block/block.component.html +++ b/frontend/src/app/components/block/block.component.html @@ -402,6 +402,8 @@

@defer (on viewport) { @if (!block?.stale) { + + } } @placeholder { diff --git a/frontend/src/app/components/block/block.module.ts b/frontend/src/app/components/block/block.module.ts index 206492e3f49..2bd45a6ca21 100644 --- a/frontend/src/app/components/block/block.module.ts +++ b/frontend/src/app/components/block/block.module.ts @@ -4,6 +4,7 @@ import { Routes, RouterModule } from '@angular/router'; import { BlockComponent } from '@components/block/block.component'; import { BlockTransactionsComponent } from '@components/block/block-transactions.component'; import { SharedModule } from '@app/shared/shared.module'; +import { BlockProtocolsComponent } from '@app/universe/block-protocols/block-protocols.component'; const routes: Routes = [ { @@ -30,6 +31,7 @@ export class BlockRoutingModule { } CommonModule, BlockRoutingModule, SharedModule, + BlockProtocolsComponent, ], declarations: [ BlockComponent, diff --git a/frontend/src/app/components/blockchain/blockchain.component.html b/frontend/src/app/components/blockchain/blockchain.component.html index af3bf52b19a..13ff9b702e7 100644 --- a/frontend/src/app/components/blockchain/blockchain.component.html +++ b/frontend/src/app/components/blockchain/blockchain.component.html @@ -10,8 +10,12 @@

- - + +
diff --git a/frontend/src/app/components/blocks-list/blocks-list.component.ts b/frontend/src/app/components/blocks-list/blocks-list.component.ts index be9660081f8..46fb80ae64d 100644 --- a/frontend/src/app/components/blocks-list/blocks-list.component.ts +++ b/frontend/src/app/components/blocks-list/blocks-list.component.ts @@ -69,7 +69,6 @@ export class BlocksList implements OnInit { this.websocketService.want(['blocks']); this.seoService.setTitle($localize`:@@8a7b4bd44c0ac71b2e72de0398b303257f7d2f54:Blocks`); - this.ogService.setManualOgImage('recent-blocks.jpg'); if( this.stateService.network==='liquid'||this.stateService.network==='liquidtestnet' ) { this.seoService.setDescription($localize`:@@meta.description.liquid.blocks:See the most recent Liquid${seoDescriptionNetwork(this.stateService.network)} blocks along with basic stats such as block height, block size, and more.`); } else { diff --git a/frontend/src/app/components/custom-dashboard/custom-dashboard.component.html b/frontend/src/app/components/custom-dashboard/custom-dashboard.component.html index e8ce0f6db76..984393f1609 100644 --- a/frontend/src/app/components/custom-dashboard/custom-dashboard.component.html +++ b/frontend/src/app/components/custom-dashboard/custom-dashboard.component.html @@ -18,18 +18,18 @@
} - @case ('goggles') { + @case ('lens') {
-
Universe Lens : {{ goggleCycle[goggleIndex].name }}
+
Universe Lens : {{ lensCycle[lensIndex].name }}
 
-
@@ -37,9 +37,9 @@
Universe Lens : {{ goggleCycle[gogg
diff --git a/frontend/src/app/components/custom-dashboard/custom-dashboard.component.scss b/frontend/src/app/components/custom-dashboard/custom-dashboard.component.scss index 4a9ffe94aa0..c0337610f7e 100644 --- a/frontend/src/app/components/custom-dashboard/custom-dashboard.component.scss +++ b/frontend/src/app/components/custom-dashboard/custom-dashboard.component.scss @@ -396,7 +396,7 @@ } } -.goggle-badge { +.lens-badge { margin: 6px 5px 8px; background: none; border: solid 2px var(--primary); diff --git a/frontend/src/app/components/custom-dashboard/custom-dashboard.component.ts b/frontend/src/app/components/custom-dashboard/custom-dashboard.component.ts index 587763a5975..ea10939e40e 100644 --- a/frontend/src/app/components/custom-dashboard/custom-dashboard.component.ts +++ b/frontend/src/app/components/custom-dashboard/custom-dashboard.component.ts @@ -69,17 +69,17 @@ export class CustomDashboardComponent implements OnInit, OnDestroy, AfterViewIni walletSummary$: Observable; address: Address; - goggleResolution = 82; - goggleCycle: { index: number, name: string, mode: FilterMode, filters: string[], gradient: GradientMode }[] = [ + lensResolution = 82; + lensCycle: { index: number, name: string, mode: FilterMode, filters: string[], gradient: GradientMode }[] = [ { index: 0, name: $localize`:@@dfc3c34e182ea73c5d784ff7c8135f087992dac1:All`, mode: 'and', filters: [], gradient: 'age' }, { index: 1, name: $localize`Consolidation`, mode: 'and', filters: ['consolidation'], gradient: 'fee' }, { index: 2, name: $localize`Coinjoin`, mode: 'and', filters: ['coinjoin'], gradient: 'fee' }, { index: 3, name: $localize`Data`, mode: 'or', filters: ['inscription', 'fake_pubkey', 'fake_scripthash', 'op_return'], gradient: 'fee' }, ]; - goggleFlags = 0n; - goggleMode: FilterMode = 'and'; + lensFlags = 0n; + lensMode: FilterMode = 'and'; gradientMode: GradientMode = 'age'; - goggleIndex = 0; + lensIndex = 0; private destroy$ = new Subject(); @@ -130,30 +130,30 @@ export class CustomDashboardComponent implements OnInit, OnDestroy, AfterViewIni map((indicators) => indicators.mempool !== undefined ? indicators.mempool : 100) ); - this.filterSubscription = this.stateService.activeGoggles$.subscribe((active: ActiveFilter) => { + this.filterSubscription = this.stateService.activeLens$.subscribe((active: ActiveFilter) => { const activeFilters = active.filters.sort().join(','); - for (const goggle of this.goggleCycle) { - if (goggle.mode === active.mode) { - const goggleFilters = goggle.filters.sort().join(','); - if (goggleFilters === activeFilters) { - this.goggleIndex = goggle.index; - this.goggleFlags = toFlags(goggle.filters); - this.goggleMode = goggle.mode; + for (const lens of this.lensCycle) { + if (lens.mode === active.mode) { + const lensFilters = lens.filters.sort().join(','); + if (lensFilters === activeFilters) { + this.lensIndex = lens.index; + this.lensFlags = toFlags(lens.filters); + this.lensMode = lens.mode; this.gradientMode = active.gradient; return; } } } - this.goggleCycle.push({ - index: this.goggleCycle.length, + this.lensCycle.push({ + index: this.lensCycle.length, name: 'Custom', mode: active.mode, filters: active.filters, gradient: active.gradient, }); - this.goggleIndex = this.goggleCycle.length - 1; - this.goggleFlags = toFlags(active.filters); - this.goggleMode = active.mode; + this.lensIndex = this.lensCycle.length - 1; + this.lensFlags = toFlags(active.filters); + this.lensMode = active.mode; }); this.mempoolInfoData$ = combineLatest([ @@ -288,8 +288,8 @@ export class CustomDashboardComponent implements OnInit, OnDestroy, AfterViewIni } setFilter(index): void { - const selected = this.goggleCycle[index]; - this.stateService.activeGoggles$.next(selected); + const selected = this.lensCycle[index]; + this.stateService.activeLens$.next(selected); } startAddressSubscription(): void { @@ -438,15 +438,15 @@ export class CustomDashboardComponent implements OnInit, OnDestroy, AfterViewIni onResize(): void { if (window.innerWidth >= 992) { this.incomingGraphHeight = 300; - this.goggleResolution = 82; + this.lensResolution = 82; this.graphHeight = 400; } else if (window.innerWidth >= 768) { this.incomingGraphHeight = 215; - this.goggleResolution = 80; + this.lensResolution = 80; this.graphHeight = 310; } else { this.incomingGraphHeight = 180; - this.goggleResolution = 86; + this.lensResolution = 86; this.graphHeight = 310; } this.isMobile = window.innerWidth <= 767.98; diff --git a/frontend/src/app/components/master-page/master-page.component.html b/frontend/src/app/components/master-page/master-page.component.html index 2f580f8ce21..5afc6cb916f 100644 --- a/frontend/src/app/components/master-page/master-page.component.html +++ b/frontend/src/app/components/master-page/master-page.component.html @@ -74,42 +74,62 @@

See how results of the block audit are used to devise the block health score below.

-

Because of this feature's resource usage and availability requirements, it is only supported on official mempool.space instances.

+

This feature has high resource and availability requirements and may not be enabled on every instance.

-

Block health is a measure of how many transactions appear to be intentionally excluded from a block—a block without any transactions that appear intentionally excluded will have 100% health, while a block with 1 or more transactions that appear intentionally excluded will have sub-100% health.

+

Block health is a measure of how many transactions appear to be intentionally excluded from a block: a block without any transactions that appear intentionally excluded will have 100% health, while a block with 1 or more transactions that appear intentionally excluded will have sub-100% health.

How is it calculated? Let sexpected be the set of all transactions in Mempool's expected block and let sactual be the set of all transactions in the actual block. Then let n be the number of all transactions in both sexpected and sactual.

Furthermore, let r be the number of transactions Mempool deduces were intentionally excluded from sactual.

Block health is calculated as n / ( n + r ).

@@ -374,7 +358,7 @@

extreme example).

See more context in our FAQ on block audits.

-

Because of this feature's resource usage and availability requirements, it is only supported on official mempool.space instances.

+

This feature has high resource and availability requirements and may not be enabled on every instance.

@@ -477,7 +461,7 @@

Then, during block template construction, Bitcoin Core selects transactions in descending order of fee rate measured in satoshis per adjusted vsize

-

On mempool.space, effective fee rates for unconfirmed transactions are also measured in terms of satoshis per adjusted vsize, after accounting for CPFP relationships and other dependencies.

+

Effective fee rates for unconfirmed transactions are measured in terms of satoshis per adjusted vsize, after accounting for CPFP relationships and other dependencies.

@@ -497,7 +481,7 @@

-

You can manually install Mempool on your own server, but this requires advanced sysadmin skills since you will be manually configuring everything. You could also use our Docker images.

In any case, we only provide support for manual deployments to enterprise sponsors.

+

You can install this explorer on your own server. It expects advanced sysadmin skills, since you configure every component yourself. The repository ships Docker images and deployment notes.

For casual users, we strongly suggest installing Mempool using one of the 1-click install methods.

@@ -506,5 +490,5 @@

-

If you're getting errors when doing address lookups, it's probably because of your Electrum server backend.

Mempool uses an Electrum server to do address lookups. There are several implementations of the Electrum server protocol, and Mempool can use any of them, but the implementation you use affects performance:

  1. romanz/electrs. This is a common choice for its low resource requirements, and most full-node distros use it. But while this implementation works great for basic queries, it will struggle with heavier ones (e.g. looking up addresses with many transactions)—especially when running on low-power hardware like a Raspberry Pi.
  2. Fulcrum. Fulcrum requires more resources than romanz/electrs but it can still run on a Raspberry Pi, and it handles heavy queries much more efficiently. If you're having issues with romanz/electrs, Fulcrum is worth a try.
  3. mempool/electrs. If you have stronger hardware, you could consider running mempool/electrs, the backend that powers mempool.space. It's a fork of Blockstream's Esplora, which is in turn a fork of romanz/electrs, intended for maximum performance and larger-scale deployments.
+

If you're getting errors when doing address lookups, it's probably because of your Electrum server backend.

Mempool uses an Electrum server to do address lookups. There are several implementations of the Electrum server protocol, and Mempool can use any of them, but the implementation you use affects performance:

  1. romanz/electrs. This is a common choice for its low resource requirements, and most full-node distros use it. But while this implementation works great for basic queries, it will struggle with heavier ones (e.g. looking up addresses with many transactions), especially on low-power hardware like a Raspberry Pi.
  2. Fulcrum. Fulcrum requires more resources than romanz/electrs but it can still run on a Raspberry Pi, and it handles heavy queries much more efficiently. If you're having issues with romanz/electrs, Fulcrum is worth a try.
  3. An Esplora-derived electrs fork. With stronger hardware these forks of Blockstream's Esplora, itself a fork of romanz/electrs, target maximum performance for larger deployments. This explorer runs Fulcrum.
diff --git a/frontend/src/app/docs/code-template/code-template.component.ts b/frontend/src/app/docs/code-template/code-template.component.ts index bfbfc115a0b..d0d2d81e587 100644 --- a/frontend/src/app/docs/code-template/code-template.component.ts +++ b/frontend/src/app/docs/code-template/code-template.component.ts @@ -164,7 +164,7 @@ init();`; return codeText; } - let importText = ``; + let importText = ``; if (this.env.BASE_MODULE === 'liquid') { importText = ``; } @@ -260,7 +260,7 @@ yarn add @mempool/liquid.js`; } wrapPythonTemplate(code: any) { - return ( ( this.network === 'testnet' || this.network === 'testnet4' || this.network === 'signet' ) ? ( code.codeTemplate.python.replace( 'wss://mempool.space/api/v1/ws', 'wss://mempool.space/' + this.network + '/api/v1/ws' ) ) : code.codeTemplate.python ); + return ( ( this.network === 'testnet' || this.network === 'testnet4' || this.network === 'signet' ) ? ( code.codeTemplate.python.replace( '/api/v1/ws', '/' + this.network + '/api/v1/ws' ) ) : code.codeTemplate.python ); } replaceJSPlaceholder(text: string, code: any) { diff --git a/frontend/src/app/docs/docs/docs.component.ts b/frontend/src/app/docs/docs/docs.component.ts index d60252863b4..c7a720e1c7c 100644 --- a/frontend/src/app/docs/docs/docs.component.ts +++ b/frontend/src/app/docs/docs/docs.component.ts @@ -45,15 +45,14 @@ export class DocsComponent implements OnInit { if (url[0].path === 'faq' ) { this.activeTab = 0; this.seoService.setTitle($localize`:@@meta.title.docs.faq:FAQ`); - this.seoService.setDescription($localize`:@@meta.description.docs.faq:Get answers to common questions like: What is a mempool? Why isn't my transaction confirming? How can I run my own instance of The Mempool Open Source Project? And more.`); - this.ogService.setManualOgImage('faq.jpg'); + this.seoService.setDescription($localize`:@@meta.description.docs.faq:Get answers to common questions like: What is a mempool? Why isn't my transaction confirming? How can I run my own instance of this explorer? And more.`); } else if( url[1].path === 'rest' ) { this.activeTab = 1; this.seoService.setTitle($localize`:@@meta.title.docs.rest:REST API`); if (this.stateService.network === 'liquid' || this.stateService.network === 'liquidtestnet' ) { this.seoService.setDescription($localize`:@@meta.description.docs.rest-liquid:Documentation for the liquid.network REST API service: get info on addresses, transactions, assets, blocks, and more.`); } else { - this.seoService.setDescription($localize`:@@meta.description.docs.rest-bitcoin:Documentation for the mempool.space REST API service: get info on addresses, transactions, blocks, fees, mining, the Lightning network, and more.`); + this.seoService.setDescription($localize`:@@meta.description.docs.rest-bitcoin:Documentation for the Universe Explorer REST API: get info on addresses, transactions, blocks, fees, mining, the Lightning network, and more.`); } } else if( url[1].path === 'websocket' ) { this.activeTab = 2; @@ -61,7 +60,7 @@ export class DocsComponent implements OnInit { if( this.stateService.network === 'liquid' || this.stateService.network === 'liquidtestnet' ) { this.seoService.setDescription($localize`:@@meta.description.docs.websocket-liquid:Documentation for the liquid.network WebSocket API service: get real-time info on blocks, mempools, transactions, addresses, and more.`); } else { - this.seoService.setDescription($localize`:@@meta.description.docs.websocket-bitcoin:Documentation for the mempool.space WebSocket API service: get real-time info on blocks, mempools, transactions, addresses, and more.`); + this.seoService.setDescription($localize`:@@meta.description.docs.websocket-bitcoin:Documentation for the Universe Explorer WebSocket API: get real-time info on blocks, mempools, transactions, addresses, and more.`); } } else { this.activeTab = 3; diff --git a/frontend/src/app/graphs/graphs.module.ts b/frontend/src/app/graphs/graphs.module.ts index 0fd4e69131a..f0419c6f11b 100644 --- a/frontend/src/app/graphs/graphs.module.ts +++ b/frontend/src/app/graphs/graphs.module.ts @@ -36,6 +36,8 @@ import { HashrateChartComponent } from '@components/hashrate-chart/hashrate-char import { HashrateChartPoolsComponent } from '@components/hashrates-chart-pools/hashrate-chart-pools.component'; import { BlockHealthGraphComponent } from '@components/block-health-graph/block-health-graph.component'; import { AddressComponent } from '@components/address/address.component'; +import { AddressAssetsComponent } from '@app/universe/address-assets/address-assets.component'; +import { ProtocolStripComponent } from '@app/universe/protocol-strip/protocol-strip.component'; import { WalletComponent } from '@components/wallet/wallet.component'; import { WalletPreviewComponent } from '@components/wallet/wallet-preview.component'; import { AddressGraphComponent } from '@components/address-graph/address-graph.component'; @@ -102,6 +104,8 @@ import { AsmStylerPipe } from '@app/shared/pipes/asm-styler/asm-styler.pipe'; CommonModule, SharedModule, GraphsRoutingModule, + AddressAssetsComponent, + ProtocolStripComponent, NgxEchartsModule.forRoot({ echarts: () => import('@app/graphs/echarts').then(m => m.echarts), }) diff --git a/frontend/src/app/interfaces/websocket.interface.ts b/frontend/src/app/interfaces/websocket.interface.ts index d22061259f7..8f77e3ddb43 100644 --- a/frontend/src/app/interfaces/websocket.interface.ts +++ b/frontend/src/app/interfaces/websocket.interface.ts @@ -124,6 +124,18 @@ export interface IBackendInfo { hostname?: string; gitCommit: string; version: string; + backend?: 'esplora' | 'electrum' | 'none'; + coreVersion?: string; + /** How far the node this explorer reads has actually got. Null until read. */ + chainSync?: IChainSyncState | null; +} + +export interface IChainSyncState { + blocks: number; + headers: number; + initialBlockDownload: boolean; + verificationProgress: number; + checkedAt: string; } export interface Recommendedfees { diff --git a/frontend/src/app/lightning/group/group-preview.component.html b/frontend/src/app/lightning/group/group-preview.component.html deleted file mode 100644 index d821e2752bc..00000000000 --- a/frontend/src/app/lightning/group/group-preview.component.html +++ /dev/null @@ -1,56 +0,0 @@ -
- - Lightning node group - -
-
- -
-
-

{{ group.name }}

-
-
-
-
-
{{ group.description }}
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - -
Nodes{{ nodes.nodes.length }}
Liquidity - - - {{ nodes.sumLiquidity | amountShortener: 1 }} - sats - -   -
Channels{{ nodes.sumChannels }}
Average size - -
-
-
- -
-
-
\ No newline at end of file diff --git a/frontend/src/app/lightning/group/group-preview.component.scss b/frontend/src/app/lightning/group/group-preview.component.scss deleted file mode 100644 index f31c33f471e..00000000000 --- a/frontend/src/app/lightning/group/group-preview.component.scss +++ /dev/null @@ -1,65 +0,0 @@ -.table { - font-size: 32px; - margin-top: 0px; -} - -.logo-wrapper { - position: relative; - width: 62px; - height: 62px; - margin-right: 1em; - - img { - position: absolute; - right: 0; - top: 0; - } -} - -.description-wrapper { - width: 100%; - margin: 16px 0 0; - padding: 20px 12px; - background: var(--stat-box-bg); - font-size: 32px; -} - -.description-text { - width: 100%; - line-height: 36px; - height: 72px; - max-height: 72px; - min-height: 72px; - overflow: hidden; - display: -webkit-box; - -webkit-box-orient: vertical; - -webkit-line-clamp: 2; - text-overflow: ellipsis; -} - -.map-col { - flex-grow: 0; - flex-shrink: 0; - width: 470px; - height: 272px; - min-width: 470px; - min-height: 272px; - max-height: 272px; - padding: 0; - background: var(--stat-box-bg); - overflow: hidden; - margin-top: 16px; -} - -.row { - margin-right: 0; -} - -.full-width-row { - padding-left: 15px; - flex-wrap: nowrap; -} - -::ng-deep .symbol { - font-size: 24px; -} \ No newline at end of file diff --git a/frontend/src/app/lightning/group/group-preview.component.ts b/frontend/src/app/lightning/group/group-preview.component.ts deleted file mode 100644 index 71b917a0903..00000000000 --- a/frontend/src/app/lightning/group/group-preview.component.ts +++ /dev/null @@ -1,130 +0,0 @@ -import { Component, OnInit } from '@angular/core'; -import { ActivatedRoute, ParamMap } from '@angular/router'; -import { map, switchMap, Observable, catchError, of } from 'rxjs'; -import { SeoService } from '@app/services/seo.service'; -import { OpenGraphService } from '@app/services/opengraph.service'; -import { GeolocationData } from '@app/shared/components/geolocation/geolocation.component'; -import { LightningApiService } from '@app/lightning/lightning-api.service'; - -interface NodeGroup { - name: string; - description: string; -} - -@Component({ - selector: 'app-group-preview', - templateUrl: './group-preview.component.html', - styleUrls: ['./group-preview.component.scss'], - standalone: false, -}) -export class GroupPreviewComponent implements OnInit { - nodes$: Observable; - group: NodeGroup = { name: '', description: '' }; - slug: string; - groupId: string; - - ogSession: number; - - constructor( - private lightningApiService: LightningApiService, - private activatedRoute: ActivatedRoute, - private seoService: SeoService, - private openGraphService: OpenGraphService, - ) { } - - ngOnInit(): void { - this.seoService.setTitle(`Mempool.Space Lightning Nodes`); - this.seoService.setDescription(`See all Lightning nodes run by mempool.space -- these are the nodes that provide the data on the mempool.space Lightning dashboard.`); - - this.nodes$ = this.activatedRoute.paramMap - .pipe( - switchMap((params: ParamMap) => { - this.slug = params.get('slug'); - this.ogSession = this.openGraphService.waitFor('ln-group-map-' + this.slug); - this.ogSession = this.openGraphService.waitFor('ln-group-data-' + this.slug); - - if (this.slug === 'the-mempool-open-source-project') { - this.groupId = 'mempool.space'; - this.group = { - name: 'The Mempool Open Source Project', - description: 'These are the Lightning nodes operated by The Mempool Open Source Project that provide data for the mempool.space website. Connect to us!', - }; - } else { - this.group = { - name: this.slug.replace(/-/gi, ' '), - description: '', - }; - this.seoService.logSoft404(); - this.openGraphService.fail({ event: 'ln-group-map-' + this.slug, sessionId: this.ogSession }); - this.openGraphService.fail({ event: 'ln-group-data-' + this.slug, sessionId: this.ogSession }); - return of(null); - } - - return this.lightningApiService.getNodeGroup$(this.groupId); - }), - map((nodes) => { - for (const node of nodes) { - const socketsObject = []; - for (const socket of node.sockets.split(',')) { - if (socket === '') { - continue; - } - let label = ''; - if (socket.match(/(?:[0-9]{1,3}\.){3}[0-9]{1,3}/)) { - label = 'IPv4'; - } else if (socket.indexOf('[') > -1) { - label = 'IPv6'; - } else if (socket.indexOf('onion') > -1) { - label = 'Tor'; - } - socketsObject.push({ - label: label, - socket: node.public_key + '@' + socket, - }); - } - // @ts-ignore - node.socketsObject = socketsObject; - - if (!node?.country && !node?.city && - !node?.subdivision) { - // @ts-ignore - node.geolocation = null; - } else { - // @ts-ignore - node.geolocation = { - country: node.country?.en, - city: node.city?.en, - subdivision: node.subdivision?.en, - iso: node.iso_code, - }; - } - } - const sumLiquidity = nodes.reduce((partialSum, a) => partialSum + parseInt(a.capacity, 10), 0); - const sumChannels = nodes.reduce((partialSum, a) => partialSum + a.opened_channel_count, 0); - - this.openGraphService.waitOver({ event: 'ln-group-data-' + this.slug, sessionId: this.ogSession }); - - return { - nodes: nodes, - sumLiquidity: sumLiquidity, - sumChannels: sumChannels, - }; - }), - catchError(() => { - this.seoService.logSoft404(); - this.openGraphService.fail({ event: 'ln-group-map-' + this.slug, sessionId: this.ogSession }); - this.openGraphService.fail({ event: 'ln-group-data-' + this.slug, sessionId: this.ogSession }); - return of({ - nodes: [], - sumLiquidity: 0, - sumChannels: 0, - }); - }) - ); - } - - onMapReady(): void { - this.openGraphService.waitOver({ event: 'ln-group-map-' + this.slug, sessionId: this.ogSession }); - } - -} diff --git a/frontend/src/app/lightning/group/group.component.html b/frontend/src/app/lightning/group/group.component.html deleted file mode 100644 index dc13f4ca2ec..00000000000 --- a/frontend/src/app/lightning/group/group.component.html +++ /dev/null @@ -1,129 +0,0 @@ -
-
Lightning node group
- -
-
- -
-

The Mempool Open Source Project

-
- -
-
-
- - - - - - - - - - - - - - - - - - - -
Description
These are the Lightning nodes operated by The Mempool Open Source Project that provide data for the mempool.space website. Connect to us! -
-
Nodes{{ nodes.nodes.length }}
Liquidity - - - {{ nodes.sumLiquidity | amountShortener: 1 }} - sats - -   - - -
Channels{{ nodes.sumChannels }}
-
-
-
- -
-
-
-
- -
- -
-
-
- - -
-
-
- -
- - - - - - - - - - - - - - - - - - - - - - - -
AliasConnectLocation
-
- {{ node.alias }} -
{{ node.opened_channel_count }} channel(s), - - {{ node.capacity | amountShortener: 1 }} sats - -
-
-
-
- - {{ node.socketsObject[selectedSocketIndex].label }} - - - - -
-
- -
- - - - - -
-
- -
diff --git a/frontend/src/app/lightning/group/group.component.scss b/frontend/src/app/lightning/group/group.component.scss deleted file mode 100644 index 61bc87ca8f0..00000000000 --- a/frontend/src/app/lightning/group/group.component.scss +++ /dev/null @@ -1,73 +0,0 @@ -.logo-container { - width: 50px; -} - -.header { - text-align: center; - display: flex; -} - -h1 { - margin-inline-start: 15px; -} - -.qr-wrapper { - background-color: var(--fg); - padding: 10px; - padding-bottom: 5px; - display: inline-block; - - - position: absolute; - bottom: 50px; - left: -175px; - z-index: 100; -} - -.dropdownLabel { - min-width: 50px; - display: inline-block; -} - -#inputGroupFileAddon04 { - position: relative; -} - -.toggle-holder { - display: flex; - width: 100%; - justify-content: flex-end; -} -@media (max-width: 767.98px) { - .text-truncate { - width: 120px; - } - .btn { - padding: 0.25rem 0.5rem; - font-size: 0.875rem; - line-height: 1.5; - border-radius: 0.2rem; - } -} - -.second-line { - font-size: 12px; -} - -.description-text { - white-space: break-spaces; -} - -.timestamp-first .input-group { - input { - margin-inline-end: .25rem; - } -} - -:host-context(.rtl-layout) { - .timestamp-first .input-group { - button { - margin-inline-end: .25rem; - } - } -} \ No newline at end of file diff --git a/frontend/src/app/lightning/group/group.component.ts b/frontend/src/app/lightning/group/group.component.ts deleted file mode 100644 index 34a3e9e2cfc..00000000000 --- a/frontend/src/app/lightning/group/group.component.ts +++ /dev/null @@ -1,111 +0,0 @@ -import { Component, OnInit } from '@angular/core'; -import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms'; -import { map, Observable, share } from 'rxjs'; -import { SeoService } from '@app/services/seo.service'; -import { GeolocationData } from '@app/shared/components/geolocation/geolocation.component'; -import { LightningApiService } from '@app/lightning/lightning-api.service'; - -@Component({ - selector: 'app-group', - templateUrl: './group.component.html', - styleUrls: ['./group.component.scss'], - standalone: false, -}) -export class GroupComponent implements OnInit { - nodes$: Observable; - isp: {name: string, id: number}; - - skeletonLines: number[] = []; - selectedSocketIndex = 0; - qrCodeVisible = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - socketToggleForm: UntypedFormGroup; - - constructor( - private lightningApiService: LightningApiService, - private seoService: SeoService, - private formBuilder: UntypedFormBuilder, - ) { - for (let i = 0; i < 20; ++i) { - this.skeletonLines.push(i); - } - } - - ngOnInit(): void { - this.socketToggleForm = this.formBuilder.group({ - socket: [this.selectedSocketIndex], - }); - - this.socketToggleForm.get('socket').valueChanges.subscribe((val) => { - this.selectedSocketIndex = val; - }); - - this.seoService.setTitle(`Mempool.space Lightning Nodes`); - this.seoService.setDescription(`See all Lightning nodes run by mempool.space -- these are the nodes that provide the data on the mempool.space Lightning dashboard.`); - - this.nodes$ = this.lightningApiService.getNodeGroup$('mempool.space') - .pipe( - map((nodes) => { - for (const node of nodes) { - const socketsObject = []; - for (const socket of node.sockets.split(',')) { - if (socket === '') { - continue; - } - let label = ''; - if (socket.match(/(?:[0-9]{1,3}\.){3}[0-9]{1,3}/)) { - label = 'IPv4'; - } else if (socket.indexOf('[') > -1) { - label = 'IPv6'; - } else if (socket.indexOf('onion') > -1) { - label = 'Tor'; - } - socketsObject.push({ - label: label, - socket: node.public_key + '@' + socket, - }); - } - // @ts-ignore - node.socketsObject = socketsObject; - - if (!node?.country && !node?.city && - !node?.subdivision) { - // @ts-ignore - node.geolocation = null; - } else { - // @ts-ignore - node.geolocation = { - country: node.country?.en, - city: node.city?.en, - subdivision: node.subdivision?.en, - iso: node.iso_code, - }; - } - } - - nodes.map((node) => { - node.channels = node.opened_channel_count; - return node; - }); - - const sumLiquidity = nodes.reduce((partialSum, a) => partialSum + parseInt(a.capacity, 10), 0); - const sumChannels = nodes.reduce((partialSum, a) => partialSum + a.opened_channel_count, 0); - - return { - nodes: nodes, - sumLiquidity: sumLiquidity, - sumChannels: sumChannels, - }; - }), - share() - ); - } - - trackByPublicKey(index: number, node: any): string { - return node.public_key; - } - - changeSocket(index: number) { - this.selectedSocketIndex = index; - } - -} diff --git a/frontend/src/app/lightning/lightning-dashboard/lightning-dashboard.component.ts b/frontend/src/app/lightning/lightning-dashboard/lightning-dashboard.component.ts index e243d26d2a5..0f5e6e87c28 100644 --- a/frontend/src/app/lightning/lightning-dashboard/lightning-dashboard.component.ts +++ b/frontend/src/app/lightning/lightning-dashboard/lightning-dashboard.component.ts @@ -33,7 +33,6 @@ export class LightningDashboardComponent implements OnInit, AfterViewInit { this.seoService.setTitle($localize`:@@142e923d3b04186ac6ba23387265d22a2fa404e0:Lightning Explorer`); this.seoService.setDescription($localize`:@@meta.description.lightning.dashboard:Get stats on the Lightning network (aggregate capacity, connectivity, etc), Lightning nodes (channels, liquidity, etc) and Lightning channels (status, fees, etc).`); - this.ogService.setManualOgImage('lightning.jpg'); this.nodesRanking$ = this.lightningApiService.getNodesRanking$().pipe(share()); this.statistics$ = this.lightningApiService.getLatestStatistics$().pipe(share()); diff --git a/frontend/src/app/lightning/lightning-previews.module.ts b/frontend/src/app/lightning/lightning-previews.module.ts index 5efac798fcb..2cfb2e67add 100644 --- a/frontend/src/app/lightning/lightning-previews.module.ts +++ b/frontend/src/app/lightning/lightning-previews.module.ts @@ -9,13 +9,11 @@ import { NodePreviewComponent } from '@app/lightning/node/node-preview.component import { LightningPreviewsRoutingModule } from '@app/lightning/lightning-previews.routing.module'; import { ChannelPreviewComponent } from '@app/lightning/channel/channel-preview.component'; import { NodesPerISPPreview } from '@app/lightning/nodes-per-isp/nodes-per-isp-preview.component'; -import { GroupPreviewComponent } from '@app/lightning/group/group-preview.component'; @NgModule({ declarations: [ NodePreviewComponent, ChannelPreviewComponent, NodesPerISPPreview, - GroupPreviewComponent, ], imports: [ CommonModule, diff --git a/frontend/src/app/lightning/lightning-previews.routing.module.ts b/frontend/src/app/lightning/lightning-previews.routing.module.ts index d899e559bac..43ed89f3d78 100644 --- a/frontend/src/app/lightning/lightning-previews.routing.module.ts +++ b/frontend/src/app/lightning/lightning-previews.routing.module.ts @@ -3,7 +3,6 @@ import { RouterModule, Routes } from '@angular/router'; import { NodePreviewComponent } from '@app/lightning/node/node-preview.component'; import { ChannelPreviewComponent } from '@app/lightning/channel/channel-preview.component'; import { NodesPerISPPreview } from '@app/lightning/nodes-per-isp/nodes-per-isp-preview.component'; -import { GroupPreviewComponent } from '@app/lightning/group/group-preview.component'; const routes: Routes = [ { @@ -18,10 +17,6 @@ const routes: Routes = [ path: 'nodes/isp/:isp', component: NodesPerISPPreview, }, - { - path: 'group/:slug', - component: GroupPreviewComponent, - }, { path: '**', redirectTo: '' diff --git a/frontend/src/app/lightning/lightning.module.ts b/frontend/src/app/lightning/lightning.module.ts index 405900e1964..8e1d72c2235 100644 --- a/frontend/src/app/lightning/lightning.module.ts +++ b/frontend/src/app/lightning/lightning.module.ts @@ -33,7 +33,6 @@ import { JusticeList } from '@app/lightning/justice-list/justice-list.component' import { OldestNodes } from '@app/lightning/nodes-ranking/oldest-nodes/oldest-nodes.component'; import { NodesRankingsDashboard } from '@app/lightning/nodes-rankings-dashboard/nodes-rankings-dashboard.component'; import { NodeChannels } from '@app/lightning/nodes-channels/node-channels.component'; -import { GroupComponent } from '@app/lightning/group/group.component'; @NgModule({ declarations: [ @@ -65,7 +64,6 @@ import { GroupComponent } from '@app/lightning/group/group.component'; OldestNodes, NodesRankingsDashboard, NodeChannels, - GroupComponent, ], imports: [ CommonModule, diff --git a/frontend/src/app/lightning/lightning.routing.module.ts b/frontend/src/app/lightning/lightning.routing.module.ts index c7f16730825..6c0f51cdf2b 100644 --- a/frontend/src/app/lightning/lightning.routing.module.ts +++ b/frontend/src/app/lightning/lightning.routing.module.ts @@ -8,7 +8,6 @@ import { NodesPerCountry } from '@app/lightning/nodes-per-country/nodes-per-coun import { NodesPerISP } from '@app/lightning/nodes-per-isp/nodes-per-isp.component'; import { NodesRanking } from '@app/lightning/nodes-ranking/nodes-ranking.component'; import { NodesRankingsDashboard } from '@app/lightning/nodes-rankings-dashboard/nodes-rankings-dashboard.component'; -import { GroupComponent } from '@app/lightning/group/group.component'; import { JusticeList } from '@app/lightning/justice-list/justice-list.component'; const routes: Routes = [ @@ -38,10 +37,6 @@ const routes: Routes = [ path: 'nodes/isp/:isp', component: NodesPerISP, }, - { - path: 'group/the-mempool-open-source-project', - component: GroupComponent, - }, { path: 'nodes/rankings', component: NodesRankingsDashboard, diff --git a/frontend/src/app/liquid/liquid-master-page.module.ts b/frontend/src/app/liquid/liquid-master-page.module.ts index 44d660508ce..d4f9c90d0fe 100644 --- a/frontend/src/app/liquid/liquid-master-page.module.ts +++ b/frontend/src/app/liquid/liquid-master-page.module.ts @@ -30,10 +30,6 @@ const routes: Routes = [ path: 'tx/push', component: PushTransactionComponent, }, - { - path: 'about', - loadChildren: () => import('@components/about/about.module').then(m => m.AboutModule), - }, { path: 'blocks/:page', component: BlocksList, @@ -50,10 +46,6 @@ const routes: Routes = [ path: 'privacy-policy', loadChildren: () => import('@components/privacy-policy/privacy-policy.module').then(m => m.PrivacyPolicyModule), }, - { - path: 'trademark-policy', - loadChildren: () => import('@components/trademark-policy/trademark-policy.module').then(m => m.TrademarkModule), - }, { path: 'tx', component: StartComponent, diff --git a/frontend/src/app/master-page.module.ts b/frontend/src/app/master-page.module.ts index 975b98f5f53..6ee7c7405fc 100644 --- a/frontend/src/app/master-page.module.ts +++ b/frontend/src/app/master-page.module.ts @@ -17,6 +17,7 @@ import { ServerStatusComponent } from '@components/server-health/server-status.c import { FaucetComponent } from '@components/faucet/faucet.component'; import { SimpleProofWidgetComponent } from '@components/simpleproof-widget/simpleproof-widget.component'; import { SimpleProofCuboWidgetComponent } from '@components/simpleproof-widget/simpleproof-cubo-widget.component'; +import { ChainSyncNoticeComponent } from '@app/universe/chain-sync-notice/chain-sync-notice.component'; const browserWindow = window || {}; // @ts-ignore @@ -114,6 +115,36 @@ const routes: Routes = [ loadComponent: () => import('@app/universe/source-page/source-page.component').then(m => m.SourcePageComponent), data: { networks: ['bitcoin', 'liquid'] }, }, + { + path: 'outpoint/:txid/:vout', + loadComponent: () => import('@app/universe/outpoint/outpoint.component').then(m => m.OutpointComponent), + data: { networkSpecific: true, networks: ['bitcoin'] }, + }, + { + path: 'pulse', + loadComponent: () => import('@app/universe/pulse/pulse.component').then(m => m.PulseComponent), + data: { networkSpecific: true, networks: ['bitcoin'] }, + }, + { + path: 'saved', + loadComponent: () => import('@app/universe/saved/saved.component').then(m => m.SavedComponent), + data: { networks: ['bitcoin'] }, + }, + { + path: 'inscription/:reference', + loadComponent: () => import('@app/universe/inscription/inscription.component').then(m => m.InscriptionComponent), + data: { networkSpecific: true, networks: ['bitcoin'] }, + }, + { + path: 'rune/:reference', + loadComponent: () => import('@app/universe/rune/rune.component').then(m => m.RuneComponent), + data: { networkSpecific: true, networks: ['bitcoin'] }, + }, + { + path: 'sat/:reference', + loadComponent: () => import('@app/universe/sat/sat.component').then(m => m.SatComponent), + data: { networkSpecific: true, networks: ['bitcoin'] }, + }, { path: 'tools/calculator', component: CalculatorComponent @@ -179,6 +210,7 @@ export class MasterPageRoutingModule { } CommonModule, MasterPageRoutingModule, SharedModule, + ChainSyncNoticeComponent, ], declarations: [ MasterPageComponent, diff --git a/frontend/src/app/services/enterprise.service.ts b/frontend/src/app/services/enterprise.service.ts index 350efa31660..b504de744e6 100644 --- a/frontend/src/app/services/enterprise.service.ts +++ b/frontend/src/app/services/enterprise.service.ts @@ -10,7 +10,11 @@ import { BehaviorSubject } from 'rxjs'; providedIn: 'root' }) export class EnterpriseService { - exclusiveHostName = '.mempool.space'; + /** + * Universe deployment: enterprise subdomains are an upstream hosted service + * and are not offered here, so no hostname is treated as one. + */ + exclusiveHostName = ''; subdomain: string | null = null; statsUrl: string; siteId: number; @@ -23,8 +27,9 @@ export class EnterpriseService { private stateService: StateService, private activatedRoute: ActivatedRoute, ) { - const subdomain = this.stateService.env.customize?.enterprise || this.document.location.hostname.indexOf(this.exclusiveHostName) > -1 - && this.document.location.hostname.split(this.exclusiveHostName)[0] || false; + const subdomain = this.stateService.env.customize?.enterprise + || (this.exclusiveHostName && this.document.location.hostname.indexOf(this.exclusiveHostName) > -1 + && this.document.location.hostname.split(this.exclusiveHostName)[0]) || false; if (subdomain && subdomain.match(/^[A-z0-9-_]+$/)) { this.subdomain = subdomain; this.fetchSubdomainInfo(); @@ -60,10 +65,11 @@ export class EnterpriseService { this.seoService.setEnterpriseTitle(info.title); this.info$.next(this.processEnterpriseInfo(info)); }, - (error) => { - if (error.status === 404) { - window.location.href = 'https://mempool.space' + window.location.pathname; - } + () => { + // Upstream redirects an unknown subdomain to its own hosted site. This + // deployment never sends a visitor to a third party, so an unknown + // subdomain simply renders the ordinary explorer. + this.info$.next(null); }); } } @@ -79,66 +85,16 @@ export class EnterpriseService { }; } + /** + * Universe deployment: no analytics. + * + * Upstream loads a hosted tracker on its own domains. This explorer ships no + * tracker at all, so the whole path is a deliberate no-op rather than a + * setting a deployment could switch back on by accident. `getMatomo` below + * therefore never resolves a tracker and every call through it is inert. + */ insertMatomo(siteId?: number): void { - let statsUrl = '//stats.mempool.space/'; - - if (!siteId) { - switch (this.document.location.hostname) { - case 'mempool.space': - statsUrl = '//stats.mempool.space/'; - siteId = 5; - break; - case 'mempool.ninja': - statsUrl = '//stats.mempool.space/'; - siteId = 4; - break; - case 'liquid.network': - siteId = 8; - statsUrl = '//stats.liquid.network/'; - break; - case 'liquid.place': - siteId = 10; - statsUrl = '//stats.liquid.network/'; - break; - default: - return; - } - } - - this.statsUrl = statsUrl; - this.siteId = siteId; - - // @ts-ignore - if (window._paq && window['Matomo']) { - window['Matomo'].addTracker(statsUrl+'m.php', siteId.toString()); - const matomo = this.getMatomo(); - matomo.setDocumentTitle(this.seoService.getTitle()); - matomo.setCustomUrl(this.getCustomUrl()); - matomo.disableCookies(); - matomo.trackPageView(); - matomo.enableLinkTracking(); - } else { - // @ts-ignore - const alreadyInitialized = !!window._paq; - // @ts-ignore - const _paq = window._paq = window._paq || []; - _paq.push(['setDocumentTitle', this.seoService.getTitle()]); - _paq.push(['setCustomUrl', this.getCustomUrl()]); - _paq.push(['disableCookies']); - _paq.push(['trackPageView']); - _paq.push(['enableLinkTracking']); - if (alreadyInitialized) { - _paq.push(['addTracker', statsUrl+'m.php', siteId.toString()]); - } else { - (function() { - _paq.push(['setTrackerUrl', statsUrl+'m.php']); - _paq.push(['setSiteId', siteId.toString()]); - const d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0]; - // @ts-ignore - g.type='text/javascript'; g.async=true; g.src=statsUrl+'m.js'; s.parentNode.insertBefore(g,s); - })(); - } - } + void siteId; } private getMatomo() { diff --git a/frontend/src/app/services/eta.service.ts b/frontend/src/app/services/eta.service.ts index d097a6a89ef..dc0165854ec 100644 --- a/frontend/src/app/services/eta.service.ts +++ b/frontend/src/app/services/eta.service.ts @@ -5,9 +5,27 @@ import { MempoolBlock } from '@interfaces/websocket.interface'; import { Transaction } from '@interfaces/electrs.interface'; import { MiningService, MiningStats } from '@app/services/mining.service'; import { getUnacceleratedFeeRate } from '@app/shared/transaction.utils'; -import { AccelerationEstimate } from '@components/accelerate-checkout/accelerate-checkout.component'; import { Observable, combineLatest, map, of, share, shareReplay, tap } from 'rxjs'; +/** + * The projection input this service needs. Upstream declares it on its hosted + * acceleration checkout component, which this deployment does not ship, so the + * shape lives here with the code that consumes it. + */ +export interface AccelerationEstimate { + txSummary: { txid: string, effectiveVsize: number, effectiveFee: number, ancestorCount: number }; + cost: number; + targetFeeRate: number; + nextBlockFee: number; + userBalance: number; + mempoolBaseFee: number; + vsizeFee: number; + pools: number[]; + availablePaymentMethods: Record; + unavailable?: boolean; + options: { fee: number }[]; +} + export interface ETA { now: number, // time at which calculation performed time: number, // absolute time expected (in unix epoch ms) diff --git a/frontend/src/app/services/seo.service.ts b/frontend/src/app/services/seo.service.ts index 9fe5bba16e0..30f56b09564 100644 --- a/frontend/src/app/services/seo.service.ts +++ b/frontend/src/app/services/seo.service.ts @@ -11,7 +11,8 @@ export class SeoService { network = ''; baseTitle = 'Universe Explorer'; baseDescription = 'Universe Explorer is the live protocol-aware Bitcoin explorer for the Bitcoin Universe ecosystem.'; - baseDomain = 'mempool.space'; + // Overwritten below from the canonical link in index.html; this is only the fallback. + baseDomain = 'explorer.bitcoinuniverse.io'; canonicalLink: HTMLLinkElement = document.getElementById('canonical') as HTMLLinkElement; diff --git a/frontend/src/app/services/services-api.service.ts b/frontend/src/app/services/services-api.service.ts index c354c32d390..209ca89dba6 100644 --- a/frontend/src/app/services/services-api.service.ts +++ b/frontend/src/app/services/services-api.service.ts @@ -229,7 +229,7 @@ export class ServicesApiServices { } getSimpleProofs$(key: string): Observable> { - // Need to use relative path here to avoid CORS errors, since this won't be used from mempool.space website + // Relative path avoids CORS errors: this is only used from this origin const pathname = new URL(this.stateService.env.SERVICES_API + '/sp/verified').pathname; return this.httpClient.get>(`${pathname}/${key}`); } diff --git a/frontend/src/app/services/state.service.ts b/frontend/src/app/services/state.service.ts index 592825fdcbd..bb8f97c4dda 100644 --- a/frontend/src/app/services/state.service.ts +++ b/frontend/src/app/services/state.service.ts @@ -113,8 +113,11 @@ const defaultEnv: Env = { 'MEMPOOL_BLOCKS_AMOUNT': 8, 'GIT_COMMIT_HASH': '', 'PACKAGE_JSON_VERSION': '', - 'MEMPOOL_WEBSITE_URL': 'https://mempool.space', - 'LIQUID_WEBSITE_URL': 'https://liquid.network', + // Cross-network links default to this deployment's own origin. Upstream + // points these at its hosted sites; sending a visitor to a third party is + // never the default here. + 'MEMPOOL_WEBSITE_URL': 'https://explorer.bitcoinuniverse.io', + 'LIQUID_WEBSITE_URL': 'https://explorer.bitcoinuniverse.io', 'MINING_DASHBOARD': true, 'LIGHTNING': false, 'AUDIT': false, @@ -134,7 +137,9 @@ const defaultEnv: Env = { 'PUBLIC_ACCELERATIONS': false, 'ADDITIONAL_CURRENCIES': false, 'STRATUM_ENABLED': false, - 'SERVICES_API': 'https://mempool.space/api/v1/services', + // The hosted services API is an upstream product. It is unset here, so the + // account and acceleration calls that use it never leave this origin. + 'SERVICES_API': '', 'PROD_DOMAINS': [], }; @@ -221,7 +226,7 @@ export class StateService { searchFocus$: Subject = new Subject(); menuOpen$: BehaviorSubject = new BehaviorSubject(false); - activeGoggles$: BehaviorSubject = new BehaviorSubject({ mode: 'and', filters: [], gradient: 'age' }); + activeLens$: BehaviorSubject = new BehaviorSubject({ mode: 'and', filters: [], gradient: 'age' }); constructor( @Inject(PLATFORM_ID) private platformId: any, diff --git a/frontend/src/app/services/storage.service.ts b/frontend/src/app/services/storage.service.ts index 5a69d220b20..1c581211063 100644 --- a/frontend/src/app/services/storage.service.ts +++ b/frontend/src/app/services/storage.service.ts @@ -14,7 +14,7 @@ export class StorageService { const graphWindowPreference: string = this.getValue(key); const fragment = window.location.hash.replace('#', ''); - if (graphWindowPreference === null) { // First visit to mempool.space + if (graphWindowPreference === null) { // First visit to the explorer if (window.location.pathname.includes('graphs') && key === 'graphWindowPreference' || window.location.pathname.includes('pools') && key === 'miningWindowPreference' ) { diff --git a/frontend/src/app/services/theme.service.ts b/frontend/src/app/services/theme.service.ts index 0f184e9d23e..5c1fb9e4473 100644 --- a/frontend/src/app/services/theme.service.ts +++ b/frontend/src/app/services/theme.service.ts @@ -8,6 +8,9 @@ import { StateService } from '@app/services/state.service'; providedIn: 'root' }) export class ThemeService { + /** Themes offered in the interface. 'default' is the light theme. */ + static readonly PUBLIC_THEMES = ['default', 'dark', 'contrast']; + style: HTMLLinkElement | null = null; theme: string = 'default'; themeState$: BehaviorSubject<{ theme: string; loading: boolean; }>; @@ -19,8 +22,9 @@ export class ThemeService { private stateService: StateService, ) { let theme = this.stateService.env.customize?.theme || this.storageService.getValue('theme-preference') || 'default'; - // theme preference must be a valid known public theme - if (!this.stateService.env.customize?.theme && !['default', 'contrast', 'softsimon'].includes(theme)) { + // theme preference must be a valid known public theme. 'default' is light, + // which lives on :root so it needs no stylesheet and cannot flash. + if (!this.stateService.env.customize?.theme && !ThemeService.PUBLIC_THEMES.includes(theme)) { theme = 'default'; this.storageService.setValue('theme-preference', 'default'); } @@ -64,7 +68,7 @@ export class ThemeService { this.style.media = 'all'; this.initialLoad = false; } - this.mempoolFeeColors = theme === 'contrast' || theme === 'bukele' ? contrastMempoolFeeColors : defaultMempoolFeeColors; + this.mempoolFeeColors = theme === 'contrast' ? contrastMempoolFeeColors : defaultMempoolFeeColors; this.themeState$.next({ theme, loading: false }); }; this.style.onerror = () => this.apply('default'); diff --git a/frontend/src/app/shared/components/global-footer/global-footer.component.html b/frontend/src/app/shared/components/global-footer/global-footer.component.html index 29d784083c7..63a8be4961b 100644 --- a/frontend/src/app/shared/components/global-footer/global-footer.component.html +++ b/frontend/src/app/shared/components/global-footer/global-footer.component.html @@ -64,7 +64,6 @@

Broadcast Transaction

Test Transaction

Preview Transaction

-

Connect to our Nodes

API Documentation

-
-

- {{ (backendInfo$ | async)?.hostname }} (v{{ (backendInfo$ | async )?.version }}) [{{ (backendInfo$ | async )?.gitCommit | slice:0:8 }}] - [{{ (servicesBackendInfo$ | async )?.gitCommit | slice:0:8 }}] -

-

v{{ packetJsonVersion }} [{{ frontendGitCommitHash }}]

+

v{{ packetJsonVersion }} [{{ frontendGitCommitHash }}]

diff --git a/frontend/src/app/shared/components/global-footer/global-footer.component.ts b/frontend/src/app/shared/components/global-footer/global-footer.component.ts index f5f0e32520f..28e7465b6cb 100644 --- a/frontend/src/app/shared/components/global-footer/global-footer.component.ts +++ b/frontend/src/app/shared/components/global-footer/global-footer.component.ts @@ -22,6 +22,8 @@ export class GlobalFooterComponent implements OnInit, OnDestroy, OnChanges { private destroy$: Subject = new Subject(); env: Env; + /** The public source of the running build, published on the source page too. */ + readonly sourceRepository = 'https://github.com/bitcoinuniverseio/mempool'; officialMempoolSpace = this.stateService.env.OFFICIAL_MEMPOOL_SPACE; mempoolSpaceBuild = window['isMempoolSpaceBuild']; backendInfo$: Observable; diff --git a/frontend/src/app/shared/transaction.utils.ts b/frontend/src/app/shared/transaction.utils.ts index 650881cb2d8..84b0b357c00 100644 --- a/frontend/src/app/shared/transaction.utils.ts +++ b/frontend/src/app/shared/transaction.utils.ts @@ -86,7 +86,7 @@ export function setSchnorrSighashFlags(flags: bigint, witness: string[]): bigint export function isDERSig(w: string): boolean { // heuristic to detect probable DER signatures return (w.length >= 18 - && w.startsWith('30') // minimum DER signature length is 8 bytes + sighash flag (see https://mempool.space/testnet/tx/c6c232a36395fa338da458b86ff1327395a9afc28c5d2daa4273e410089fd433) + && w.startsWith('30') // minimum DER signature length is 8 bytes + sighash flag (see testnet transaction c6c232a36395fa338da458b86ff1327395a9afc28c5d2daa4273e410089fd433) && ['01', '02', '03', '81', '82', '83'].includes(w.slice(-2)) // signature must end with a valid sighash flag && (w.length === (2 * parseInt(w.slice(2, 4), 16)) + 6) // second byte encodes the combined length of the R and S components ); @@ -96,7 +96,7 @@ export function isDERSig(w: string): boolean { // <0x30> <0x02> <0x02> // see https://github.com/bitcoin/bitcoin/blob/9a05b45da60d214cb1e5a50c3d2293b1defc9bb0/src/script/interpreter.cpp#L97-L106 export function isCanonicalDERSig(w: string): boolean { - // minimum DER signature length is 8 bytes + sighash flag (see https://mempool.space/testnet/tx/c6c232a36395fa338da458b86ff1327395a9afc28c5d2daa4273e410089fd433) + // minimum DER signature length is 8 bytes + sighash flag (see testnet transaction c6c232a36395fa338da458b86ff1327395a9afc28c5d2daa4273e410089fd433) if (w.length < 18) { return false; } @@ -845,7 +845,7 @@ export function getTransactionFlags(tx: Transaction, cpfpInfo?: CpfpInfo, replac flags |= TransactionFlags.p2tr; // every valid taproot input has at least one witness item, however transactions // created before taproot activation don't need to have any witness data - // (see https://mempool.space/tx/b10c007c60e14f9d087e0291d4d0c7869697c6681d979c6639dbd960792b4d41) + // (see transaction b10c007c60e14f9d087e0291d4d0c7869697c6681d979c6639dbd960792b4d41) if (vin.witness?.length) { const taprootInfo = parseTaproot(vin.witness); if (taprootInfo.scriptPath) { diff --git a/frontend/src/app/universe/_asset-page.scss b/frontend/src/app/universe/_asset-page.scss new file mode 100644 index 00000000000..0b108bf32df --- /dev/null +++ b/frontend/src/app/universe/_asset-page.scss @@ -0,0 +1,108 @@ +// Shared layout for the single-asset pages (inscription, rune, sat). +// They present the same kind of thing: an identity block, a location block, +// and an evidence line, so they should look identical rather than nearly so. + +@use 'universe-tokens' as u; + +@mixin universe-asset-page { + @include u.universe-protocol-tokens; + @include u.universe-state-tokens; + + display: block; + + .universe-asset { + padding: 1.25rem 0 3rem; + } + + .page-head { + display: flex; + flex-wrap: wrap; + align-items: flex-start; + justify-content: space-between; + gap: 0.75rem; + margin-bottom: 1rem; + + h1 { + font-size: 1.5rem; + margin: 0; + } + + .reference { + margin: 0.3rem 0 0; + color: var(--transparent-fg, #a8b0c4); + } + } + + .panel { + @include u.universe-surface; + + padding: 1rem; + margin-bottom: 0.75rem; + + h2 { + font-size: 1rem; + margin: 0 0 0.6rem; + } + + p { + margin: 0 0 0.5rem; + max-width: 70ch; + } + + p:last-child { + margin-bottom: 0; + } + } + + .state-panel.unavailable { + border-left: 3px solid var(--universe-state-unavailable); + } + + .identifier { + @include u.universe-identifier; + } + + dl { + display: grid; + grid-template-columns: minmax(9rem, max-content) 1fr; + gap: 0.4rem 1rem; + margin: 0; + + dt { + color: var(--transparent-fg, #a8b0c4); + } + + dd { + margin: 0; + min-width: 0; + } + } + + .asof { + color: var(--transparent-fg, #a8b0c4); + font-size: 0.85rem; + margin: 0; + } + + .skeleton-line { + height: 1rem; + border-radius: 0.2rem; + background: rgba(255, 255, 255, 0.06); + margin: 0 0 0.6rem; + + &.short { + width: 40%; + } + } + + @media (max-width: 575px) { + dl { + grid-template-columns: 1fr; + gap: 0.1rem; + + dd { + margin-bottom: 0.5rem; + } + } + } +} diff --git a/frontend/src/app/universe/_universe-tokens.scss b/frontend/src/app/universe/_universe-tokens.scss new file mode 100644 index 00000000000..e4ad13579eb --- /dev/null +++ b/frontend/src/app/universe/_universe-tokens.scss @@ -0,0 +1,72 @@ +// Universe Explorer design tokens. +// +// One place for the protocol identity colors and evidence-state colors used +// across the Universe surfaces. Colors are chosen against the explorer's dark +// surfaces (--box-bg, --bg) and all of them clear WCAG AA contrast as text. +// Color is never the only signal: every state also carries a text label. + +@mixin universe-protocol-tokens { + --universe-protocol-ordinals: #f2a35c; + --universe-protocol-runes: #7bdff2; + --universe-protocol-alkanes: #b8a3f6; + --universe-protocol-stamps: #f6a3c5; + --universe-protocol-atomicals: #9df29d; + --universe-protocol-op-data: #e8e05c; + --universe-protocol-fallback: #c9cddd; +} + +@mixin universe-state-tokens { + // Evidence states. Proven, partial, pending, and unavailable must never be + // confusable, because the whole product rests on the difference. + --universe-state-proven: #6fd39a; + --universe-state-partial: #e8c15c; + --universe-state-pending: #7bb8f2; + --universe-state-unavailable: #f28b82; + --universe-state-neutral: #a8b0c4; +} + +@mixin universe-surface { + background: var(--box-bg, #171c2a); + border: 1px solid rgba(255, 255, 255, 0.07); + border-radius: 0.4rem; +} + +// A compact status chip. `kind` selects the token. +@mixin universe-chip { + display: inline-flex; + align-items: center; + gap: 0.35em; + padding: 0.15em 0.55em; + border-radius: 0.25rem; + border: 1px solid currentColor; + font-size: 0.75rem; + font-weight: 600; + line-height: 1.5; + white-space: nowrap; + color: var(--universe-state-neutral); + + &.state-proven { color: var(--universe-state-proven); } + &.state-partial { color: var(--universe-state-partial); } + &.state-pending { color: var(--universe-state-pending); } + &.state-unavailable { color: var(--universe-state-unavailable); } +} + +// Monospace identifier treatment. Long hashes must stay selectable and must +// never widen a layout, so they wrap on any character rather than overflow. +@mixin universe-identifier { + font-family: var(--font-mono, 'Courier New', monospace); + font-size: 0.85em; + overflow-wrap: anywhere; + word-break: break-all; +} + +// Motion is meaningful here (arrival, confirmation, replacement), so it stays +// on by default, but a visitor who asked their system for less motion gets it. +@mixin universe-motion($properties: all, $duration: 220ms) { + transition: $properties $duration ease-out; + + @media (prefers-reduced-motion: reduce) { + transition: none; + animation: none !important; + } +} diff --git a/frontend/src/app/universe/address-assets/address-assets.component.html b/frontend/src/app/universe/address-assets/address-assets.component.html new file mode 100644 index 00000000000..1ec51d2c749 --- /dev/null +++ b/frontend/src/app/universe/address-assets/address-assets.component.html @@ -0,0 +1,59 @@ +
+ + + + +
+

Universe assets

+

+
+ +
+

Universe assets

+

+ The asset authority could not be reached, so this address's protocol assets + are not shown. Its bitcoin balance above is unaffected. +

+
+ +
+

Universe assets

+ +

+ + Checked {{ state.resolved }} of this address's unspent outputs. + + + {{ state.notResolved }} more were not checked on this page. + +

+ +

+ At least one output could not be fully accounted for, so this list may be + incomplete. +

+ +

+ No supported protocol asset was found on the outputs checked. +

+ + + +

+ Proven at block {{ state.checkpointHeight }}. +

+
+ +
+
diff --git a/frontend/src/app/universe/address-assets/address-assets.component.scss b/frontend/src/app/universe/address-assets/address-assets.component.scss new file mode 100644 index 00000000000..43600c3eb14 --- /dev/null +++ b/frontend/src/app/universe/address-assets/address-assets.component.scss @@ -0,0 +1,116 @@ +@use '../universe-tokens' as u; + +:host { + @include u.universe-protocol-tokens; + @include u.universe-state-tokens; + + display: block; + margin-bottom: 1rem; +} + +.panel { + @include u.universe-surface; + + padding: 1rem; + + h2 { + font-size: 1rem; + margin: 0 0 0.6rem; + } + + p { + margin: 0 0 0.5rem; + max-width: 72ch; + } + + p:last-child { + margin-bottom: 0; + } + + &.unavailable { + border-left: 3px solid var(--universe-state-unavailable); + } +} + +.identifier { + @include u.universe-identifier; +} + +.coverage, +.asof { + color: var(--transparent-fg, #a8b0c4); + font-size: 0.85rem; +} + +.partial { + color: var(--universe-state-partial); + font-size: 0.85rem; +} + +.empty { + color: var(--transparent-fg, #a8b0c4); +} + +.holding-list { + list-style: none; + margin: 0 0 0.6rem; + padding: 0; + + li { + display: grid; + grid-template-columns: minmax(6rem, max-content) minmax(8rem, 1fr) max-content; + grid-template-areas: + 'protocol asset quantity' + 'outputs outputs outputs'; + align-items: baseline; + gap: 0.25rem 0.75rem; + padding: 0.45rem 0; + border-top: 1px solid rgba(255, 255, 255, 0.05); + } + + li:first-child { + border-top: 0; + } +} + +.protocol { + grid-area: protocol; + font-size: 0.75rem; + text-transform: uppercase; + letter-spacing: 0.06em; +} + +.asset { + grid-area: asset; + font-weight: 600; + overflow-wrap: anywhere; +} + +.quantity { + grid-area: quantity; + font-variant-numeric: tabular-nums; +} + +.outputs { + grid-area: outputs; + display: flex; + flex-wrap: wrap; + gap: 0.35rem 0.6rem; +} + +.skeleton-line { + height: 1rem; + width: 60%; + border-radius: 0.2rem; + background: rgba(255, 255, 255, 0.06); +} + +@media (max-width: 575px) { + .holding-list li { + grid-template-columns: 1fr max-content; + grid-template-areas: + 'protocol quantity' + 'asset asset' + 'outputs outputs'; + } +} diff --git a/frontend/src/app/universe/address-assets/address-assets.component.spec.ts b/frontend/src/app/universe/address-assets/address-assets.component.spec.ts new file mode 100644 index 00000000000..55f50350e6b --- /dev/null +++ b/frontend/src/app/universe/address-assets/address-assets.component.spec.ts @@ -0,0 +1,122 @@ +import { describe, expect, it } from 'vitest'; +import { summarise } from '@app/universe/address-assets/address-assets.component'; +import type { OutpointEnrichment } from '@app/universe/universe.types'; + +function result(patch: Partial = {}): OutpointEnrichment { + return { + outpoint: `${'a'.repeat(64)}:0`, + status: 'ok', + positions: [], + coveredProtocolIds: [], + unknownAttachments: false, + checkpoint: null, + ...patch, + }; +} + +function position(protocolId: string, assetId: string, quantityAtomic?: string): unknown { + return { + outpoint: `${'a'.repeat(64)}:0`, + vout: 0, + valueSatsAtomic: '546', + asset: { protocolId, canonicalAssetId: assetId, assetKind: 'fungible', displayName: assetId }, + quantityAtomic, + state: 'unspent', + evidence: { authorityId: 'ord', coverage: 'complete' }, + }; +} + +describe('summarise', () => { + it('reports nothing for no results', () => { + const summary = summarise([]); + expect(summary.holdings).toEqual([]); + expect(summary.resolved).toBe(0); + expect(summary.partial).toBe(false); + }); + + it('counts only the outputs the authority actually answered for', () => { + const summary = summarise([result(), result({ status: 'unavailable' })]); + expect(summary.resolved).toBe(1); + expect(summary.partial).toBe(true); + }); + + it('does not treat a coverage boundary as a failure', () => { + const summary = summarise([result({ status: 'not-indexed' })]); + expect(summary.resolved).toBe(0); + expect(summary.partial).toBe(false); + }); + + it('flags unknown attachments as partial', () => { + const summary = summarise([result({ unknownAttachments: true })]); + expect(summary.partial).toBe(true); + }); + + it('sums quantities across outputs without losing precision', () => { + const big = '340282366920938463463374607431768211455'; + const summary = summarise([ + result({ positions: [position('runes', 'RUNE', big)] as never }), + result({ positions: [position('runes', 'RUNE', '1')] as never }), + ]); + expect(summary.holdings[0].quantityAtomic).toBe( + (BigInt(big) + 1n).toString(), + ); + }); + + it('keeps a holding with no quantity rather than inventing a zero', () => { + const summary = summarise([ + result({ positions: [position('ordinals', 'insc1')] as never }), + ]); + expect(summary.holdings[0].quantityAtomic).toBeNull(); + expect(summary.holdings[0].outpoints).toHaveLength(1); + }); + + it('separates assets that share a protocol', () => { + const summary = summarise([ + result({ + positions: [position('runes', 'A', '1'), position('runes', 'B', '2')] as never, + }), + ]); + expect(summary.holdings).toHaveLength(2); + }); + + it('ignores a malformed quantity instead of guessing', () => { + const summary = summarise([ + result({ positions: [position('runes', 'A', '-5')] as never }), + ]); + expect(summary.holdings[0].quantityAtomic).toBeNull(); + }); + + it('drops a position with no protocol rather than filing it wrongly', () => { + const summary = summarise([ + result({ positions: [{ outpoint: 'x', asset: {} }] as never }), + ]); + expect(summary.holdings).toEqual([]); + }); + + it('reports the most recent checkpoint it saw', () => { + const summary = summarise([ + result({ checkpoint: { heightAtomic: '900000', blockHash: 'a' } as never }), + result({ checkpoint: { heightAtomic: '900001', blockHash: 'b' } as never }), + ]); + expect(summary.checkpointHeight).toBe('900001'); + }); + + it('sorts holdings by protocol, then by how many outputs hold them', () => { + const summary = summarise([ + result({ + positions: [ + position('runes', 'A', '1'), + position('runes', 'B', '1'), + position('runes', 'B', '1'), + position('ordinals', 'C'), + ] as never, + }), + ]); + expect(summary.holdings.map((holding) => holding.protocolId)).toEqual([ + 'ordinals', + 'runes', + 'runes', + ]); + expect(summary.holdings[1].displayName).toBe('B'); + }); +}); diff --git a/frontend/src/app/universe/address-assets/address-assets.component.ts b/frontend/src/app/universe/address-assets/address-assets.component.ts new file mode 100644 index 00000000000..7423e4a7895 --- /dev/null +++ b/frontend/src/app/universe/address-assets/address-assets.component.ts @@ -0,0 +1,185 @@ +import { ChangeDetectionStrategy, Component, Input, OnChanges, SimpleChanges } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { RouterModule } from '@angular/router'; +import { Observable, catchError, forkJoin, map, of, startWith } from 'rxjs'; +import { Utxo } from '@interfaces/electrs.interface'; +import { + UniverseApiService, + UNIVERSE_OUTPOINT_BATCH_LIMIT, +} from '@app/universe/universe-api.service'; +import { + ExplorerOutpointPosition, + OutpointEnrichment, +} from '@app/universe/universe.types'; +import { formatAtomicAmount, shortenIdentifier } from '@app/universe/universe-evidence'; + +/** + * Outputs resolved per address view. Two batches is enough to cover almost + * every address a person actually reads, and it keeps one page view to two + * authority requests rather than an unbounded sweep. + */ +const MAXIMUM_RESOLVED_OUTPUTS = UNIVERSE_OUTPOINT_BATCH_LIMIT * 2; + +interface ProtocolHolding { + readonly protocolId: string; + readonly assetKey: string; + readonly displayName: string; + /** Sum across outputs, kept exact as a decimal string. */ + readonly quantityAtomic: string | null; + readonly outpoints: readonly string[]; +} + +interface AddressAssetsState { + readonly kind: 'loading' | 'ready' | 'unavailable' | 'skipped'; + readonly holdings?: readonly ProtocolHolding[]; + /** Outputs the authority answered for. The denominator for everything shown. */ + readonly resolved?: number; + /** Outputs this address holds that were not asked about. */ + readonly notResolved?: number; + /** True when at least one answered output could not be fully accounted for. */ + readonly partial?: boolean; + readonly checkpointHeight?: string | null; +} + +/** + * The protocol assets an address currently holds. + * + * Built from the address's own unspent outputs, resolved through the asset + * authority one bounded batch at a time. The panel always states how many + * outputs it covered, because a portfolio that hides its own coverage is + * indistinguishable from a wrong one. + */ +@Component({ + selector: 'app-universe-address-assets', + standalone: true, + imports: [CommonModule, RouterModule], + templateUrl: './address-assets.component.html', + styleUrls: ['./address-assets.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class AddressAssetsComponent implements OnChanges { + @Input() utxos: Utxo[] | null = null; + + state$: Observable; + readonly shorten = shortenIdentifier; + readonly amount = formatAtomicAmount; + + constructor(private api: UniverseApiService) {} + + ngOnChanges(changes: SimpleChanges): void { + if (!changes.utxos) {return;} + const utxos = this.utxos; + if (!Array.isArray(utxos) || utxos.length === 0) { + this.state$ = of({ kind: 'skipped' }); + return; + } + + const references = utxos + .filter((utxo) => utxo && typeof utxo.txid === 'string' && Number.isInteger(utxo.vout)) + .map((utxo) => `${utxo.txid}:${utxo.vout}`); + const covered = references.slice(0, MAXIMUM_RESOLVED_OUTPUTS); + const notResolved = references.length - covered.length; + + const batches: string[][] = []; + for (let index = 0; index < covered.length; index += UNIVERSE_OUTPOINT_BATCH_LIMIT) { + batches.push(covered.slice(index, index + UNIVERSE_OUTPOINT_BATCH_LIMIT)); + } + + this.state$ = forkJoin(batches.map((batch) => this.api.getOutpoints$(batch))).pipe( + map((responses): AddressAssetsState => { + const results = responses.flatMap((response) => response?.results ?? []); + return { ...summarise(results), notResolved, kind: 'ready' }; + }), + catchError(() => of({ kind: 'unavailable' })), + startWith({ kind: 'loading' }), + ); + } + + trackByHolding(index: number, holding: ProtocolHolding): string { + return holding.assetKey; + } + + outpointRoute(outpoint: string): string[] | null { + const separator = outpoint.lastIndexOf(':'); + if (separator !== 64) {return null;} + return ['/outpoint', outpoint.slice(0, 64), outpoint.slice(65)]; + } +} + +/** + * Folds per-output positions into per-asset holdings. + * + * Quantities are summed with BigInt, never with JavaScript numbers: token + * supplies routinely exceed the safe integer range and a silently rounded + * balance would be worse than none. + */ +export function summarise( + results: readonly OutpointEnrichment[], +): Omit { + const holdings = new Map(); + let resolved = 0; + let partial = false; + let checkpointHeight: string | null = null; + + for (const result of results) { + if (result?.status !== 'ok') { + if (result?.status && result.status !== 'not-indexed') {partial = true;} + continue; + } + resolved += 1; + if (result.unknownAttachments) {partial = true;} + if (result.checkpoint?.heightAtomic) {checkpointHeight = result.checkpoint.heightAtomic;} + for (const position of result.positions ?? []) { + addPosition(holdings, position); + } + } + + const list: ProtocolHolding[] = [...holdings.entries()].map(([assetKey, entry]) => ({ + assetKey, + protocolId: entry.protocolId, + displayName: entry.displayName, + quantityAtomic: entry.quantity === null ? null : entry.quantity.toString(), + outpoints: entry.outpoints, + })); + + list.sort( + (a, b) => + a.protocolId.localeCompare(b.protocolId) || + b.outpoints.length - a.outpoints.length || + a.displayName.localeCompare(b.displayName), + ); + + return { holdings: list, resolved, partial, checkpointHeight }; +} + +function addPosition( + holdings: Map, + position: ExplorerOutpointPosition, +): void { + const asset = position?.asset; + if (!asset?.protocolId) {return;} + const assetKey = `${asset.protocolId}:${asset.canonicalAssetId ?? ''}`; + if (!holdings.has(assetKey)) { + holdings.set(assetKey, { + protocolId: asset.protocolId, + displayName: asset.displayName || asset.ticker || asset.canonicalAssetId || asset.protocolId, + quantity: null, + outpoints: [], + }); + } + const entry = holdings.get(assetKey); + entry.outpoints.push(position.outpoint); + if (position.quantityAtomic && /^(0|[1-9][0-9]*)$/.test(position.quantityAtomic)) { + entry.quantity = (entry.quantity ?? 0n) + BigInt(position.quantityAtomic); + } +} diff --git a/frontend/src/app/universe/asset-flow/asset-flow.component.html b/frontend/src/app/universe/asset-flow/asset-flow.component.html index 5bb75fac4eb..4281afc8196 100644 --- a/frontend/src/app/universe/asset-flow/asset-flow.component.html +++ b/frontend/src/app/universe/asset-flow/asset-flow.component.html @@ -35,7 +35,9 @@

Universe Asset Flow

-

+

{{ plainSummary(state.flow) }}

+ +

{{ emptyLabel(state.flow) }}

@@ -67,6 +69,19 @@

Outputs

+
+ How this was proven +
    +
  • + {{ evidence.authorityId }} + {{ evidence.coverage }} + + block {{ checkpoint.heightAtomic }} + +
  • +
+
+

Protocol actions

    @@ -90,6 +105,13 @@

    Protocol actions

  • + :{{ position.vout }} {{ assetLabel(position.asset) }} diff --git a/frontend/src/app/universe/asset-flow/asset-flow.component.scss b/frontend/src/app/universe/asset-flow/asset-flow.component.scss index 58c0ea12fc8..72b83104b1b 100644 --- a/frontend/src/app/universe/asset-flow/asset-flow.component.scss +++ b/frontend/src/app/universe/asset-flow/asset-flow.component.scss @@ -212,3 +212,48 @@ white-space: nowrap; border: 0; } + +.flow-summary { + margin: 0 0 0.85rem; + max-width: 74ch; + font-size: 1rem; + line-height: 1.55; +} + +.outpoint-link { + font-family: var(--font-mono, 'Courier New', monospace); + font-size: 0.8em; + opacity: 0.75; + + &:hover, + &:focus-visible { opacity: 1; } +} + +.flow-evidence { + margin: 0.75rem 0 0; + font-size: 0.85rem; + + summary { + cursor: pointer; + color: var(--transparent-fg, #a8b0c4); + min-height: 32px; + display: flex; + align-items: center; + } + + .evidence-list { + list-style: none; + margin: 0.4rem 0 0; + padding: 0; + + li { + display: flex; + flex-wrap: wrap; + gap: 0.75rem; + padding: 0.15rem 0; + color: var(--transparent-fg, #a8b0c4); + } + } + + .evidence-authority { font-weight: 600; } +} diff --git a/frontend/src/app/universe/asset-flow/asset-flow.component.ts b/frontend/src/app/universe/asset-flow/asset-flow.component.ts index a08358a415b..1731f490a5b 100644 --- a/frontend/src/app/universe/asset-flow/asset-flow.component.ts +++ b/frontend/src/app/universe/asset-flow/asset-flow.component.ts @@ -139,6 +139,65 @@ export class AssetFlowComponent implements OnChanges { return this.badgeCache.get(protocolId); } + /** + * One or two sentences that a reader with no protocol knowledge can act on. + * + * The rule the whole product rests on applies here more than anywhere: this + * never says "sold", "bought", or "traded", because the authority proves what + * moved, not why. It describes actions the authority reported and counts + * positions it proved, and nothing else. + */ + plainSummary(flow: ExplorerTransactionAssetFlow): string { + if (flow.coinbase) { + return $localize`:@@universe.flow.summary-coinbase:This is the coinbase transaction that pays the miner. It has no inputs to spend.`; + } + + const actionCounts = new Map(); + for (const action of flow.actions ?? []) { + if (!action?.actionType) {continue;} + actionCounts.set(action.actionType, (actionCounts.get(action.actionType) ?? 0) + 1); + } + + const outputs = flow.outputs?.length ?? 0; + const inputs = flow.inputs?.length ?? 0; + + let core: string; + if (actionCounts.size > 0) { + const phrases = [...actionCounts.entries()].map( + ([type, count]) => `${count} ${this.actionLabel({ actionType: type } as ExplorerAssetAction).toLowerCase()}`, + ); + core = $localize`:@@universe.flow.summary-actions:The asset authority reports ${phrases.join(', ')}:actions: in this transaction.`; + } else if (outputs > 0) { + core = $localize`:@@universe.flow.summary-positions:This transaction places assets on ${outputs}:outputs: of its outputs. The authority reported no named protocol action for them.`; + } else if (inputs > 0) { + core = $localize`:@@universe.flow.summary-inputs-only:This transaction spends outputs that carried assets. The authority reported nothing attached to its outputs.`; + } else if (flow.complete) { + core = $localize`:@@universe.flow.summary-none:No supported protocol asset is involved in this transaction.`; + } else { + core = $localize`:@@universe.flow.summary-unproven:What this transaction does with protocol assets is not proven here.`; + } + + if (flow.status === 'mempool-candidate') { + return core + ' ' + $localize`:@@universe.flow.summary-pending:It is still waiting in the mempool, so this can change if it is replaced.`; + } + if (flow.status === 'replaced') { + return core + ' ' + $localize`:@@universe.flow.summary-replaced:It was replaced by another transaction and will not confirm as it stands.`; + } + if (flow.status === 'orphaned') { + return core + ' ' + $localize`:@@universe.flow.summary-orphaned:The block that contained it is no longer part of the chain.`; + } + return core; + } + + /** Route to the dedicated page for the output a position sits on. */ + outpointRoute(position: ExplorerOutpointPosition): string[] | null { + const outpoint = position?.outpoint; + if (typeof outpoint !== 'string') {return null;} + const separator = outpoint.lastIndexOf(':'); + if (separator !== 64) {return null;} + return ['/outpoint', outpoint.slice(0, 64), outpoint.slice(65)]; + } + /** Notable sats are the substance of a rare_sats position, not decoration. */ notableSats(position: ExplorerOutpointPosition): ExplorerNotableSat[] { return position.notableSats ?? []; diff --git a/frontend/src/app/universe/asset-lookup.spec.ts b/frontend/src/app/universe/asset-lookup.spec.ts new file mode 100644 index 00000000000..05ab36ec7e8 --- /dev/null +++ b/frontend/src/app/universe/asset-lookup.spec.ts @@ -0,0 +1,134 @@ +import { describe, expect, it } from 'vitest'; +import { of, throwError } from 'rxjs'; +import { + applyDivisibility, + assetState$, + assetStatusMessage, + assetTone, + mintProgressPercent, + utcFromSeconds, +} from '@app/universe/asset-lookup'; +import type { AssetLookupResult } from '@app/universe/universe.types'; + +function collect(source: ReturnType>): Promise { + return new Promise((resolve, reject) => { + const seen: unknown[] = []; + source.subscribe({ + next: (value) => seen.push(value), + error: reject, + complete: () => resolve(seen), + }); + }); +} + +const OK: AssetLookupResult<{ id: string }> = { + schemaVersion: 'universe-explorer-asset-v1', + status: 'ok', + authorityId: 'ord', + checkpoint: null, + value: { id: 'x' }, +}; + +describe('assetState$', () => { + it('emits loading before the answer', async () => { + const states = await collect(assetState$('x', of(OK))); + expect(states.map((state: never) => state.kind)).toEqual(['loading', 'ready']); + }); + + it('turns a 404 into a miss, not an outage', async () => { + const error = { status: 404, error: { ...OK, status: 'not-found', value: null } }; + const states = await collect(assetState$('x', throwError(() => error))); + expect(states.map((state: never) => state.kind)).toEqual(['loading', 'missing']); + }); + + it('turns a 400 into an invalid reference', async () => { + const states = await collect(assetState$('x', throwError(() => ({ status: 400 })))); + expect(states.map((state: never) => state.kind)).toEqual(['loading', 'invalid']); + }); + + it('turns a 502 into unavailable', async () => { + const states = await collect(assetState$('x', throwError(() => ({ status: 502 })))); + expect(states.map((state: never) => state.kind)).toEqual(['loading', 'unavailable']); + }); + + it('treats a 200 with a non-ok status as unavailable rather than ready', async () => { + const degraded = { ...OK, status: 'unavailable' as const, value: null }; + const states = await collect(assetState$('x', of(degraded))); + expect(states.map((state: never) => state.kind)).toEqual(['loading', 'unavailable']); + }); +}); + +describe('assetStatusMessage', () => { + it('never describes an outage as an absence', () => { + expect(assetStatusMessage('not-found')).toContain('no record'); + expect(assetStatusMessage('unavailable')).toContain('could not be reached'); + expect(assetStatusMessage('unconfigured')).toContain('no asset authority configured'); + expect(assetStatusMessage(undefined)).toContain('could not be reached'); + }); +}); + +describe('assetTone', () => { + it('maps view kinds to evidence tones', () => { + expect(assetTone('ready')).toBe('proven'); + expect(assetTone('missing')).toBe('partial'); + expect(assetTone('unavailable')).toBe('unavailable'); + expect(assetTone('invalid')).toBe('unavailable'); + }); +}); + +describe('applyDivisibility', () => { + it('places the decimal point exactly', () => { + expect(applyDivisibility('1234567', '3')).toBe('1,234.567'); + expect(applyDivisibility('1000', '3')).toBe('1'); + expect(applyDivisibility('1', '3')).toBe('0.001'); + }); + + it('treats zero divisibility as a whole number', () => { + expect(applyDivisibility('1234', '0')).toBe('1,234'); + }); + + it('keeps precision beyond the safe integer range', () => { + const huge = '123456789012345678901234567890'; + expect(applyDivisibility(huge, '0').replace(/,/g, '')).toBe(huge); + }); + + it('refuses malformed input', () => { + expect(applyDivisibility('abc', '2')).toBe(''); + }); +}); + +describe('mintProgressPercent', () => { + it('floors the ratio', () => { + expect(mintProgressPercent('1', '3')).toBe(33); + expect(mintProgressPercent('2', '3')).toBe(66); + }); + + it('reports zero progress as zero, not as missing', () => { + expect(mintProgressPercent('0', '1000')).toBe(0); + }); + + it('caps at one hundred when mints exceed the cap', () => { + expect(mintProgressPercent('2000', '1000')).toBe(100); + }); + + it('reports no progress at all when there is no cap', () => { + expect(mintProgressPercent('5', null)).toBeNull(); + expect(mintProgressPercent('5', undefined)).toBeNull(); + expect(mintProgressPercent('5', '0')).toBeNull(); + }); + + it('handles caps beyond the safe integer range', () => { + expect(mintProgressPercent('500000000000000000000', '1000000000000000000000')).toBe(50); + }); +}); + +describe('utcFromSeconds', () => { + it('formats a unix timestamp in UTC', () => { + expect(utcFromSeconds('0')).toBe('1970-01-01 00:00:00 UTC'); + }); + + it('returns nothing for junk', () => { + expect(utcFromSeconds(null)).toBe(''); + expect(utcFromSeconds('abc')).toBe(''); + }); +}); diff --git a/frontend/src/app/universe/asset-lookup.ts b/frontend/src/app/universe/asset-lookup.ts new file mode 100644 index 00000000000..e3b4a0ec0c2 --- /dev/null +++ b/frontend/src/app/universe/asset-lookup.ts @@ -0,0 +1,111 @@ +import { HttpErrorResponse } from '@angular/common/http'; +import { Observable, catchError, map, of, startWith } from 'rxjs'; +import { AssetLookupResult, AssetLookupStatus } from '@app/universe/universe.types'; +import { EvidenceTone } from '@app/universe/universe-evidence'; + +/** + * Shared handling for the asset lookup routes. + * + * The overlay answers a miss with 404 and an outage with 502, and the + * difference is the whole point: an inscription that does not exist and an + * authority that is down must never look the same on screen. + */ + +export interface AssetViewState { + readonly kind: 'loading' | 'ready' | 'missing' | 'unavailable' | 'invalid'; + readonly result?: AssetLookupResult; + readonly reference?: string; +} + +export function assetState$( + reference: string, + request$: Observable>, +): Observable> { + return request$.pipe( + map((result): AssetViewState => + result?.status === 'ok' && result.value + ? { kind: 'ready', result, reference } + : { kind: 'unavailable', result, reference }, + ), + catchError((error: HttpErrorResponse) => { + const body = error?.error; + const result: AssetLookupResult | undefined = + body && typeof body === 'object' && typeof body.status === 'string' ? body : undefined; + if (error?.status === 404) { + return of>({ kind: 'missing', result, reference }); + } + if (error?.status === 400) { + return of>({ kind: 'invalid', reference }); + } + return of>({ kind: 'unavailable', result, reference }); + }), + startWith>({ kind: 'loading', reference }), + ); +} + +/** Says exactly what happened, and never dresses an outage as an absence. */ +export function assetStatusMessage(status: AssetLookupStatus | undefined): string { + switch (status) { + case 'not-found': + return $localize`:@@universe.asset.not-found:The asset authority has no record of this, as of the block below.`; + case 'unconfigured': + return $localize`:@@universe.asset.unconfigured:This deployment has no asset authority configured, so protocol assets cannot be looked up.`; + case 'malformed': + return $localize`:@@universe.asset.malformed:The asset authority replied with something this explorer refuses to trust.`; + default: + return $localize`:@@universe.asset.unavailable:The asset authority could not be reached. Nothing is claimed while that is true.`; + } +} + +export function assetTone(kind: AssetViewState['kind']): EvidenceTone { + if (kind === 'ready') {return 'proven';} + if (kind === 'missing') {return 'partial';} + return 'unavailable'; +} + +/** + * Formats a whole-number amount against a divisibility, without floating + * point. Rune supplies routinely exceed the safe integer range. + */ +export function applyDivisibility(atomic: string, divisibility: string): string { + if (!/^(0|[1-9][0-9]*)$/.test(atomic ?? '')) {return '';} + const decimals = Number(divisibility); + if (!Number.isInteger(decimals) || decimals <= 0 || decimals > 38) { + return groupDigits(atomic); + } + const padded = atomic.padStart(decimals + 1, '0'); + const whole = padded.slice(0, padded.length - decimals); + const fraction = padded.slice(padded.length - decimals).replace(/0+$/, ''); + return fraction ? `${groupDigits(whole)}.${fraction}` : groupDigits(whole); +} + +function groupDigits(value: string): string { + return value.replace(/\B(?=(\d{3})+(?!\d))/g, ','); +} + +/** + * Mint progress as a whole percent, floored. + * + * Returns null when the terms do not define a cap, because a mint with no cap + * has no progress to report and inventing one would be a fabricated metric. + */ +export function mintProgressPercent( + mintsAtomic: string, + capAtomic: string | null | undefined, +): number | null { + if (!capAtomic || !/^(0|[1-9][0-9]*)$/.test(capAtomic)) {return null;} + if (!/^(0|[1-9][0-9]*)$/.test(mintsAtomic ?? '')) {return null;} + const cap = BigInt(capAtomic); + if (cap === 0n) {return null;} + const mints = BigInt(mintsAtomic); + const percent = (mints * 100n) / cap; + return Number(percent > 100n ? 100n : percent); +} + +/** Seconds since the epoch to a readable UTC timestamp. */ +export function utcFromSeconds(atomic: string | null | undefined): string { + if (!atomic || !/^(0|[1-9][0-9]{0,12})$/.test(atomic)) {return '';} + const milliseconds = Number(atomic) * 1000; + if (!Number.isFinite(milliseconds)) {return '';} + return new Date(milliseconds).toISOString().replace('T', ' ').replace('.000Z', ' UTC'); +} diff --git a/frontend/src/app/universe/block-protocols/block-protocols.component.html b/frontend/src/app/universe/block-protocols/block-protocols.component.html new file mode 100644 index 00000000000..204c9af6ff9 --- /dev/null +++ b/frontend/src/app/universe/block-protocols/block-protocols.component.html @@ -0,0 +1,38 @@ +
    + + + + +
    +

    Universe protocol activity

    +

    +
    + +
    +

    Universe protocol activity

    +

    {{ unavailableMessage(state.result) }}

    +
    + +
    +

    Universe protocol activity

    +

    {{ summary(state.result) }}

    + + + +

    + {{ hidden }} more are not listed here. +

    + +

    + + Read from {{ state.result.authorityId }} at block {{ checkpoint.heightAtomic }}. + +

    +
    + +
    +
    diff --git a/frontend/src/app/universe/block-protocols/block-protocols.component.scss b/frontend/src/app/universe/block-protocols/block-protocols.component.scss new file mode 100644 index 00000000000..ef8faa21c51 --- /dev/null +++ b/frontend/src/app/universe/block-protocols/block-protocols.component.scss @@ -0,0 +1,59 @@ +@use '../universe-tokens' as u; + +:host { + @include u.universe-protocol-tokens; + @include u.universe-state-tokens; + + display: block; + margin-bottom: 1rem; +} + +.panel { + @include u.universe-surface; + + padding: 1rem; + + h2 { + font-size: 1rem; + margin: 0 0 0.6rem; + } + + p { + margin: 0 0 0.5rem; + max-width: 72ch; + } + + p:last-child { + margin-bottom: 0; + } + + &.unavailable { + border-left: 3px solid var(--universe-state-unavailable); + } +} + +.identifier { + @include u.universe-identifier; +} + +.inscription-list { + display: flex; + flex-wrap: wrap; + gap: 0.35rem 0.75rem; + list-style: none; + margin: 0 0 0.5rem; + padding: 0; +} + +.more, +.asof { + color: var(--transparent-fg, #a8b0c4); + font-size: 0.85rem; +} + +.skeleton-line { + height: 1rem; + width: 60%; + border-radius: 0.2rem; + background: rgba(255, 255, 255, 0.06); +} diff --git a/frontend/src/app/universe/block-protocols/block-protocols.component.ts b/frontend/src/app/universe/block-protocols/block-protocols.component.ts new file mode 100644 index 00000000000..8ca99dbd92f --- /dev/null +++ b/frontend/src/app/universe/block-protocols/block-protocols.component.ts @@ -0,0 +1,95 @@ +import { ChangeDetectionStrategy, Component, Input, OnChanges, SimpleChanges } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { RouterModule } from '@angular/router'; +import { HttpErrorResponse } from '@angular/common/http'; +import { Observable, catchError, map, of, startWith } from 'rxjs'; +import { UniverseApiService } from '@app/universe/universe-api.service'; +import { AssetLookupResult, OrdBlockInscriptionsView } from '@app/universe/universe.types'; +import { shortenIdentifier } from '@app/universe/universe-evidence'; + +interface BlockProtocolsState { + readonly kind: 'loading' | 'ready' | 'unavailable' | 'skipped'; + readonly result?: AssetLookupResult; +} + +/** How many inscription ids to show before the list is summarised. */ +const VISIBLE_LIMIT = 24; + +/** + * What protocol activity a confirmed block actually contains. + * + * This asks the asset authority for the inscriptions revealed in one block, + * which is a fact it can answer in a single bounded request. It deliberately + * does not attempt to enrich every transaction in the block: that would be + * thousands of authority reads per page view, and a page that slow would stop + * being used. + */ +@Component({ + selector: 'app-universe-block-protocols', + standalone: true, + imports: [CommonModule, RouterModule], + templateUrl: './block-protocols.component.html', + styleUrls: ['./block-protocols.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class BlockProtocolsComponent implements OnChanges { + @Input() height: number | null = null; + + state$: Observable; + readonly shorten = shortenIdentifier; + readonly visibleLimit = VISIBLE_LIMIT; + + constructor(private api: UniverseApiService) {} + + ngOnChanges(changes: SimpleChanges): void { + if (!changes.height) {return;} + if (this.height === null || this.height === undefined || this.height < 0) { + this.state$ = of({ kind: 'skipped' }); + return; + } + this.state$ = this.api.getBlockInscriptions$(this.height).pipe( + map((result): BlockProtocolsState => + result?.status === 'ok' && result.value + ? { kind: 'ready', result } + : { kind: 'unavailable', result }, + ), + catchError((error: HttpErrorResponse) => { + const body = error?.error; + const result = + body && typeof body === 'object' && typeof body.status === 'string' + ? (body as AssetLookupResult) + : undefined; + return of({ kind: 'unavailable', result }); + }), + startWith({ kind: 'loading' }), + ); + } + + visible(ids: string[]): string[] { + return ids.slice(0, VISIBLE_LIMIT); + } + + hiddenCount(result: AssetLookupResult): number { + const ids = result.value?.ids ?? []; + return Math.max(0, ids.length - VISIBLE_LIMIT); + } + + /** Explains what the count does and does not cover, without hedging into noise. */ + summary(result: AssetLookupResult): string { + const count = result.value?.ids.length ?? 0; + if (result.value?.more) { + return $localize`:@@universe.block.more:The authority returned the first ${count}:count: inscriptions revealed in this block and reports there are more.`; + } + if (count === 0) { + return $localize`:@@universe.block.none:No inscription was revealed in this block.`; + } + return $localize`:@@universe.block.count:${count}:count: inscriptions were revealed in this block.`; + } + + unavailableMessage(result?: AssetLookupResult): string { + if (result?.status === 'unconfigured') { + return $localize`:@@universe.block.unconfigured:This deployment has no asset authority configured, so protocol activity is not shown for blocks.`; + } + return $localize`:@@universe.block.unavailable:The asset authority could not be reached, so protocol activity for this block is unknown.`; + } +} diff --git a/frontend/src/app/universe/bookmark-button/bookmark-button.component.html b/frontend/src/app/universe/bookmark-button/bookmark-button.component.html new file mode 100644 index 00000000000..d9974f40199 --- /dev/null +++ b/frontend/src/app/universe/bookmark-button/bookmark-button.component.html @@ -0,0 +1,12 @@ + diff --git a/frontend/src/app/universe/bookmark-button/bookmark-button.component.scss b/frontend/src/app/universe/bookmark-button/bookmark-button.component.scss new file mode 100644 index 00000000000..9e067d1e05f --- /dev/null +++ b/frontend/src/app/universe/bookmark-button/bookmark-button.component.scss @@ -0,0 +1,47 @@ +@use '../universe-tokens' as u; + +.universe-bookmark { + display: inline-flex; + align-items: center; + gap: 0.35em; + padding: 0.2em 0.6em; + border-radius: 0.25rem; + border: 1px solid rgba(255, 255, 255, 0.18); + background: transparent; + color: var(--transparent-fg, #a8b0c4); + font-size: 0.8rem; + line-height: 1.6; + cursor: pointer; + min-height: 32px; + + &:hover, + &:focus-visible { + border-color: rgba(255, 255, 255, 0.4); + color: #fff; + } + + &.saved { + border-color: #e8c15c; + color: #e8c15c; + } + + .mark { + font-size: 1em; + line-height: 1; + } + + @include u.universe-motion; +} + +@media (max-width: 767px) { + .universe-bookmark .text { + // The star alone is unambiguous once the label has been read, and the + // accessible name stays on the button either way. + position: absolute; + width: 1px; + height: 1px; + overflow: hidden; + clip: rect(0 0 0 0); + white-space: nowrap; + } +} diff --git a/frontend/src/app/universe/bookmark-button/bookmark-button.component.ts b/frontend/src/app/universe/bookmark-button/bookmark-button.component.ts new file mode 100644 index 00000000000..b0bbbea6b64 --- /dev/null +++ b/frontend/src/app/universe/bookmark-button/bookmark-button.component.ts @@ -0,0 +1,66 @@ +import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnDestroy, OnInit } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { Subscription } from 'rxjs'; +import { UniverseEntryKind, UniverseLocalService } from '@app/universe/universe-local.service'; + +/** + * Saves a page to the visitor's own browser. No account, no server call, no + * profile: the list lives in local storage and is readable only by this + * browser. That is the whole point of it. + */ +@Component({ + selector: 'app-universe-bookmark-button', + standalone: true, + imports: [CommonModule], + templateUrl: './bookmark-button.component.html', + styleUrls: ['./bookmark-button.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class BookmarkButtonComponent implements OnInit, OnDestroy { + @Input() kind: UniverseEntryKind; + @Input() value: string; + @Input() path: string; + @Input() label: string; + + saved = false; + private subscription?: Subscription; + + constructor( + private local: UniverseLocalService, + private changeDetector: ChangeDetectorRef, + ) {} + + ngOnInit(): void { + this.subscription = this.local.bookmarks$.subscribe(() => { + const next = this.local.isBookmarked(this.kind, this.value); + if (next !== this.saved) { + this.saved = next; + this.changeDetector.markForCheck(); + } + }); + } + + ngOnDestroy(): void { + this.subscription?.unsubscribe(); + } + + toggle(): void { + if (!this.kind || !this.value || !this.path || !this.label) {return;} + this.saved = this.local.toggleBookmark({ + kind: this.kind, + value: this.value, + path: this.path, + label: this.label, + }); + this.changeDetector.markForCheck(); + } + + readonly saveLabel = $localize`:@@universe.bookmark.save-short:Save`; + readonly savedLabel = $localize`:@@universe.bookmark.saved-short:Saved`; + + get actionLabel(): string { + return this.saved + ? $localize`:@@universe.bookmark.remove:Remove from saved` + : $localize`:@@universe.bookmark.add:Save to this browser`; + } +} diff --git a/frontend/src/app/universe/chain-sync-notice/chain-sync-notice.component.html b/frontend/src/app/universe/chain-sync-notice/chain-sync-notice.component.html new file mode 100644 index 00000000000..f7ae12fb067 --- /dev/null +++ b/frontend/src/app/universe/chain-sync-notice/chain-sync-notice.component.html @@ -0,0 +1,10 @@ +
    + + This node is still catching up + + It has verified {{ notice.blocks }} of {{ notice.headers }} blocks, {{ notice.percent }} percent. + Everything below is accurate as of block {{ notice.blocks }}, and is {{ notice.behind }} blocks + behind the chain tip. + + +
    diff --git a/frontend/src/app/universe/chain-sync-notice/chain-sync-notice.component.scss b/frontend/src/app/universe/chain-sync-notice/chain-sync-notice.component.scss new file mode 100644 index 00000000000..89a6488bd8d --- /dev/null +++ b/frontend/src/app/universe/chain-sync-notice/chain-sync-notice.component.scss @@ -0,0 +1,28 @@ +@use '../universe-tokens' as u; + +:host { + @include u.universe-state-tokens; + + display: block; +} + +.chain-sync-notice:not(:empty) { + display: flex; + flex-wrap: wrap; + align-items: baseline; + gap: 0.35rem 0.75rem; + padding: 0.6rem 1rem; + border-bottom: 1px solid rgba(232, 193, 92, 0.35); + background: rgba(232, 193, 92, 0.08); + color: var(--universe-state-partial); + font-size: 0.9rem; + line-height: 1.5; + + strong { + font-weight: 700; + } + + span { + color: var(--transparent-fg, #a8b0c4); + } +} diff --git a/frontend/src/app/universe/chain-sync-notice/chain-sync-notice.component.spec.ts b/frontend/src/app/universe/chain-sync-notice/chain-sync-notice.component.spec.ts new file mode 100644 index 00000000000..0df0fa63166 --- /dev/null +++ b/frontend/src/app/universe/chain-sync-notice/chain-sync-notice.component.spec.ts @@ -0,0 +1,128 @@ +import { describe, expect, it } from 'vitest'; +import { + CHAIN_SYNC_TOLERANCE_BLOCKS, + chainSyncNotice, +} from '@app/universe/chain-sync-notice/chain-sync-notice.component'; +import type { IBackendInfo } from '@interfaces/websocket.interface'; + +function info(patch: Record = {}): IBackendInfo { + return { + gitCommit: 'abc1234', + version: '3.3.1', + chainSync: { + blocks: 900000, + headers: 900000, + initialBlockDownload: false, + verificationProgress: 1, + checkedAt: '2026-08-26T00:00:00.000Z', + }, + ...patch, + } as IBackendInfo; +} + +describe('chainSyncNotice', () => { + it('says nothing when the node is at the tip', () => { + expect(chainSyncNotice(info()).show).toBe(false); + }); + + it('says nothing while the backend has not reported yet', () => { + expect(chainSyncNotice(null).show).toBe(false); + expect(chainSyncNotice(info({ chainSync: null })).show).toBe(false); + expect(chainSyncNotice(info({ chainSync: undefined })).show).toBe(false); + }); + + it('tolerates ordinary propagation lag', () => { + const notice = chainSyncNotice( + info({ + chainSync: { + blocks: 900000, + headers: 900000 + CHAIN_SYNC_TOLERANCE_BLOCKS, + initialBlockDownload: false, + verificationProgress: 1, + checkedAt: '', + }, + }), + ); + expect(notice.show).toBe(false); + }); + + it('speaks up once the node is genuinely behind', () => { + const notice = chainSyncNotice( + info({ + chainSync: { + blocks: 819435, + headers: 964191, + initialBlockDownload: true, + verificationProgress: 0.663316, + checkedAt: '', + }, + }), + ); + expect(notice.show).toBe(true); + expect(notice.behind).toBe(964191 - 819435); + expect(notice.percent).toBe(66); + expect(notice.initial).toBe(true); + }); + + it('speaks up during initial block download even with no gap reported yet', () => { + const notice = chainSyncNotice( + info({ + chainSync: { + blocks: 100, + headers: 100, + initialBlockDownload: true, + verificationProgress: 0, + checkedAt: '', + }, + }), + ); + expect(notice.show).toBe(true); + expect(notice.behind).toBe(0); + }); + + it('never reports a negative gap or a percentage outside its range', () => { + const notice = chainSyncNotice( + info({ + chainSync: { + blocks: 900005, + headers: 900000, + initialBlockDownload: true, + verificationProgress: 1.4, + checkedAt: '', + }, + }), + ); + expect(notice.behind).toBe(0); + expect(notice.percent).toBe(100); + }); + + it('floors progress rather than rounding it up', () => { + const notice = chainSyncNotice( + info({ + chainSync: { + blocks: 1, + headers: 100, + initialBlockDownload: true, + verificationProgress: 0.999, + checkedAt: '', + }, + }), + ); + expect(notice.percent).toBe(99); + }); + + it('ignores a malformed reading rather than rendering nonsense', () => { + const notice = chainSyncNotice( + info({ + chainSync: { + blocks: Number.NaN, + headers: 100, + initialBlockDownload: true, + verificationProgress: 0.5, + checkedAt: '', + }, + }), + ); + expect(notice.show).toBe(false); + }); +}); diff --git a/frontend/src/app/universe/chain-sync-notice/chain-sync-notice.component.ts b/frontend/src/app/universe/chain-sync-notice/chain-sync-notice.component.ts new file mode 100644 index 00000000000..146c834e31a --- /dev/null +++ b/frontend/src/app/universe/chain-sync-notice/chain-sync-notice.component.ts @@ -0,0 +1,65 @@ +import { ChangeDetectionStrategy, Component } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { Observable, map } from 'rxjs'; +import { StateService } from '@app/services/state.service'; +import { IBackendInfo } from '@interfaces/websocket.interface'; + +export interface ChainSyncNotice { + readonly show: boolean; + readonly behind: number; + readonly blocks: number; + readonly headers: number; + readonly percent: number; + readonly initial: boolean; +} + +/** + * The gap between the node this explorer reads and the chain that exists. + * + * Every other claim on the site is qualified by the evidence behind it. The + * base chain deserves the same treatment: an explorer reading a node that is + * still catching up would otherwise present a months-old tip as the present, + * silently, which is the single worst thing it could do. So it says so, and it + * says by how much. + */ +@Component({ + selector: 'app-universe-chain-sync-notice', + standalone: true, + imports: [CommonModule], + templateUrl: './chain-sync-notice.component.html', + styleUrls: ['./chain-sync-notice.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class ChainSyncNoticeComponent { + notice$: Observable; + + constructor(private stateService: StateService) { + this.notice$ = this.stateService.backendInfo$.pipe(map(chainSyncNotice)); + } +} + +/** + * A gap of a block or two is ordinary propagation, not a sync problem, so the + * notice only appears once the node is genuinely behind. + */ +export const CHAIN_SYNC_TOLERANCE_BLOCKS = 3; + +export function chainSyncNotice(info: IBackendInfo | null): ChainSyncNotice { + const sync = info?.chainSync; + if (!sync || !Number.isFinite(sync.blocks) || !Number.isFinite(sync.headers)) { + return { show: false, behind: 0, blocks: 0, headers: 0, percent: 0, initial: false }; + } + const behind = Math.max(0, sync.headers - sync.blocks); + const progress = Number(sync.verificationProgress); + const percent = Number.isFinite(progress) + ? Math.min(100, Math.max(0, Math.floor(progress * 100))) + : 0; + return { + show: sync.initialBlockDownload || behind > CHAIN_SYNC_TOLERANCE_BLOCKS, + behind, + blocks: sync.blocks, + headers: sync.headers, + percent, + initial: !!sync.initialBlockDownload, + }; +} diff --git a/frontend/src/app/universe/inscription/inscription.component.html b/frontend/src/app/universe/inscription/inscription.component.html new file mode 100644 index 00000000000..27d480847a3 --- /dev/null +++ b/frontend/src/app/universe/inscription/inscription.component.html @@ -0,0 +1,142 @@ +
    + +
    +
    +

    Inscription

    +

    {{ state.reference }}

    +
    + +
    + + + +
    +

    +

    +
    + +
    +

    That is not an inscription reference

    +

    + Use an inscription id, written as a transaction id followed by + i and the index, or an inscription number. +

    +
    + +
    +

    No such inscription

    +

    {{ statusMessage(state.result?.status) }}

    +

    + As of block {{ checkpoint.heightAtomic }} +

    +
    + +
    +

    The asset authority did not answer

    +

    {{ statusMessage(state.result?.status) }}

    +
    + + +
    +
    +
    Inscription number
    +
    {{ state.result.value.numberAtomic }}
    + +
    Inscription id
    +
    {{ state.result.value.id }}
    + + +
    Revealed by
    +
    {{ txid }}
    +
    + + +
    Inscribed in block
    +
    {{ height }}
    +
    + + +
    Block time
    +
    {{ utc(timestamp) }}
    +
    + + +
    Content type
    +
    {{ contentType }}
    +
    + + +
    Content size
    +
    {{ amount(length) }} bytes
    +
    + + +
    Metaprotocol tag
    +
    {{ metaprotocol }}
    +
    +
    +
    + +
    +

    Where it sits now

    +
    + +
    Output
    +
    {{ state.result.value.satpoint }}
    +
    + + +
    Address
    +
    {{ address }}
    +
    + + +
    Satoshi
    +
    {{ amount(sat) }}
    +
    + + +
    Output value
    +
    {{ amount(value) }} sats
    +
    +
    +
    + +
    +

    Notes from the authority

    + +
      +
    • {{ charmLabel(charm) }}
    • +
    + +
    + +
    Parents
    +
    + {{ shorten(parent, 10) }} +
    +
    + + +
    Etches rune
    +
    {{ rune }}
    +
    +
    +
    + +

    + + Proven by {{ state.result.authorityId }} at block {{ checkpoint.heightAtomic }}. + +

    +
    +
    +
    diff --git a/frontend/src/app/universe/inscription/inscription.component.scss b/frontend/src/app/universe/inscription/inscription.component.scss new file mode 100644 index 00000000000..cba6a2ed6c1 --- /dev/null +++ b/frontend/src/app/universe/inscription/inscription.component.scss @@ -0,0 +1,27 @@ +@use '../asset-page' as page; + +:host { + @include page.universe-asset-page; + + .relations dd a + a { + margin-left: 0.6rem; + } + + .tag-list { + display: flex; + flex-wrap: wrap; + gap: 0.4rem; + list-style: none; + margin: 0 0 0.75rem; + padding: 0; + + li { + padding: 0.15em 0.55em; + border: 1px solid var(--universe-protocol-ordinals); + border-radius: 0.25rem; + color: var(--universe-protocol-ordinals); + font-size: 0.8rem; + text-transform: capitalize; + } + } +} diff --git a/frontend/src/app/universe/inscription/inscription.component.ts b/frontend/src/app/universe/inscription/inscription.component.ts new file mode 100644 index 00000000000..da091b4ae8f --- /dev/null +++ b/frontend/src/app/universe/inscription/inscription.component.ts @@ -0,0 +1,105 @@ +import { ChangeDetectionStrategy, Component, OnDestroy, OnInit } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { ActivatedRoute, RouterModule } from '@angular/router'; +import { Observable, Subscription, switchMap } from 'rxjs'; +import { SeoService } from '@app/services/seo.service'; +import { UniverseApiService } from '@app/universe/universe-api.service'; +import { UniverseLocalService } from '@app/universe/universe-local.service'; +import { BookmarkButtonComponent } from '@app/universe/bookmark-button/bookmark-button.component'; +import { OrdInscriptionView } from '@app/universe/universe.types'; +import { + AssetViewState, + assetState$, + assetStatusMessage, + assetTone, + utcFromSeconds, +} from '@app/universe/asset-lookup'; +import { formatAtomicAmount, shortenIdentifier } from '@app/universe/universe-evidence'; + +const INSCRIPTION_ID = /^[0-9a-f]{64}i(0|[1-9][0-9]{0,9})$/; +const INSCRIPTION_NUMBER = /^-?(0|[1-9][0-9]{0,18})$/; + +/** + * One inscription, as the first-party ord authority reports it. + * + * The page never renders inscription content. Rendering arbitrary inscribed + * data would mean executing whatever a stranger put on chain inside the + * explorer's own origin, and no view is worth that. + */ +@Component({ + selector: 'app-universe-inscription', + standalone: true, + imports: [CommonModule, RouterModule, BookmarkButtonComponent], + templateUrl: './inscription.component.html', + styleUrls: ['./inscription.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class InscriptionComponent implements OnInit, OnDestroy { + state$: Observable>; + + readonly shorten = shortenIdentifier; + readonly statusMessage = assetStatusMessage; + readonly tone = assetTone; + readonly utc = utcFromSeconds; + readonly amount = formatAtomicAmount; + + private visitSubscription?: Subscription; + + constructor( + private route: ActivatedRoute, + private api: UniverseApiService, + private local: UniverseLocalService, + private seo: SeoService, + ) {} + + ngOnInit(): void { + this.state$ = this.route.paramMap.pipe( + switchMap((params) => { + const reference = (params.get('reference') || '').trim(); + this.seo.setTitle(`Inscription ${shortenIdentifier(reference, 10)}`); + return assetState$( + reference, + this.api.getInscription$(reference), + ); + }), + ); + + this.visitSubscription = this.state$.subscribe((state) => { + if (state.kind !== 'ready' || !state.result?.value) {return;} + const inscription = state.result.value; + this.local.recordVisit({ + kind: 'inscription', + value: inscription.id, + path: `/inscription/${inscription.id}`, + label: `Inscription ${inscription.numberAtomic}`, + }); + }); + } + + ngOnDestroy(): void { + this.visitSubscription?.unsubscribe(); + } + + static valid(reference: string): boolean { + return INSCRIPTION_ID.test(reference) || INSCRIPTION_NUMBER.test(reference); + } + + /** The output the inscription currently sits on, so it can be opened directly. */ + outpointRoute(satpoint: string | null): string[] | null { + if (!satpoint) {return null;} + const parts = satpoint.split(':'); + if (parts.length !== 3) {return null;} + const [txid, vout] = parts; + if (!/^[0-9a-f]{64}$/.test(txid) || !/^(0|[1-9][0-9]{0,9})$/.test(vout)) {return null;} + return ['/outpoint', txid, vout]; + } + + /** The transaction that revealed this inscription, taken from its own id. */ + revealTxid(id: string): string | null { + return INSCRIPTION_ID.test(id) ? id.slice(0, 64) : null; + } + + charmLabel(charm: string): string { + return charm.replace(/[_-]+/g, ' '); + } +} diff --git a/frontend/src/app/universe/outpoint/outpoint.component.html b/frontend/src/app/universe/outpoint/outpoint.component.html new file mode 100644 index 00000000000..19d33dfb960 --- /dev/null +++ b/frontend/src/app/universe/outpoint/outpoint.component.html @@ -0,0 +1,131 @@ +
    + +
    +
    +

    Transaction output

    +

    + What this single output carries right now, and the evidence behind it. +

    +
    + +
    + + + +
    +

    That is not an output reference

    +

    + An output is written as a 64 character transaction id, a colon, and the + output number. For example + e0a1…4f2b:0. +

    +
    + +
    +

    This output could not be read

    +

    + The request was rejected. Check the output reference, then try again. +

    + + Open the transaction instead + +
    + +
    +

    +

    + Reading the asset authority +
    + + + +
    +
    +
    Output
    +
    {{ vm.result.outpoint }}
    + +
    Transaction
    +
    {{ vm.txid }}
    + + +
    Proven as of
    +
    + + Block {{ checkpoint.heightAtomic }} + +
    +
    +
    +
    + +
    +
    + {{ vm.evidence.label }} + Covering {{ vm.result.coveredProtocolIds.join(', ') }} +
    +

    {{ vm.evidence.detail }}

    +
    + +
    +

    Attached assets

    + +
    +

    + {{ group.protocolId }} +

    + +
      +
    • +
      + {{ position.asset?.displayName || position.asset?.ticker || position.asset?.canonicalAssetId }} + {{ amount }} +
      +
      + {{ position.asset?.assetKind }} + {{ position.state }} +
      +
        +
      • + {{ rarityLabel(sat) }} + {{ sat.satAtomic }} +
      • +
      +

      + More notable satoshis exist on this output than are listed here. +

      +
    • +
    +
    +
    + + +
    +

    Attached assets

    +

    + None. This output carries bitcoin only. +

    +

    + Not shown. Nothing is claimed about this output while the evidence above stands. +

    +
    +
    + +
    +

    Bitcoin value

    +

    {{ satsLabel(vm.result.positions[0].valueSatsAtomic) }} sats

    +

    + {{ owner }} +

    +
    + +
    +
    +
    diff --git a/frontend/src/app/universe/outpoint/outpoint.component.scss b/frontend/src/app/universe/outpoint/outpoint.component.scss new file mode 100644 index 00000000000..186f418d379 --- /dev/null +++ b/frontend/src/app/universe/outpoint/outpoint.component.scss @@ -0,0 +1,205 @@ +@use '../universe-tokens' as u; + +:host { + @include u.universe-protocol-tokens; + @include u.universe-state-tokens; + + display: block; +} + +.universe-outpoint { + padding: 1.25rem 0 3rem; +} + +.page-head { + display: flex; + flex-wrap: wrap; + align-items: flex-start; + justify-content: space-between; + gap: 0.75rem; + margin-bottom: 1rem; + + h1 { + font-size: 1.5rem; + margin: 0; + } + + .lede { + margin: 0.35rem 0 0; + color: var(--transparent-fg, #a8b0c4); + max-width: 46ch; + } +} + +.panel { + @include u.universe-surface; + + padding: 1rem; + margin-bottom: 0.75rem; + + h2 { + font-size: 1rem; + margin: 0 0 0.75rem; + letter-spacing: 0.02em; + } +} + +.identity dl { + display: grid; + grid-template-columns: minmax(8rem, max-content) 1fr; + gap: 0.4rem 1rem; + margin: 0; + + dt { + color: var(--transparent-fg, #a8b0c4); + font-weight: 500; + } + + dd { + margin: 0; + min-width: 0; + } +} + +.identifier { + @include u.universe-identifier; +} + +.universe-chip { + @include u.universe-chip; +} + +.evidence { + border-left: 3px solid var(--universe-state-neutral); + + &.state-proven { border-left-color: var(--universe-state-proven); } + &.state-partial { border-left-color: var(--universe-state-partial); } + &.state-pending { border-left-color: var(--universe-state-pending); } + &.state-unavailable { border-left-color: var(--universe-state-unavailable); } + + .evidence-head { + display: flex; + flex-wrap: wrap; + align-items: center; + gap: 0.5rem 0.75rem; + } + + .authority { + color: var(--transparent-fg, #a8b0c4); + font-size: 0.85rem; + } + + .evidence-detail { + margin: 0.6rem 0 0; + max-width: 68ch; + } +} + +.protocol-group + .protocol-group { + margin-top: 1rem; + padding-top: 1rem; + border-top: 1px solid rgba(255, 255, 255, 0.06); +} + +.protocol-name { + font-size: 0.8rem; + text-transform: uppercase; + letter-spacing: 0.06em; + margin: 0 0 0.5rem; + color: var(--transparent-fg, #a8b0c4); +} + +.position-list, +.notable-sats { + list-style: none; + margin: 0; + padding: 0; +} + +.position-list > li + li { + margin-top: 0.75rem; +} + +.asset-line { + display: flex; + flex-wrap: wrap; + align-items: baseline; + gap: 0.5rem 0.75rem; + + .asset-name { + font-weight: 600; + overflow-wrap: anywhere; + } + + .asset-amount { + font-variant-numeric: tabular-nums; + } +} + +.asset-meta { + display: flex; + gap: 0.75rem; + font-size: 0.8rem; + color: var(--transparent-fg, #a8b0c4); +} + +.notable-sats { + margin-top: 0.4rem; + + li { + display: flex; + gap: 0.5rem; + font-size: 0.8rem; + } + + .rarity { + text-transform: uppercase; + letter-spacing: 0.05em; + font-weight: 700; + color: var(--universe-protocol-ordinals); + } +} + +.notable-truncated { + margin: 0.35rem 0 0; + font-size: 0.8rem; + color: var(--transparent-fg, #a8b0c4); +} + +.value .sats { + font-variant-numeric: tabular-nums; + font-size: 1.1rem; + margin: 0 0 0.35rem; +} + +.state-panel .action { + display: inline-block; + margin-top: 0.5rem; +} + +.skeleton-line { + height: 1rem; + border-radius: 0.2rem; + background: rgba(255, 255, 255, 0.06); + margin: 0 0 0.6rem; + + &.short { width: 40%; } +} + +.visually-hidden { + position: absolute; + width: 1px; + height: 1px; + overflow: hidden; + clip: rect(0 0 0 0); + white-space: nowrap; +} + +@media (max-width: 575px) { + .identity dl { + grid-template-columns: 1fr; + gap: 0.15rem; + + dd { margin-bottom: 0.5rem; } + } +} diff --git a/frontend/src/app/universe/outpoint/outpoint.component.ts b/frontend/src/app/universe/outpoint/outpoint.component.ts new file mode 100644 index 00000000000..6de1e55a130 --- /dev/null +++ b/frontend/src/app/universe/outpoint/outpoint.component.ts @@ -0,0 +1,149 @@ +import { ChangeDetectionStrategy, Component, OnDestroy, OnInit } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { ActivatedRoute, RouterModule } from '@angular/router'; +import { HttpErrorResponse } from '@angular/common/http'; +import { Observable, Subscription, catchError, map, of, startWith, switchMap } from 'rxjs'; +import { SeoService } from '@app/services/seo.service'; +import { UniverseApiService } from '@app/universe/universe-api.service'; +import { UniverseLocalService } from '@app/universe/universe-local.service'; +import { BookmarkButtonComponent } from '@app/universe/bookmark-button/bookmark-button.component'; +import { + ExplorerNotableSat, + ExplorerOutpointPosition, + OutpointEnrichment, +} from '@app/universe/universe.types'; +import { + EvidenceView, + ProtocolGroup, + formatAtomicAmount, + groupPositionsByProtocol, + outpointEvidence, + shortenIdentifier, +} from '@app/universe/universe-evidence'; + +interface OutpointViewModel { + readonly kind: 'loading' | 'ready' | 'invalid' | 'error'; + readonly txid?: string; + readonly vout?: string; + readonly result?: OutpointEnrichment; + readonly evidence?: EvidenceView; + readonly groups?: readonly ProtocolGroup[]; +} + +const TXID = /^[0-9a-f]{64}$/; +const VOUT = /^(0|[1-9][0-9]{0,9})$/; + +/** + * One transaction output, treated as the thing it actually is: the unit that + * carries protocol assets on Bitcoin. Every other explorer treats an output as + * a row inside a transaction. Making it addressable is what lets a holder ask + * "what exactly is sitting on this UTXO right now" and get an answer with the + * evidence attached. + */ +@Component({ + selector: 'app-universe-outpoint', + standalone: true, + imports: [CommonModule, RouterModule, BookmarkButtonComponent], + templateUrl: './outpoint.component.html', + styleUrls: ['./outpoint.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class OutpointComponent implements OnInit, OnDestroy { + vm$: Observable; + + private visitSubscription?: Subscription; + + readonly shorten = shortenIdentifier; + + constructor( + private route: ActivatedRoute, + private api: UniverseApiService, + private local: UniverseLocalService, + private seo: SeoService, + ) {} + + ngOnInit(): void { + this.vm$ = this.route.paramMap.pipe( + switchMap((params): Observable => { + const txid = (params.get('txid') || '').toLowerCase(); + const vout = params.get('vout') || ''; + if (!TXID.test(txid) || !VOUT.test(vout)) { + return of({ kind: 'invalid' }); + } + this.seo.setTitle(`Output ${shortenIdentifier(txid)}:${vout}`); + return this.api.getOutpoint$(txid, vout).pipe( + map((result): OutpointViewModel => ({ + kind: 'ready', + txid, + vout, + result, + evidence: outpointEvidence(result), + groups: groupPositionsByProtocol(result.positions || []), + })), + catchError((error: HttpErrorResponse) => { + // A 5xx from the overlay is still a real answer about the state of + // the deployment, so it renders as an unavailable authority rather + // than a blank page. + if (error?.status >= 500 || error?.status === 0) { + const result: OutpointEnrichment = { + outpoint: `${txid}:${vout}`, + status: 'unavailable', + positions: [], + coveredProtocolIds: [], + unknownAttachments: false, + checkpoint: null, + }; + return of({ + kind: 'ready', + txid, + vout, + result, + evidence: outpointEvidence(result), + groups: [], + }); + } + return of({ kind: 'error', txid, vout }); + }), + startWith({ kind: 'loading', txid, vout }), + ); + }), + ); + + this.visitSubscription = this.route.paramMap.subscribe((params) => { + const txid = (params.get('txid') || '').toLowerCase(); + const vout = params.get('vout') || ''; + if (!TXID.test(txid) || !VOUT.test(vout)) {return;} + this.local.recordVisit({ + kind: 'outpoint', + value: `${txid}:${vout}`, + path: `/outpoint/${txid}/${vout}`, + label: `${shortenIdentifier(txid)}:${vout}`, + }); + }); + } + + ngOnDestroy(): void { + this.visitSubscription?.unsubscribe(); + } + + quantityLabel(position: ExplorerOutpointPosition): string { + if (!position.quantityAtomic) {return '';} + return formatAtomicAmount(position.quantityAtomic); + } + + satsLabel(valueSatsAtomic: string): string { + return formatAtomicAmount(valueSatsAtomic); + } + + rarityLabel(sat: ExplorerNotableSat): string { + return sat.rarity; + } + + trackByGroup(index: number, group: ProtocolGroup): string { + return group.protocolId; + } + + trackByPosition(index: number, position: ExplorerOutpointPosition): string { + return `${position.outpoint}:${position.asset?.canonicalAssetId ?? index}`; + } +} diff --git a/frontend/src/app/universe/protocol-detail/protocol-detail.component.html b/frontend/src/app/universe/protocol-detail/protocol-detail.component.html new file mode 100644 index 00000000000..de533fce229 --- /dev/null +++ b/frontend/src/app/universe/protocol-detail/protocol-detail.component.html @@ -0,0 +1,117 @@ +
    + + + +
    +

    No protocol by that name

    +

    + The registry has no entry with that id or alias. +

    + Back to all protocols +
    + +
    +

    The protocol registry could not be read

    +

    + The explorer could not reach its own registry. Everything else on the site + still works. +

    +
    + + + +
    +
    + +

    + {{ vm.protocol.displayName }} + {{ statusLabel(vm.protocol) }} +

    +

    {{ vm.copy.summary }}

    +
    + +
    + +
    +
    + +
    + +
    +

    Actions it creates

    +
      +
    • {{ action }}
    • +
    +
    + +
    +

    Authority and freshness

    +
    +
    Chain
    +
    {{ vm.protocol.chain }}
    + +
    Authority
    +
    {{ vm.protocol.indexerAuthority || notConfiguredLabel }}
    + + +
    Proven through
    +
    + Block {{ checkpoint.heightAtomic }} +
    +
    + + +
    Coverage
    +
    {{ coverage }}
    +
    +
    +
    + +
    + +
    +

    What is not shown, and why

    +

    {{ note }}

    +
    + +
    +

    How to read its evidence

    +

    {{ vm.copy.howToRead }}

    +
    + +
    +

    Live activity

    +

    + Seen in {{ liveCount(vm) }} of the {{ vm.pulse.checked }} transactions checked since this page opened. +

    + + + +

    + No transaction carrying this protocol has arrived since this page opened. +

    +
    + + Open the live protocol feed +
    + +
    + +
    +

    +

    +
    + +
    +
    diff --git a/frontend/src/app/universe/protocol-detail/protocol-detail.component.scss b/frontend/src/app/universe/protocol-detail/protocol-detail.component.scss new file mode 100644 index 00000000000..9d4ff234975 --- /dev/null +++ b/frontend/src/app/universe/protocol-detail/protocol-detail.component.scss @@ -0,0 +1,139 @@ +@use '../universe-tokens' as u; + +:host { + @include u.universe-protocol-tokens; + @include u.universe-state-tokens; + + display: block; +} + +.protocol-detail { + padding: 1.25rem 0 3rem; +} + +.page-head { + display: flex; + flex-wrap: wrap; + align-items: flex-start; + justify-content: space-between; + gap: 0.75rem; + margin-bottom: 1rem; + + h1 { + display: flex; + flex-wrap: wrap; + align-items: center; + gap: 0.6rem; + font-size: 1.5rem; + margin: 0.2rem 0 0; + } + + .summary { + margin: 0.5rem 0 0; + max-width: 68ch; + color: var(--transparent-fg, #a8b0c4); + } +} + +.crumbs { + font-size: 0.85rem; +} + +.panel { + @include u.universe-surface; + + padding: 1rem; + margin-bottom: 0.75rem; + + h2 { + font-size: 1rem; + margin: 0 0 0.6rem; + } + + p { margin: 0 0 0.5rem; max-width: 72ch; } + p:last-of-type { margin-bottom: 0; } +} + +.grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr)); + gap: 0.75rem; + + .panel { margin-bottom: 0; } +} + +.universe-chip { + @include u.universe-chip; +} + +.identifier { + @include u.universe-identifier; +} + +.action-list { + display: flex; + flex-wrap: wrap; + gap: 0.4rem; + list-style: none; + margin: 0; + padding: 0; + + li { + padding: 0.15em 0.55em; + border: 1px solid rgba(255, 255, 255, 0.16); + border-radius: 0.25rem; + font-size: 0.85rem; + text-transform: lowercase; + } +} + +.authority dl { + display: grid; + grid-template-columns: minmax(7rem, max-content) 1fr; + gap: 0.35rem 1rem; + margin: 0; + + dt { color: var(--transparent-fg, #a8b0c4); } + dd { margin: 0; overflow-wrap: anywhere; } +} + +.limitation { + border-left: 3px solid var(--universe-state-partial); +} + +.event-list { + list-style: none; + margin: 0 0 0.6rem; + padding: 0; + + li { padding: 0.2rem 0; } +} + +.empty { + color: var(--transparent-fg, #a8b0c4); +} + +.pin { + padding: 0.3em 0.75em; + border-radius: 0.25rem; + border: 1px solid rgba(255, 255, 255, 0.18); + background: transparent; + color: var(--transparent-fg, #a8b0c4); + font-size: 0.85rem; + min-height: 34px; + cursor: pointer; + + &.pinned { + border-color: var(--universe-protocol-runes); + color: var(--universe-protocol-runes); + } +} + +.skeleton-line { + height: 1rem; + border-radius: 0.2rem; + background: rgba(255, 255, 255, 0.06); + margin: 0 0 0.6rem; + + &.short { width: 40%; } +} diff --git a/frontend/src/app/universe/protocol-detail/protocol-detail.component.ts b/frontend/src/app/universe/protocol-detail/protocol-detail.component.ts new file mode 100644 index 00000000000..5bf2f1ba333 --- /dev/null +++ b/frontend/src/app/universe/protocol-detail/protocol-detail.component.ts @@ -0,0 +1,190 @@ +import { ChangeDetectionStrategy, Component, OnDestroy, OnInit } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; +import { Observable, catchError, combineLatest, map, of, shareReplay, switchMap, tap } from 'rxjs'; +import { SeoService } from '@app/services/seo.service'; +import { UniverseApiService } from '@app/universe/universe-api.service'; +import { UniverseLocalService } from '@app/universe/universe-local.service'; +import { PulseEvent, PulseState, UniversePulseService } from '@app/universe/universe-pulse.service'; +import { ProtocolCopy, protocolCopy } from '@app/universe/universe-protocol-copy'; +import { + ExplorerProtocolDefinition, + ProtocolCoverage, + SourceEntry, +} from '@app/universe/universe.types'; +import { shortenIdentifier } from '@app/universe/universe-evidence'; + +interface ProtocolDetailViewModel { + readonly kind: 'loading' | 'ready' | 'missing' | 'error'; + readonly protocol?: ExplorerProtocolDefinition; + readonly copy?: ProtocolCopy; + readonly source?: SourceEntry | null; + readonly live?: boolean; + readonly onThisChain?: boolean; + readonly pulse?: PulseState; + readonly events?: readonly PulseEvent[]; + readonly pinned?: boolean; +} + +/** + * One protocol, explained and evidenced. + * + * The page has to be equally clear when a protocol is fully supported and when + * it is not. A registry entry with no running authority is described as + * exactly that, and never dressed up as live coverage. + */ +@Component({ + selector: 'app-protocol-detail', + templateUrl: './protocol-detail.component.html', + styleUrls: ['./protocol-detail.component.scss'], + standalone: false, + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class ProtocolDetailComponent implements OnInit, OnDestroy { + vm$: Observable; + readonly shorten = shortenIdentifier; + readonly notConfiguredLabel = $localize`:@@universe.detail.authority-none:Not configured here`; + + constructor( + private route: ActivatedRoute, + private api: UniverseApiService, + private pulse: UniversePulseService, + private local: UniverseLocalService, + private seo: SeoService, + ) {} + + ngOnInit(): void { + this.pulse.start(); + + const sources$ = this.api.getSources$().pipe( + map((response) => response.sources || []), + catchError(() => of([] as SourceEntry[])), + ); + + // The protocol itself resolves once per navigation. Title and history are + // recorded there, not in the live stream below, so a ticking pulse never + // re-runs a page-level side effect. + const protocol$ = this.route.paramMap.pipe( + switchMap((params) => { + const id = (params.get('id') || '').toLowerCase(); + return this.api.getProtocols$().pipe( + map((registry) => findProtocol(registry.protocols || [], id)), + ); + }), + tap((protocol) => { + if (!protocol) {return;} + this.seo.setTitle(protocol.displayName); + this.local.recordVisit({ + kind: 'protocol', + value: protocol.id, + path: `/protocols/${protocol.id}`, + label: protocol.displayName, + }); + }), + shareReplay({ bufferSize: 1, refCount: true }), + ); + + this.vm$ = protocol$.pipe( + switchMap((protocol) => { + if (!protocol) { + return of({ kind: 'missing' }); + } + return combineLatest([ + sources$, + this.pulse.state$, + this.local.preferences$, + ]).pipe( + map(([sources, pulse, preferences]): ProtocolDetailViewModel => { + return { + kind: 'ready', + protocol, + copy: protocolCopy(protocol.id, protocol.family), + source: sources.find((entry) => entry.authorityId === protocol.indexerAuthority) ?? null, + live: isLive(protocol), + onThisChain: protocol.chain === 'bitcoin', + pulse, + events: pulse.recent.filter((event) => event.protocolIds.includes(protocol.id)), + pinned: preferences.pinnedProtocols.includes(protocol.id), + }; + }), + catchError(() => of({ kind: 'error' })), + ); + }), + ); + } + + ngOnDestroy(): void { + this.pulse.stop(); + } + + togglePin(protocolId: string): void { + this.local.togglePinnedProtocol(protocolId); + } + + statusLabel(protocol: ExplorerProtocolDefinition): string { + switch (normalizeStatus(protocol)) { + case 'production verified': + case 'verified read only': + return $localize`:@@universe.detail.status-live:Readable in this explorer`; + case 'blocked': + return $localize`:@@universe.detail.status-blocked:Not readable here yet`; + case 'intentionally disabled': + return $localize`:@@universe.detail.status-disabled:Deliberately turned off`; + default: + return $localize`:@@universe.detail.status-unknown:Support status unknown`; + } + } + + statusTone(protocol: ExplorerProtocolDefinition): string { + return isLive(protocol) ? 'proven' : 'partial'; + } + + /** Says what is actually missing, so a blocked entry is never a mystery. */ + limitation(vm: ProtocolDetailViewModel): string | null { + if (!vm.onThisChain) { + return $localize`:@@universe.detail.other-chain:This protocol lives on ${vm.protocol.chain}:chain:, which this explorer does not serve. It is listed so the registry stays complete, not because it is readable here.`; + } + if (vm.live) {return null;} + if (!vm.source || vm.source.status === 'unconfigured') { + return $localize`:@@universe.detail.no-authority:No first-party authority for this protocol is configured in this deployment, so the explorer makes no claim about it. Nothing is inferred from transaction shape to fill the gap.`; + } + if (vm.source.status === 'unreachable') { + return $localize`:@@universe.detail.authority-unreachable:The authority for this protocol is configured but not answering, so no protocol state is shown for it.`; + } + return $localize`:@@universe.detail.adapter-pending:The authority is reachable, but the explorer's reader for this protocol is not finished, so its state is not shown yet.`; + } + + coverageLabel(protocol: ExplorerProtocolDefinition): string | null { + const coverage = protocol.coverage; + if (!coverage) {return null;} + if (typeof coverage === 'string') {return coverage;} + return (coverage as ProtocolCoverage).state ?? null; + } + + liveCount(vm: ProtocolDetailViewModel): number { + return vm.pulse?.protocolCounts.get(vm.protocol.id) ?? 0; + } + + trackByEvent(index: number, event: PulseEvent): string { + return event.txid; + } +} + +function normalizeStatus(protocol: ExplorerProtocolDefinition): string { + return (protocol.releaseStatus || '').toLowerCase().replace(/[_-]+/g, ' ').trim(); +} + +function isLive(protocol: ExplorerProtocolDefinition): boolean { + const status = normalizeStatus(protocol); + return status === 'verified read only' || status === 'production verified'; +} + +/** Matches on id first, then on any alias, so old links keep working. */ +export function findProtocol( + protocols: readonly ExplorerProtocolDefinition[], + id: string, +): ExplorerProtocolDefinition | null { + if (!id) {return null;} + const exact = protocols.find((protocol) => protocol.id === id); + if (exact) {return exact;} + return protocols.find((protocol) => (protocol.aliases || []).includes(id)) ?? null; +} diff --git a/frontend/src/app/universe/protocol-directory/protocol-directory.component.scss b/frontend/src/app/universe/protocol-directory/protocol-directory.component.scss index c82f35cf343..236a2cb675f 100644 --- a/frontend/src/app/universe/protocol-directory/protocol-directory.component.scss +++ b/frontend/src/app/universe/protocol-directory/protocol-directory.component.scss @@ -74,18 +74,35 @@ .protocol-state { display: flex; + // Three chips do not fit beside a protocol name on a narrow screen, and + // without wrapping they simply left the viewport. They wrap now, and the + // row grows instead of hiding its own state. + flex-wrap: wrap; align-items: center; - gap: 0.5rem; + gap: 0.35rem 0.5rem; + min-width: 0; + } + } + + @media (max-width: 575px) { + .protocol-row { + align-items: flex-start; + flex-direction: column; + + .protocol-state { + width: 100%; + } } } .state-chip { display: inline-block; + max-width: 100%; + overflow-wrap: anywhere; padding: 0.15em 0.6em; border-radius: 0.75rem; font-size: 0.75rem; font-weight: 600; - white-space: nowrap; border: 1px solid var(--transparent-fg); color: var(--fg); background-color: var(--box-bg); diff --git a/frontend/src/app/universe/protocol-strip/protocol-strip.component.html b/frontend/src/app/universe/protocol-strip/protocol-strip.component.html new file mode 100644 index 00000000000..0a2ba5758e6 --- /dev/null +++ b/frontend/src/app/universe/protocol-strip/protocol-strip.component.html @@ -0,0 +1,36 @@ +
    +
    +
    Universe protocol activity
    + Open live feed +
    + +

    + + Seen in the last {{ vm.checked }} mempool transactions checked. + + + + Reading arriving transactions against {{ vm.supportedCount }} supported protocols. + + +

    + + +

    + The asset authority is not answering, so protocol activity is not shown. +

    +
    + + + + + All protocols and their authorities + +
    diff --git a/frontend/src/app/universe/protocol-strip/protocol-strip.component.scss b/frontend/src/app/universe/protocol-strip/protocol-strip.component.scss new file mode 100644 index 00000000000..bf397dda99e --- /dev/null +++ b/frontend/src/app/universe/protocol-strip/protocol-strip.component.scss @@ -0,0 +1,82 @@ +@use '../universe-tokens' as u; + +:host { + @include u.universe-protocol-tokens; + @include u.universe-state-tokens; + + display: block; +} + +.universe-strip { + padding-top: 0.25rem; +} + +.strip-head { + display: flex; + flex-wrap: wrap; + align-items: baseline; + justify-content: space-between; + gap: 0.5rem; +} + +.strip-link { + font-size: 0.85rem; +} + +.strip-note { + margin: 0.35rem 0 0.75rem; + font-size: 0.85rem; + color: var(--transparent-fg, #a8b0c4); + + &.warning { + color: var(--universe-state-partial); + } +} + +.strip-list { + display: flex; + flex-wrap: wrap; + gap: 0.5rem; + list-style: none; + margin: 0 0 0.75rem; + padding: 0; + + a { + display: inline-flex; + align-items: baseline; + gap: 0.45rem; + padding: 0.25em 0.65em; + border: 1px solid rgba(255, 255, 255, 0.14); + border-radius: 0.25rem; + min-height: 32px; + + &:hover, + &:focus-visible { + border-color: var(--universe-protocol-runes); + } + + @include u.universe-motion; + } +} + +.strip-name { + font-size: 0.8rem; + text-transform: uppercase; + letter-spacing: 0.05em; +} + +.strip-count { + font-variant-numeric: tabular-nums; + font-weight: 700; + color: var(--universe-protocol-runes); + + // A zero is a real measurement, not a failure, so it stays legible but quiet. + &.zero { + color: var(--transparent-fg, #a8b0c4); + font-weight: 400; + } +} + +.strip-all { + font-size: 0.85rem; +} diff --git a/frontend/src/app/universe/protocol-strip/protocol-strip.component.ts b/frontend/src/app/universe/protocol-strip/protocol-strip.component.ts new file mode 100644 index 00000000000..89391541cc3 --- /dev/null +++ b/frontend/src/app/universe/protocol-strip/protocol-strip.component.ts @@ -0,0 +1,96 @@ +import { ChangeDetectionStrategy, Component, OnDestroy, OnInit } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { RouterModule } from '@angular/router'; +import { Observable, catchError, combineLatest, map, of } from 'rxjs'; +import { UniverseApiService } from '@app/universe/universe-api.service'; +import { PulseState, UniversePulseService } from '@app/universe/universe-pulse.service'; +import { ExplorerProtocolDefinition, ProtocolsResponse } from '@app/universe/universe.types'; + +interface StripEntry { + readonly protocolId: string; + readonly displayName: string; + readonly count: number; +} + +interface StripViewModel { + readonly entries: readonly StripEntry[]; + readonly checked: number; + readonly supportedCount: number; + readonly authorityAnswering: boolean; +} + +/** + * The homepage answer to "what else does this explorer see". + * + * It is deliberately small: a first-time visitor should learn within a glance + * that this explorer reads Bitcoin protocol assets, not read a dashboard about + * it. Counts come from the same live sample the pulse page publishes, with the + * same denominator, so the number on the homepage and the number on the pulse + * page can never disagree. + */ +@Component({ + selector: 'app-universe-protocol-strip', + standalone: true, + imports: [CommonModule, RouterModule], + templateUrl: './protocol-strip.component.html', + styleUrls: ['./protocol-strip.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class ProtocolStripComponent implements OnInit, OnDestroy { + vm$: Observable; + + constructor( + private api: UniverseApiService, + private pulse: UniversePulseService, + ) {} + + ngOnInit(): void { + this.pulse.start(); + + const registry$ = this.api.getProtocols$().pipe( + catchError(() => of({ protocols: [] } as unknown as ProtocolsResponse)), + ); + + this.vm$ = combineLatest([registry$, this.pulse.state$]).pipe( + map(([registry, pulse]): StripViewModel => { + const supported = (registry.protocols || []).filter(isSupported); + return { + supportedCount: supported.length, + checked: pulse.checked, + authorityAnswering: pulse.authorityAnswering, + entries: stripEntries(supported, pulse), + }; + }), + ); + } + + ngOnDestroy(): void { + this.pulse.stop(); + } + + trackByEntry(index: number, entry: StripEntry): string { + return entry.protocolId; + } +} + +function isSupported(protocol: ExplorerProtocolDefinition): boolean { + const status = (protocol.releaseStatus || '').toLowerCase().replace(/[_-]+/g, ' ').trim(); + return ( + protocol.chain === 'bitcoin' && + (status === 'verified read only' || status === 'production verified') + ); +} + +/** Supported protocols, busiest first, each with its exact live count. */ +export function stripEntries( + supported: readonly ExplorerProtocolDefinition[], + pulse: PulseState, +): StripEntry[] { + return supported + .map((protocol) => ({ + protocolId: protocol.id, + displayName: protocol.shortName || protocol.displayName || protocol.id, + count: pulse.protocolCounts.get(protocol.id) ?? 0, + })) + .sort((a, b) => b.count - a.count || a.displayName.localeCompare(b.displayName)); +} diff --git a/frontend/src/app/universe/pulse/pulse.component.html b/frontend/src/app/universe/pulse/pulse.component.html new file mode 100644 index 00000000000..c429c1f5d8a --- /dev/null +++ b/frontend/src/app/universe/pulse/pulse.component.html @@ -0,0 +1,82 @@ +
    + +
    +

    Live protocol activity

    +

    + Transactions arriving in the mempool right now, checked against the asset + authority and grouped by what they actually do. +

    +
    + +
    +

    How this is counted

    +

    + Since you opened this page, {{ vm.pulse.checked }} transactions were checked and + {{ vm.pulse.withAssets }} of them carried a supported asset. A protocol's share + below is the number of those transactions it appeared in, divided by the number + checked. Nothing is weighted, smoothed, or predicted. +

    +

    + Sampling stopped at this page's limit. Reload to start a new sample. +

    +

    + The asset authority stopped answering. The tally below is frozen at the last + transaction it confirmed, and nothing new is being claimed. +

    +
    + +
    +

    Protocol mix

    + +

    + Waiting for the first transactions to arrive. +

    +

    + None of the {{ vm.pulse.checked }} transactions checked so far carried a supported asset. +

    + + +
    + +
    +

    Recent protocol transactions

    + +

    + Nothing yet. Transactions appear here the moment the authority confirms what they carry. +

    + + +
    + +
    +

    Authorities behind this page

    +

    + {{ readySourceCount(sources) }} of {{ sources.length }} configured authorities are answering. + Which protocols each one covers is on the protocols page. +

    + See every protocol and its authority +
    + +
    diff --git a/frontend/src/app/universe/pulse/pulse.component.scss b/frontend/src/app/universe/pulse/pulse.component.scss new file mode 100644 index 00000000000..3f1b468c28a --- /dev/null +++ b/frontend/src/app/universe/pulse/pulse.component.scss @@ -0,0 +1,170 @@ +@use '../universe-tokens' as u; + +:host { + @include u.universe-protocol-tokens; + @include u.universe-state-tokens; + + display: block; +} + +.universe-pulse { + padding: 1.25rem 0 3rem; +} + +.page-head { + margin-bottom: 1rem; + + h1 { + font-size: 1.5rem; + margin: 0; + } + + .lede { + margin: 0.35rem 0 0; + color: var(--transparent-fg, #a8b0c4); + max-width: 60ch; + } +} + +.panel { + @include u.universe-surface; + + padding: 1rem; + margin-bottom: 0.75rem; + + h2 { + font-size: 1rem; + margin: 0 0 0.6rem; + } + + p { + margin: 0 0 0.5rem; + max-width: 72ch; + + &:last-child { margin-bottom: 0; } + } +} + +.method .warning { + color: var(--universe-state-partial); +} + +.identifier { + @include u.universe-identifier; +} + +.universe-chip { + @include u.universe-chip; +} + +.empty { + color: var(--transparent-fg, #a8b0c4); +} + +.share-list { + list-style: none; + margin: 0; + padding: 0; + + li { + display: grid; + grid-template-columns: minmax(6rem, 10rem) 1fr minmax(6rem, max-content); + align-items: center; + gap: 0.75rem; + padding: 0.35rem 0; + } +} + +.share-bar { + height: 0.5rem; + border-radius: 0.25rem; + background: rgba(255, 255, 255, 0.08); + overflow: hidden; + + .fill { + display: block; + height: 100%; + min-width: 2px; + background: var(--universe-protocol-runes); + + @include u.universe-motion(width, 400ms); + } +} + +.share-count { + font-variant-numeric: tabular-nums; + font-size: 0.85rem; + color: var(--transparent-fg, #a8b0c4); + text-align: right; +} + +.event-list { + list-style: none; + margin: 0; + padding: 0; +} + +.event { + display: grid; + grid-template-columns: minmax(9rem, max-content) minmax(6rem, 1fr) minmax(6rem, 1fr) max-content; + align-items: center; + gap: 0.5rem 0.75rem; + padding: 0.4rem 0; + border-top: 1px solid rgba(255, 255, 255, 0.05); + + &:first-child { + border-top: 0; + // A new row is a real event, so it earns a brief entrance. Nothing moves + // afterwards, so reading a row is never a moving target. + animation: universe-pulse-in 260ms ease-out; + } +} + +@keyframes universe-pulse-in { + from { opacity: 0; transform: translateY(-3px); } + to { opacity: 1; transform: none; } +} + +@media (prefers-reduced-motion: reduce) { + .event:first-child { animation: none; } +} + +.protocol-tag { + display: inline-block; + margin-right: 0.35rem; + font-size: 0.8rem; + text-transform: uppercase; + letter-spacing: 0.04em; +} + +.event-action { + font-size: 0.85rem; + color: var(--transparent-fg, #a8b0c4); + overflow-wrap: anywhere; +} + +@media (max-width: 767px) { + .share-list li { + grid-template-columns: 1fr max-content; + grid-template-areas: + 'name count' + 'bar bar'; + + .share-name { grid-area: name; } + .share-count { grid-area: count; } + .share-bar { grid-area: bar; } + } + + .event { + grid-template-columns: 1fr max-content; + grid-template-areas: + 'txid status' + 'protocols protocols' + 'action action'; + + .event-txid { grid-area: txid; } + .universe-chip { grid-area: status; } + .event-protocols { grid-area: protocols; } + .event-action { grid-area: action; } + } +} diff --git a/frontend/src/app/universe/pulse/pulse.component.ts b/frontend/src/app/universe/pulse/pulse.component.ts new file mode 100644 index 00000000000..e549878eb7d --- /dev/null +++ b/frontend/src/app/universe/pulse/pulse.component.ts @@ -0,0 +1,161 @@ +import { ChangeDetectionStrategy, Component, OnDestroy, OnInit } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { RouterModule } from '@angular/router'; +import { Observable, catchError, combineLatest, map, of } from 'rxjs'; +import { SeoService } from '@app/services/seo.service'; +import { WebsocketService } from '@app/services/websocket.service'; +import { UniverseApiService } from '@app/universe/universe-api.service'; +import { PulseEvent, PulseState, UniversePulseService } from '@app/universe/universe-pulse.service'; +import { + ExplorerProtocolDefinition, + ProtocolsResponse, + SourceEntry, + SourcesResponse, +} from '@app/universe/universe.types'; +import { shortenIdentifier } from '@app/universe/universe-evidence'; + +interface ProtocolShare { + readonly protocolId: string; + readonly displayName: string; + readonly count: number; + /** Whole percent of checked transactions. Never rounded up from zero. */ + readonly percent: number; +} + +interface PulseViewModel { + readonly pulse: PulseState; + readonly shares: readonly ProtocolShare[]; + readonly names: ReadonlyMap; + readonly sources: readonly SourceEntry[] | null; +} + +/** + * Live protocol activity, measured rather than asserted. + * + * The page states exactly what it sampled and how it counted, because a + * "trending protocol" that cannot be reproduced from published numbers is + * decoration. Everything shown here is derived from transactions the asset + * authority answered for since the page opened. + */ +@Component({ + selector: 'app-universe-pulse', + standalone: true, + imports: [CommonModule, RouterModule], + templateUrl: './pulse.component.html', + styleUrls: ['./pulse.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class PulseComponent implements OnInit, OnDestroy { + vm$: Observable; + readonly shorten = shortenIdentifier; + + constructor( + private pulse: UniversePulseService, + private api: UniverseApiService, + private websocketService: WebsocketService, + private seo: SeoService, + ) {} + + ngOnInit(): void { + this.seo.setTitle('Live protocol activity'); + // The pulse reads the same mempool feed the dashboard uses, so the socket + // subscription is the ordinary one, not a new channel. + this.websocketService.want(['blocks', 'stats', 'mempool-blocks']); + this.pulse.start(); + + const names$ = this.api.getProtocols$().pipe( + map((response: ProtocolsResponse) => nameIndex(response.protocols || [])), + catchError(() => of(new Map())), + ); + const sources$ = this.api.getSources$().pipe( + map((response: SourcesResponse) => response.sources || []), + catchError(() => of(null)), + ); + + this.vm$ = combineLatest([this.pulse.state$, names$, sources$]).pipe( + map(([pulse, names, sources]): PulseViewModel => ({ + pulse, + names, + sources, + shares: sharesOf(pulse, names), + })), + ); + } + + ngOnDestroy(): void { + this.pulse.stop(); + } + + actionSummary(event: PulseEvent): string { + if (!event.actions?.length) { + return $localize`:@@universe.pulse.holds-assets:Moves assets`; + } + const types = [...new Set(event.actions.map((action) => action.actionType).filter(Boolean))]; + return types.join(', '); + } + + statusLabel(event: PulseEvent): string { + switch (event.status) { + case 'mempool-candidate': + return $localize`:@@universe.pulse.status-pending:Pending`; + case 'confirmed': + return $localize`:@@universe.pulse.status-confirmed:Confirmed`; + case 'replaced': + return $localize`:@@universe.pulse.status-replaced:Replaced`; + case 'orphaned': + return $localize`:@@universe.pulse.status-orphaned:Orphaned`; + default: + return $localize`:@@universe.pulse.status-enriching:Reading evidence`; + } + } + + statusTone(event: PulseEvent): string { + switch (event.status) { + case 'confirmed': return 'proven'; + case 'mempool-candidate': return 'pending'; + case 'replaced': + case 'orphaned': return 'unavailable'; + default: return 'partial'; + } + } + + readySourceCount(sources: readonly SourceEntry[] | null): number { + return (sources || []).filter((source) => source.ready).length; + } + + trackByShare(index: number, share: ProtocolShare): string { + return share.protocolId; + } + + trackByEvent(index: number, event: PulseEvent): string { + return event.txid; + } +} + +function nameIndex(protocols: readonly ExplorerProtocolDefinition[]): Map { + const names = new Map(); + for (const protocol of protocols) { + names.set(protocol.id, protocol.shortName || protocol.displayName || protocol.id); + } + return names; +} + +/** + * Percentages are floored, so a protocol seen in a handful of transactions + * reads as the small share it is instead of being rounded up into significance. + */ +export function sharesOf( + pulse: PulseState, + names: ReadonlyMap, +): ProtocolShare[] { + const shares: ProtocolShare[] = []; + for (const [protocolId, count] of pulse.protocolCounts) { + shares.push({ + protocolId, + count, + displayName: names.get(protocolId) || protocolId, + percent: pulse.checked > 0 ? Math.floor((count * 100) / pulse.checked) : 0, + }); + } + return shares.sort((a, b) => b.count - a.count || a.protocolId.localeCompare(b.protocolId)); +} diff --git a/frontend/src/app/universe/rune/rune.component.html b/frontend/src/app/universe/rune/rune.component.html new file mode 100644 index 00000000000..37769290784 --- /dev/null +++ b/frontend/src/app/universe/rune/rune.component.html @@ -0,0 +1,150 @@ +
    + +
    +
    +

    Rune

    +

    {{ state.reference }}

    +
    + +
    + + + +
    +

    +

    +
    + +
    +

    That is not a rune reference

    +

    + Use a rune name in capital letters, with or without spacers, or a rune id + written as the etching block and index. +

    +
    + +
    +

    No such rune

    +

    {{ statusMessage(state.result?.status) }}

    +

    + As of block {{ checkpoint.heightAtomic }} +

    +
    + +
    +

    The asset authority did not answer

    +

    {{ statusMessage(state.result?.status) }}

    +
    + + + +
    +

    + {{ state.result.value.symbol }} + {{ state.result.value.spacedRune }} +

    +
    +
    Rune id
    +
    {{ state.result.value.id }}
    + + +
    Rune number
    +
    {{ number }}
    +
    + + +
    Etched in block
    +
    {{ block }}
    +
    + + +
    Etching transaction
    +
    {{ txid }}
    +
    + + +
    Etched at
    +
    {{ utc(timestamp) }}
    +
    + +
    Divisibility
    +
    {{ state.result.value.divisibilityAtomic }}
    +
    +
    + +
    +

    Supply

    +
    +
    Mints so far
    +
    {{ amount(state.result.value.mintsAtomic) }}
    + +
    Premine
    +
    {{ scaled(state.result.value.premineAtomic, state.result.value) }}
    + +
    Burned
    +
    {{ scaled(state.result.value.burnedAtomic, state.result.value) }}
    +
    +
    + +
    +
    +

    Minting

    + + {{ mintStateLabel(state.result.value) }} + +
    + +

    {{ mintExplanation(state.result.value) }}

    + + +
    + +

    + + {{ amount(state.result.value.mintsAtomic) }} of {{ amount(terms.capAtomic) }} mints, {{ progress(state.result.value) }} percent + +

    +
    + +
    + +
    Amount per mint
    +
    {{ scaled(amountPerMint, state.result.value) }}
    +
    + + +
    Mint height window
    +
    {{ terms.heightStartAtomic || '-' }} to {{ terms.heightEndAtomic || '-' }}
    +
    + + +
    Mint offset window
    +
    {{ terms.offsetStartAtomic || '-' }} to {{ terms.offsetEndAtomic || '-' }}
    +
    +
    +
    +
    + +
    +

    Parent inscription

    + {{ parent }} +
    + +

    + + Proven by {{ state.result.authorityId }} at block {{ checkpoint.heightAtomic }}. + +

    + +
    +
    +
    diff --git a/frontend/src/app/universe/rune/rune.component.scss b/frontend/src/app/universe/rune/rune.component.scss new file mode 100644 index 00000000000..02cbcbba877 --- /dev/null +++ b/frontend/src/app/universe/rune/rune.component.scss @@ -0,0 +1,67 @@ +@use '../asset-page' as page; +@use '../universe-tokens' as u; + +:host { + @include page.universe-asset-page; + + .rune-name { + display: flex; + align-items: baseline; + gap: 0.5rem; + font-size: 1.25rem; + margin: 0 0 0.75rem; + overflow-wrap: anywhere; + + .symbol { + color: var(--universe-protocol-runes); + font-size: 1.4rem; + line-height: 1; + } + } + + .universe-chip { + @include u.universe-chip; + } + + .mint-head { + display: flex; + flex-wrap: wrap; + align-items: center; + gap: 0.5rem 0.75rem; + margin-bottom: 0.5rem; + + h2 { + margin: 0; + } + } + + .progress { + margin: 0.75rem 0; + } + + .progress-bar { + height: 0.6rem; + border-radius: 0.3rem; + background: rgba(255, 255, 255, 0.08); + overflow: hidden; + + .fill { + display: block; + height: 100%; + background: var(--universe-protocol-runes); + + @include u.universe-motion(width, 400ms); + } + } + + .progress-label { + margin: 0.4rem 0 0; + font-variant-numeric: tabular-nums; + font-size: 0.9rem; + } + + .supply dd, + .mint dd { + font-variant-numeric: tabular-nums; + } +} diff --git a/frontend/src/app/universe/rune/rune.component.ts b/frontend/src/app/universe/rune/rune.component.ts new file mode 100644 index 00000000000..b798806153c --- /dev/null +++ b/frontend/src/app/universe/rune/rune.component.ts @@ -0,0 +1,117 @@ +import { ChangeDetectionStrategy, Component, OnDestroy, OnInit } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { ActivatedRoute, RouterModule } from '@angular/router'; +import { Observable, Subscription, switchMap } from 'rxjs'; +import { SeoService } from '@app/services/seo.service'; +import { UniverseApiService } from '@app/universe/universe-api.service'; +import { UniverseLocalService } from '@app/universe/universe-local.service'; +import { BookmarkButtonComponent } from '@app/universe/bookmark-button/bookmark-button.component'; +import { OrdRuneView } from '@app/universe/universe.types'; +import { + AssetViewState, + applyDivisibility, + assetState$, + assetStatusMessage, + assetTone, + mintProgressPercent, + utcFromSeconds, +} from '@app/universe/asset-lookup'; +import { formatAtomicAmount, shortenIdentifier } from '@app/universe/universe-evidence'; + +/** + * One rune, with its mint terms and current progress stated exactly as the + * authority reports them. + * + * Mint progress is a real ratio out of a real cap. A rune with open terms has + * no progress and the page says so, rather than showing a bar that means + * nothing. + */ +@Component({ + selector: 'app-universe-rune', + standalone: true, + imports: [CommonModule, RouterModule, BookmarkButtonComponent], + templateUrl: './rune.component.html', + styleUrls: ['./rune.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class RuneComponent implements OnInit, OnDestroy { + state$: Observable>; + + readonly shorten = shortenIdentifier; + readonly statusMessage = assetStatusMessage; + readonly tone = assetTone; + readonly utc = utcFromSeconds; + readonly amount = formatAtomicAmount; + + private visitSubscription?: Subscription; + + constructor( + private route: ActivatedRoute, + private api: UniverseApiService, + private local: UniverseLocalService, + private seo: SeoService, + ) {} + + ngOnInit(): void { + this.state$ = this.route.paramMap.pipe( + switchMap((params) => { + const reference = (params.get('reference') || '').trim(); + this.seo.setTitle(`Rune ${reference}`); + return assetState$(reference, this.api.getRune$(reference)); + }), + ); + + this.visitSubscription = this.state$.subscribe((state) => { + if (state.kind !== 'ready' || !state.result?.value) {return;} + const rune = state.result.value; + this.local.recordVisit({ + kind: 'rune', + value: rune.rune, + path: `/rune/${rune.rune}`, + label: rune.spacedRune, + }); + }); + } + + ngOnDestroy(): void { + this.visitSubscription?.unsubscribe(); + } + + /** Supply figures respect the rune's own divisibility, never a float. */ + scaled(atomic: string, rune: OrdRuneView): string { + return applyDivisibility(atomic, rune.divisibilityAtomic); + } + + progress(rune: OrdRuneView): number | null { + return mintProgressPercent(rune.mintsAtomic, rune.terms?.capAtomic); + } + + mintStateLabel(rune: OrdRuneView): string { + return rune.mintable + ? $localize`:@@universe.rune.mintable:Open for minting` + : $localize`:@@universe.rune.closed:Closed to minting`; + } + + mintStateTone(rune: OrdRuneView): string { + return rune.mintable ? 'pending' : 'proven'; + } + + /** Explains why minting is closed only when the terms actually prove it. */ + mintExplanation(rune: OrdRuneView): string { + if (rune.mintable) { + return $localize`:@@universe.rune.mintable-detail:The authority reports this rune can still be minted at the block below.`; + } + if (!rune.terms) { + return $localize`:@@universe.rune.no-terms:This rune was etched without mint terms, so it was never open for public minting.`; + } + return $localize`:@@universe.rune.closed-detail:The authority reports this rune can no longer be minted at the block below.`; + } + + hasHeightWindow(rune: OrdRuneView): boolean { + return !!(rune.terms?.heightStartAtomic || rune.terms?.heightEndAtomic); + } + + hasOffsetWindow(rune: OrdRuneView): boolean { + return !!(rune.terms?.offsetStartAtomic || rune.terms?.offsetEndAtomic); + } +} diff --git a/frontend/src/app/universe/sat/sat.component.html b/frontend/src/app/universe/sat/sat.component.html new file mode 100644 index 00000000000..2152e0cbb99 --- /dev/null +++ b/frontend/src/app/universe/sat/sat.component.html @@ -0,0 +1,136 @@ +
    + +
    +
    +

    Satoshi

    +

    {{ state.reference }}

    +
    + +
    + + + +
    +

    +

    +
    + +
    +

    That is not a satoshi number

    +

    + A satoshi is addressed by its ordinal number, counted from the first + satoshi ever mined. +

    +
    + +
    +

    No such satoshi

    +

    {{ statusMessage(state.result?.status) }}

    +
    + +
    +

    The asset authority did not answer

    +

    {{ statusMessage(state.result?.status) }}

    +
    + + + +
    +

    {{ rarityLabel(state.result.value.rarity) }}

    +

    {{ rarityReason(state.result.value) }}

    +
    + +
    +
    +
    Ordinal number
    +
    {{ amount(state.result.value.numberAtomic) }}
    + + +
    Name
    +
    {{ name }}
    +
    + + +
    Decimal position
    +
    {{ decimal }}
    +
    + + +
    Degree
    +
    {{ degree }}
    +
    + + +
    Percentile of supply
    +
    {{ percentile }}
    +
    + + +
    Mined in block
    +
    {{ block }}
    +
    + + +
    Mined at
    +
    {{ utc(timestamp) }}
    +
    + + +
    Cycle
    +
    {{ cycle }}
    +
    + + +
    Epoch
    +
    {{ epoch }}
    +
    + + +
    Difficulty period
    +
    {{ period }}
    +
    +
    +
    + +
    +

    Where it sits now

    +
    + +
    Output
    +
    {{ state.result.value.satpoint }}
    +
    + + +
    Address
    +
    {{ address }}
    +
    +
    +

    + The authority did not report a current location for this satoshi. +

    +
    + +
    +

    Inscriptions on this satoshi

    + +
    + +

    + + Proven by {{ state.result.authorityId }} at block {{ checkpoint.heightAtomic }}. + +

    + +
    +
    +
    diff --git a/frontend/src/app/universe/sat/sat.component.scss b/frontend/src/app/universe/sat/sat.component.scss new file mode 100644 index 00000000000..7d600a000b7 --- /dev/null +++ b/frontend/src/app/universe/sat/sat.component.scss @@ -0,0 +1,44 @@ +@use '../asset-page' as page; + +:host { + @include page.universe-asset-page; + + .rarity { + border-left: 3px solid var(--universe-state-neutral); + + h2 { + font-size: 1.15rem; + text-transform: none; + margin-bottom: 0.4rem; + } + + // Rarity earns a color only when it is above common, so the page never + // dresses an ordinary satoshi up as a find. + &.rarity-uncommon, + &.rarity-rare, + &.rarity-epic, + &.rarity-legendary, + &.rarity-mythic { + border-left-color: var(--universe-protocol-ordinals); + + h2 { color: var(--universe-protocol-ordinals); } + } + } + + .identity dd, + .inscriptions li { + font-variant-numeric: tabular-nums; + } + + .inscriptions ul { + list-style: none; + margin: 0; + padding: 0; + + li { padding: 0.15rem 0; } + } + + .empty { + color: var(--transparent-fg, #a8b0c4); + } +} diff --git a/frontend/src/app/universe/sat/sat.component.ts b/frontend/src/app/universe/sat/sat.component.ts new file mode 100644 index 00000000000..80194495778 --- /dev/null +++ b/frontend/src/app/universe/sat/sat.component.ts @@ -0,0 +1,115 @@ +import { ChangeDetectionStrategy, Component, OnDestroy, OnInit } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { ActivatedRoute, RouterModule } from '@angular/router'; +import { Observable, Subscription, switchMap } from 'rxjs'; +import { SeoService } from '@app/services/seo.service'; +import { UniverseApiService } from '@app/universe/universe-api.service'; +import { UniverseLocalService } from '@app/universe/universe-local.service'; +import { BookmarkButtonComponent } from '@app/universe/bookmark-button/bookmark-button.component'; +import { OrdSatView } from '@app/universe/universe.types'; +import { + AssetViewState, + assetState$, + assetStatusMessage, + assetTone, + utcFromSeconds, +} from '@app/universe/asset-lookup'; +import { formatAtomicAmount, shortenIdentifier } from '@app/universe/universe-evidence'; + +/** + * One satoshi. + * + * Rarity here is not an opinion. It comes from where the satoshi sits in + * Bitcoin's own issuance schedule, so the page states the rule that makes it + * rare rather than asserting the label on its own. + */ +@Component({ + selector: 'app-universe-sat', + standalone: true, + imports: [CommonModule, RouterModule, BookmarkButtonComponent], + templateUrl: './sat.component.html', + styleUrls: ['./sat.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class SatComponent implements OnInit, OnDestroy { + state$: Observable>; + + readonly shorten = shortenIdentifier; + readonly statusMessage = assetStatusMessage; + readonly tone = assetTone; + readonly utc = utcFromSeconds; + readonly amount = formatAtomicAmount; + + private visitSubscription?: Subscription; + + constructor( + private route: ActivatedRoute, + private api: UniverseApiService, + private local: UniverseLocalService, + private seo: SeoService, + ) {} + + ngOnInit(): void { + this.state$ = this.route.paramMap.pipe( + switchMap((params) => { + const reference = (params.get('reference') || '').trim(); + this.seo.setTitle(`Sat ${reference}`); + return assetState$(reference, this.api.getSat$(reference)); + }), + ); + + this.visitSubscription = this.state$.subscribe((state) => { + if (state.kind !== 'ready' || !state.result?.value) {return;} + const sat = state.result.value; + this.local.recordVisit({ + kind: 'sat', + value: sat.numberAtomic, + path: `/sat/${sat.numberAtomic}`, + label: sat.name ? `Sat ${sat.name}` : `Sat ${sat.numberAtomic}`, + }); + }); + } + + ngOnDestroy(): void { + this.visitSubscription?.unsubscribe(); + } + + rarityLabel(rarity: string): string { + switch (rarity) { + case 'mythic': return $localize`:@@universe.rarity.mythic:Mythic`; + case 'legendary': return $localize`:@@universe.rarity.legendary:Legendary`; + case 'epic': return $localize`:@@universe.rarity.epic:Epic`; + case 'rare': return $localize`:@@universe.rarity.rare:Rare`; + case 'uncommon': return $localize`:@@universe.rarity.uncommon:Uncommon`; + case 'common': return $localize`:@@universe.rarity.common:Common`; + default: return rarity; + } + } + + /** The rule that produces this rarity, so the label is checkable. */ + rarityReason(sat: OrdSatView): string { + switch (sat.rarity) { + case 'mythic': + return $localize`:@@universe.sat.reason-mythic:The first satoshi of the genesis block. There is exactly one.`; + case 'legendary': + return $localize`:@@universe.sat.reason-legendary:The first satoshi of a cycle, which happens every six halvings.`; + case 'epic': + return $localize`:@@universe.sat.reason-epic:The first satoshi of a halving epoch.`; + case 'rare': + return $localize`:@@universe.sat.reason-rare:The first satoshi of a difficulty adjustment period.`; + case 'uncommon': + return $localize`:@@universe.sat.reason-uncommon:The first satoshi of a block.`; + default: + return $localize`:@@universe.sat.reason-common:Not the first satoshi of any block, period, epoch, or cycle. Most satoshis are common.`; + } + } + + outpointRoute(satpoint: string | null): string[] | null { + if (!satpoint) {return null;} + const parts = satpoint.split(':'); + if (parts.length !== 3) {return null;} + const [txid, vout] = parts; + if (!/^[0-9a-f]{64}$/.test(txid) || !/^(0|[1-9][0-9]{0,9})$/.test(vout)) {return null;} + return ['/outpoint', txid, vout]; + } +} diff --git a/frontend/src/app/universe/saved/saved.component.html b/frontend/src/app/universe/saved/saved.component.html new file mode 100644 index 00000000000..a75b83c04f8 --- /dev/null +++ b/frontend/src/app/universe/saved/saved.component.html @@ -0,0 +1,84 @@ +
    + +
    +

    Saved in this browser

    +

    + This list lives only on this device. The explorer never sends it anywhere and + keeps no account for you. +

    +
    + +
    +

    Saved pages

    + +

    + Nothing saved yet. Use the save button on a transaction, output, address, or + protocol page and it appears here. +

    + + +
    + +
    +

    Recently viewed

    + +

    + Nothing viewed yet in this browser. +

    + + + + +
    + +
    +

    Pinned protocols

    + +
    + +
    +

    Forget everything

    +

    + Clears saved pages, recently viewed items, and pinned protocols from this + browser. It cannot be undone. +

    + + + +
    +

    Forget everything stored in this browser?

    + + +
    +
    + +
    diff --git a/frontend/src/app/universe/saved/saved.component.scss b/frontend/src/app/universe/saved/saved.component.scss new file mode 100644 index 00000000000..be596f3c9a3 --- /dev/null +++ b/frontend/src/app/universe/saved/saved.component.scss @@ -0,0 +1,93 @@ +@use '../universe-tokens' as u; + +:host { + @include u.universe-state-tokens; + + display: block; +} + +.universe-saved { + padding: 1.25rem 0 3rem; +} + +.page-head { + margin-bottom: 1rem; + + h1 { font-size: 1.5rem; margin: 0; } + + .lede { + margin: 0.35rem 0 0; + color: var(--transparent-fg, #a8b0c4); + max-width: 60ch; + } +} + +.panel { + @include u.universe-surface; + + padding: 1rem; + margin-bottom: 0.75rem; + + h2 { font-size: 1rem; margin: 0 0 0.6rem; } + p { margin: 0 0 0.5rem; max-width: 68ch; } +} + +.empty { color: var(--transparent-fg, #a8b0c4); } + +.entry-list { + list-style: none; + margin: 0 0 0.6rem; + padding: 0; + + li { + display: flex; + flex-wrap: wrap; + align-items: center; + gap: 0.5rem 0.75rem; + padding: 0.35rem 0; + border-top: 1px solid rgba(255, 255, 255, 0.05); + } + + li:first-child { border-top: 0; } +} + +.entry-kind { + min-width: 6.5rem; + font-size: 0.75rem; + text-transform: uppercase; + letter-spacing: 0.05em; + color: var(--transparent-fg, #a8b0c4); +} + +.entry-label { + flex: 1 1 12rem; + overflow-wrap: anywhere; +} + +button { + border-radius: 0.25rem; + border: 1px solid rgba(255, 255, 255, 0.18); + background: transparent; + color: var(--transparent-fg, #a8b0c4); + font-size: 0.85rem; + padding: 0.3em 0.75em; + min-height: 34px; + cursor: pointer; + + &:hover, + &:focus-visible { color: #fff; border-color: rgba(255, 255, 255, 0.4); } + + &.danger { + border-color: var(--universe-state-unavailable); + color: var(--universe-state-unavailable); + } +} + +.confirm { + display: flex; + flex-wrap: wrap; + align-items: center; + gap: 0.5rem; + + p { margin: 0 0.5rem 0 0; } +} diff --git a/frontend/src/app/universe/saved/saved.component.ts b/frontend/src/app/universe/saved/saved.component.ts new file mode 100644 index 00000000000..5db6a0e86c9 --- /dev/null +++ b/frontend/src/app/universe/saved/saved.component.ts @@ -0,0 +1,97 @@ +import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { RouterModule } from '@angular/router'; +import { Observable, combineLatest, map } from 'rxjs'; +import { SeoService } from '@app/services/seo.service'; +import { + UniverseEntry, + UniverseEntryKind, + UniverseLocalService, +} from '@app/universe/universe-local.service'; + +interface SavedViewModel { + readonly bookmarks: readonly UniverseEntry[]; + readonly recent: readonly UniverseEntry[]; + readonly pinnedProtocols: readonly string[]; +} + +/** + * Everything this browser remembers, in one place, with one button that + * forgets all of it. Nothing here was ever sent to a server, so this page is + * also the complete answer to "what does the explorer know about me". + */ +@Component({ + selector: 'app-universe-saved', + standalone: true, + imports: [CommonModule, RouterModule], + templateUrl: './saved.component.html', + styleUrls: ['./saved.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class SavedComponent implements OnInit { + vm$: Observable; + confirmingReset = false; + + constructor( + private local: UniverseLocalService, + private seo: SeoService, + ) {} + + ngOnInit(): void { + this.seo.setTitle('Saved in this browser'); + this.vm$ = combineLatest([ + this.local.bookmarks$, + this.local.recent$, + this.local.preferences$, + ]).pipe( + map(([bookmarks, recent, preferences]): SavedViewModel => ({ + bookmarks, + recent, + pinnedProtocols: preferences.pinnedProtocols, + })), + ); + } + + remove(entry: UniverseEntry): void { + this.local.removeBookmark(entry.kind as UniverseEntryKind, entry.value); + } + + clearRecent(): void { + this.local.clearRecent(); + } + + unpin(protocolId: string): void { + this.local.togglePinnedProtocol(protocolId); + } + + askReset(): void { + this.confirmingReset = true; + } + + cancelReset(): void { + this.confirmingReset = false; + } + + confirmReset(): void { + this.local.resetAll(); + this.confirmingReset = false; + } + + kindLabel(kind: string): string { + switch (kind) { + case 'transaction': return $localize`:@@universe.saved.kind-transaction:Transaction`; + case 'block': return $localize`:@@universe.saved.kind-block:Block`; + case 'address': return $localize`:@@universe.saved.kind-address:Address`; + case 'outpoint': return $localize`:@@universe.saved.kind-outpoint:Output`; + case 'inscription': return $localize`:@@universe.saved.kind-inscription:Inscription`; + case 'rune': return $localize`:@@universe.saved.kind-rune:Rune`; + case 'sat': return $localize`:@@universe.saved.kind-sat:Sat`; + case 'protocol': return $localize`:@@universe.saved.kind-protocol:Protocol`; + default: return kind; + } + } + + trackByEntry(index: number, entry: UniverseEntry): string { + return `${entry.kind}:${entry.value}`; + } +} diff --git a/frontend/src/app/universe/universe-api.service.ts b/frontend/src/app/universe/universe-api.service.ts index 8cf0c7d2aa3..46236a8d116 100644 --- a/frontend/src/app/universe/universe-api.service.ts +++ b/frontend/src/app/universe/universe-api.service.ts @@ -2,7 +2,25 @@ import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Observable, catchError, shareReplay, throwError } from 'rxjs'; import { StateService } from '@app/services/state.service'; -import { BackendInfo, ExplorerTransactionAssetFlow, ProtocolsResponse, SourcesResponse, StatusResponse } from '@app/universe/universe.types'; +import { + BackendInfo, + ExplorerTransactionAssetFlow, + OutpointBatchResponse, + OutpointEnrichment, + ProtocolsResponse, + SourcesResponse, + StatusResponse, + TransactionBatchResponse, + AssetLookupResult, + OrdBlockInscriptionsView, + OrdInscriptionView, + OrdRuneView, + OrdSatView, +} from '@app/universe/universe.types'; + +/** Server-side batch ceilings. Callers must not exceed them. */ +export const UNIVERSE_OUTPOINT_BATCH_LIMIT = 50; +export const UNIVERSE_TRANSACTION_BATCH_LIMIT = 25; @Injectable({ providedIn: 'root' @@ -61,4 +79,59 @@ export class UniverseApiService { this.apiBaseUrl + '/api/v1/universe/transactions/' + txid ); } + + /** + * Asset flows for up to {@link UNIVERSE_TRANSACTION_BATCH_LIMIT} transactions + * in one request. Batching is what keeps a block or a mempool page from + * issuing one request per transaction. + */ + getTransactionFlows$(txids: string[]): Observable { + return this.httpClient.post( + this.apiBaseUrl + '/api/v1/universe/transactions/batch', + { txids: txids.slice(0, UNIVERSE_TRANSACTION_BATCH_LIMIT) } + ); + } + + /** Assets attached to one outpoint, with the evidence behind the answer. */ + getOutpoint$(txid: string, vout: number | string): Observable { + return this.httpClient.get( + this.apiBaseUrl + '/api/v1/universe/outpoints/' + txid + '/' + vout + ); + } + + /** Assets attached to up to {@link UNIVERSE_OUTPOINT_BATCH_LIMIT} outpoints. */ + getOutpoints$(outpoints: string[]): Observable { + return this.httpClient.post( + this.apiBaseUrl + '/api/v1/universe/outpoints/batch', + { outpoints: outpoints.slice(0, UNIVERSE_OUTPOINT_BATCH_LIMIT) } + ); + } + + /** One inscription, addressed by id or by inscription number. */ + getInscription$(reference: string): Observable> { + return this.httpClient.get>( + this.apiBaseUrl + '/api/v1/universe/inscriptions/' + encodeURIComponent(reference) + ); + } + + /** One rune, addressed by name or by rune id. */ + getRune$(reference: string): Observable> { + return this.httpClient.get>( + this.apiBaseUrl + '/api/v1/universe/runes/' + encodeURIComponent(reference) + ); + } + + /** One satoshi, addressed by its ordinal number. */ + getSat$(reference: string): Observable> { + return this.httpClient.get>( + this.apiBaseUrl + '/api/v1/universe/sats/' + encodeURIComponent(reference) + ); + } + + /** Inscriptions revealed in one block. Paginated by the authority. */ + getBlockInscriptions$(height: number | string, page = 0): Observable> { + return this.httpClient.get>( + this.apiBaseUrl + '/api/v1/universe/blocks/' + height + '/inscriptions?page=' + page + ); + } } diff --git a/frontend/src/app/universe/universe-evidence.spec.ts b/frontend/src/app/universe/universe-evidence.spec.ts new file mode 100644 index 00000000000..c8c186adbe8 --- /dev/null +++ b/frontend/src/app/universe/universe-evidence.spec.ts @@ -0,0 +1,137 @@ +import { describe, expect, it } from 'vitest'; +import { + formatAtomicAmount, + groupPositionsByProtocol, + outpointEvidence, + shortenIdentifier, +} from '@app/universe/universe-evidence'; +import type { OutpointEnrichment } from '@app/universe/universe.types'; + +function enrichment(patch: Partial = {}): OutpointEnrichment { + return { + outpoint: `${'a'.repeat(64)}:0`, + status: 'ok', + positions: [], + coveredProtocolIds: ['ordinals'], + unknownAttachments: false, + checkpoint: null, + ...patch, + }; +} + +describe('outpointEvidence', () => { + it('calls a clean answer proven', () => { + const view = outpointEvidence(enrichment()); + expect(view.tone).toBe('proven'); + }); + + it('separates a proven empty output from a proven full one', () => { + const empty = outpointEvidence(enrichment()); + const full = outpointEvidence( + enrichment({ positions: [{ asset: { protocolId: 'runes' } }] as never }), + ); + expect(empty.tone).toBe('proven'); + expect(full.tone).toBe('proven'); + expect(empty.detail).not.toBe(full.detail); + }); + + it('downgrades to partial when attachments are unaccounted for', () => { + expect(outpointEvidence(enrichment({ unknownAttachments: true })).tone).toBe('partial'); + }); + + it('treats an outage as unavailable, never as an empty result', () => { + const view = outpointEvidence(enrichment({ status: 'unavailable' })); + expect(view.tone).toBe('unavailable'); + expect(view.detail.toLowerCase()).toContain('nothing is claimed'); + }); + + it('distinguishes an unconfigured deployment from an outage', () => { + const unconfigured = outpointEvidence(enrichment({ status: 'unconfigured' })); + const unavailable = outpointEvidence(enrichment({ status: 'unavailable' })); + expect(unconfigured.label).not.toBe(unavailable.label); + }); + + it('describes a coverage boundary as a boundary, not a failure', () => { + const view = outpointEvidence(enrichment({ status: 'not-indexed' })); + expect(view.tone).toBe('partial'); + expect(view.detail).toContain('keeps no inventory'); + }); + + it('says the chain moved when the read straddled a block', () => { + const view = outpointEvidence(enrichment({ status: 'stale' })); + expect(view.tone).toBe('partial'); + expect(view.label).toBeTruthy(); + }); + + it('refuses to trust a malformed answer', () => { + expect(outpointEvidence(enrichment({ status: 'malformed' })).tone).toBe('unavailable'); + }); +}); + +describe('groupPositionsByProtocol', () => { + it('handles no positions', () => { + expect(groupPositionsByProtocol([])).toEqual([]); + expect(groupPositionsByProtocol(undefined as never)).toEqual([]); + }); + + it('groups by protocol and sorts by id', () => { + const groups = groupPositionsByProtocol([ + { asset: { protocolId: 'runes' } }, + { asset: { protocolId: 'ordinals' } }, + { asset: { protocolId: 'runes' } }, + ] as never); + expect(groups.map((group) => group.protocolId)).toEqual(['ordinals', 'runes']); + expect(groups[1].positions).toHaveLength(2); + }); + + it('files a position with no protocol under unknown rather than dropping it', () => { + const groups = groupPositionsByProtocol([{ asset: undefined }] as never); + expect(groups[0].protocolId).toBe('unknown'); + }); +}); + +describe('formatAtomicAmount', () => { + it('groups thousands', () => { + expect(formatAtomicAmount('1234567')).toBe('1,234,567'); + }); + + it('applies decimals without floating point', () => { + expect(formatAtomicAmount('123456789', 8)).toBe('1.23456789'); + expect(formatAtomicAmount('100000000', 8)).toBe('1'); + expect(formatAtomicAmount('1', 8)).toBe('0.00000001'); + }); + + it('keeps precision far past the safe integer range', () => { + const huge = '340282366920938463463374607431768211455'; + expect(formatAtomicAmount(huge).replace(/,/g, '')).toBe(huge); + }); + + it('refuses anything that is not a non-negative integer string', () => { + expect(formatAtomicAmount('-1')).toBe(''); + expect(formatAtomicAmount('1.5')).toBe(''); + expect(formatAtomicAmount('007')).toBe(''); + expect(formatAtomicAmount(undefined as never)).toBe(''); + }); + + it('ignores an out-of-range divisibility rather than guessing', () => { + expect(formatAtomicAmount('1000', 99)).toBe('1,000'); + expect(formatAtomicAmount('1000', -1)).toBe('1,000'); + }); +}); + +describe('shortenIdentifier', () => { + it('leaves short values alone', () => { + expect(shortenIdentifier('abcdef')).toBe('abcdef'); + }); + + it('keeps both ends of a long identifier', () => { + const value = 'a'.repeat(30) + 'b'.repeat(30); + const short = shortenIdentifier(value, 6); + expect(short.startsWith('aaaaaa')).toBe(true); + expect(short.endsWith('bbbbbb')).toBe(true); + }); + + it('tolerates a missing value', () => { + expect(shortenIdentifier(undefined as never)).toBe(''); + }); +}); diff --git a/frontend/src/app/universe/universe-evidence.ts b/frontend/src/app/universe/universe-evidence.ts new file mode 100644 index 00000000000..0496693c034 --- /dev/null +++ b/frontend/src/app/universe/universe-evidence.ts @@ -0,0 +1,125 @@ +/** + * Shared evidence vocabulary. + * + * Every Universe surface has to say the same thing about the same state, or + * the product stops being trustworthy. These helpers are the single source of + * that wording. They are pure so they can be asserted directly in tests. + */ + +import { + ExplorerOutpointPosition, + OutpointEnrichment, + OutpointEnrichmentStatus, +} from '@app/universe/universe.types'; + +export type EvidenceTone = 'proven' | 'partial' | 'pending' | 'unavailable'; + +export interface EvidenceView { + readonly tone: EvidenceTone; + readonly label: string; + /** One sentence a non-expert can act on. */ + readonly detail: string; +} + +/** + * What an outpoint enrichment actually proves. + * + * The distinction that matters most: `ok` with no positions is a proven + * negative ("nothing is attached"), while `unavailable` is an absence of + * knowledge. Collapsing the two into an empty list would be a lie. + */ +export function outpointEvidence(result: OutpointEnrichment): EvidenceView { + switch (result.status as OutpointEnrichmentStatus) { + case 'ok': + if (result.unknownAttachments) { + return { + tone: 'partial', + label: $localize`:@@universe.outpoint.partial:Partly proven`, + detail: $localize`:@@universe.outpoint.partial-detail:The asset authority answered, but could not account for every attachment on this output.`, + }; + } + return { + tone: 'proven', + label: $localize`:@@universe.outpoint.proven:Proven`, + detail: result.positions.length + ? $localize`:@@universe.outpoint.proven-detail:The asset authority confirmed exactly what this output carries at the block below.` + : $localize`:@@universe.outpoint.proven-empty-detail:The asset authority confirmed this output carries no supported assets at the block below.`, + }; + case 'not-indexed': + return { + tone: 'partial', + label: $localize`:@@universe.outpoint.not-indexed:Outside coverage`, + detail: $localize`:@@universe.outpoint.not-indexed-detail:The asset authority keeps no inventory for this output, so what it carries is not proven here.`, + }; + case 'stale': + return { + tone: 'partial', + label: $localize`:@@universe.outpoint.stale:Chain moved`, + detail: $localize`:@@universe.outpoint.stale-detail:A new block arrived while this output was being read. Reload to get a single consistent answer.`, + }; + case 'unconfigured': + return { + tone: 'unavailable', + label: $localize`:@@universe.outpoint.unconfigured:Not configured`, + detail: $localize`:@@universe.outpoint.unconfigured-detail:This deployment has no asset authority configured, so protocol assets are not shown.`, + }; + case 'malformed': + return { + tone: 'unavailable', + label: $localize`:@@universe.outpoint.malformed:Unreadable answer`, + detail: $localize`:@@universe.outpoint.malformed-detail:The asset authority replied with something this explorer refuses to trust.`, + }; + default: + return { + tone: 'unavailable', + label: $localize`:@@universe.outpoint.unavailable:Authority unavailable`, + detail: $localize`:@@universe.outpoint.unavailable-detail:The asset authority could not be reached. Nothing is claimed about this output while that is true.`, + }; + } +} + +/** Groups positions by protocol so one output reads as a short list, not a table. */ +export interface ProtocolGroup { + readonly protocolId: string; + readonly positions: readonly ExplorerOutpointPosition[]; +} + +export function groupPositionsByProtocol( + positions: readonly ExplorerOutpointPosition[], +): ProtocolGroup[] { + const groups = new Map(); + for (const position of positions ?? []) { + const id = position.asset?.protocolId || 'unknown'; + if (!groups.has(id)) {groups.set(id, []);} + groups.get(id).push(position); + } + return [...groups.entries()] + .map(([protocolId, entries]) => ({ protocolId, positions: entries })) + .sort((a, b) => a.protocolId.localeCompare(b.protocolId)); +} + +/** + * Formats an atomic integer amount with a decimal point, without ever using + * floating point. Asset supplies exceed the safe integer range, so the whole + * pipeline keeps them as decimal strings and so does this. + */ +export function formatAtomicAmount(atomic: string, decimals = 0): string { + if (typeof atomic !== 'string' || !/^(0|[1-9][0-9]*)$/.test(atomic)) {return '';} + if (!Number.isInteger(decimals) || decimals <= 0 || decimals > 38) { + return groupDigits(atomic); + } + const padded = atomic.padStart(decimals + 1, '0'); + const whole = padded.slice(0, padded.length - decimals); + const fraction = padded.slice(padded.length - decimals).replace(/0+$/, ''); + return fraction ? `${groupDigits(whole)}.${fraction}` : groupDigits(whole); +} + +function groupDigits(value: string): string { + return value.replace(/\B(?=(\d{3})+(?!\d))/g, ','); +} + +/** Short, readable form of a 64 character identifier. */ +export function shortenIdentifier(value: string, keep = 8): string { + if (typeof value !== 'string' || value.length <= keep * 2 + 1) {return value ?? '';} + return `${value.slice(0, keep)}…${value.slice(-keep)}`; +} diff --git a/frontend/src/app/universe/universe-identifier.spec.ts b/frontend/src/app/universe/universe-identifier.spec.ts new file mode 100644 index 00000000000..59a28519a97 --- /dev/null +++ b/frontend/src/app/universe/universe-identifier.spec.ts @@ -0,0 +1,148 @@ +import { describe, expect, it } from 'vitest'; +import { + classifyUniverseQuery, + identifierKindLabel, + matchProtocols, +} from '@app/universe/universe-identifier'; + +const TXID = 'a'.repeat(64); +const PROTOCOLS = [ + { id: 'runes', aliases: ['rune', 'runes_native'], displayName: 'Runes', shortName: 'RUNES' }, + { id: 'ordinals', aliases: ['inscriptions'], displayName: 'Ordinals', shortName: 'Ordinals' }, + { id: 'rare_sats', aliases: ['rare-sats'], displayName: 'Rare Sats', shortName: 'Rare Sats' }, +]; + +describe('classifyUniverseQuery', () => { + it('returns nothing for an empty or oversized query', () => { + expect(classifyUniverseQuery('')).toEqual([]); + expect(classifyUniverseQuery(' ')).toEqual([]); + expect(classifyUniverseQuery('x'.repeat(201))).toEqual([]); + }); + + it('recognises an outpoint and routes to the output page', () => { + const [candidate] = classifyUniverseQuery(`${TXID}:3`); + expect(candidate.kind).toBe('outpoint'); + expect(candidate.route).toEqual(['/outpoint', TXID, '3']); + }); + + it('rejects an outpoint whose vout has a leading zero', () => { + const kinds = classifyUniverseQuery(`${TXID}:03`).map((c) => c.kind); + expect(kinds).not.toContain('outpoint'); + }); + + it('recognises an inscription id', () => { + const [candidate] = classifyUniverseQuery(`${TXID}i0`); + expect(candidate.kind).toBe('inscription-id'); + expect(candidate.route).toEqual(['/inscription', `${TXID}i0`]); + }); + + it('accepts an uppercase inscription id by normalising it', () => { + const [candidate] = classifyUniverseQuery(`${TXID.toUpperCase()}i7`); + expect(candidate.kind).toBe('inscription-id'); + expect(candidate.value).toBe(`${TXID}i7`); + }); + + it('never steals a bare integer from block height search', () => { + expect(classifyUniverseQuery('840000')).toEqual([]); + }); + + it('recognises an inscription number only when it is marked', () => { + const hashed = classifyUniverseQuery('#123'); + expect(hashed[0].kind).toBe('inscription-number'); + expect(hashed[0].value).toBe('123'); + + const cursed = classifyUniverseQuery('-45'); + expect(cursed[0].kind).toBe('inscription-number'); + expect(cursed[0].value).toBe('-45'); + }); + + it('recognises a rune name and normalises spacers away', () => { + const [candidate] = classifyUniverseQuery('UNCOMMON•GOODS'); + expect(candidate.kind).toBe('rune-name'); + expect(candidate.value).toBe('UNCOMMONGOODS'); + }); + + it('accepts a lowercase rune name and displays it uppercase', () => { + const [candidate] = classifyUniverseQuery('dogpepe'); + expect(candidate.kind).toBe('rune-name'); + expect(candidate.value).toBe('DOGPEPE'); + }); + + it('ignores rune names shorter than three letters', () => { + expect(classifyUniverseQuery('AB').map((c) => c.kind)).not.toContain('rune-name'); + }); + + it('recognises a rune id', () => { + const [candidate] = classifyUniverseQuery('840000:1'); + expect(candidate.kind).toBe('rune-id'); + expect(candidate.route).toEqual(['/rune', '840000:1']); + }); + + it('requires an explicit prefix for a satoshi', () => { + const [candidate] = classifyUniverseQuery('sat:1234567890'); + expect(candidate.kind).toBe('sat'); + expect(classifyUniverseQuery('1234567890')).toEqual([]); + }); + + it('refuses a satoshi number above the total supply', () => { + expect(classifyUniverseQuery('sat:2099999997690001')).toEqual([]); + }); + + it('ranks an exact identifier above a protocol name match', () => { + const candidates = classifyUniverseQuery('RUNES', PROTOCOLS); + // "RUNES" is both a plausible rune name and an exact protocol id, and the + // protocol is the more useful destination, so it must not be buried. + expect(candidates.some((c) => c.kind === 'protocol' && c.value === 'runes')).toBe(true); + }); + + it('sorts candidates by rank', () => { + const candidates = classifyUniverseQuery('ordinals', PROTOCOLS); + const ranks = candidates.map((c) => c.rank); + expect([...ranks].sort((a, b) => a - b)).toEqual(ranks); + }); +}); + +describe('matchProtocols', () => { + it('needs at least two characters', () => { + expect(matchProtocols('r', PROTOCOLS)).toEqual([]); + }); + + it('matches a prefix of an id, alias, or display name', () => { + expect(matchProtocols('run', PROTOCOLS).map((m) => m.value)).toEqual(['runes']); + expect(matchProtocols('inscr', PROTOCOLS).map((m) => m.value)).toEqual(['ordinals']); + expect(matchProtocols('rare', PROTOCOLS).map((m) => m.value)).toEqual(['rare_sats']); + }); + + it('ignores separators and case when matching', () => { + expect(matchProtocols('Rare Sats', PROTOCOLS).map((m) => m.value)).toEqual(['rare_sats']); + expect(matchProtocols('runes_native', PROTOCOLS).map((m) => m.value)).toEqual(['runes']); + }); + + it('puts exact matches first', () => { + const matches = matchProtocols('runes', PROTOCOLS); + expect(matches[0].value).toBe('runes'); + expect(matches[0].rank).toBe(1); + }); + + it('honours the result limit', () => { + const many = Array.from({ length: 10 }, (_, index) => ({ id: `proto${index}` })); + expect(matchProtocols('proto', many, 3)).toHaveLength(3); + }); +}); + +describe('identifierKindLabel', () => { + it('names every kind it can be given', () => { + const kinds = [ + 'outpoint', + 'inscription-id', + 'inscription-number', + 'rune-name', + 'rune-id', + 'sat', + 'protocol', + ] as const; + for (const kind of kinds) { + expect(identifierKindLabel(kind).length).toBeGreaterThan(0); + } + }); +}); diff --git a/frontend/src/app/universe/universe-identifier.ts b/frontend/src/app/universe/universe-identifier.ts new file mode 100644 index 00000000000..9acbde21a02 --- /dev/null +++ b/frontend/src/app/universe/universe-identifier.ts @@ -0,0 +1,233 @@ +/** + * Identifier recognition for Universe search. + * + * Pure functions, no I/O. The search box has to decide what a user typed + * before it can route anywhere, and that decision must be deterministic: + * the same string always produces the same candidate list in the same order. + * Nothing here calls a network, so a query never leaves the browser to be + * classified. + * + * Base Bitcoin identifiers (address, txid, block hash, block height) stay with + * the upstream search matcher. This module only adds the identifier classes + * upstream has no concept of. + */ + +export type UniverseIdentifierKind = + | 'outpoint' + | 'inscription-id' + | 'inscription-number' + | 'rune-name' + | 'rune-id' + | 'sat' + | 'protocol'; + +export interface UniverseIdentifier { + readonly kind: UniverseIdentifierKind; + /** Normalized value used for routing and display. */ + readonly value: string; + /** Router path segments for this identifier. */ + readonly route: readonly string[]; + /** + * Rank among candidates for one query. Lower sorts first. Exactness beats + * plausibility, so a full inscription id outranks a protocol name prefix. + */ + readonly rank: number; +} + +const TXID = /^[0-9a-f]{64}$/; +const UNSIGNED = /^(0|[1-9][0-9]{0,9})$/; +/** Rune names are A to Z with optional spacers, at most 28 letters. */ +const RUNE_LETTERS = /^[A-Z]{1,28}$/; +const RUNE_SPACERS = /[•.]/g; + +/** Highest sat number that can ever exist, so a plain integer above a block height is still bounded. */ +const MAXIMUM_SAT = 2_099_999_997_690_000n; + +/** A protocol entry as far as identifier matching is concerned. */ +export interface ProtocolNameSource { + readonly id: string; + readonly aliases?: readonly string[]; + readonly displayName?: string; + readonly shortName?: string; +} + +function outpointOf(text: string): UniverseIdentifier | null { + const parts = text.split(':'); + if (parts.length !== 2) {return null;} + const [txid, vout] = parts; + if (!TXID.test(txid) || !UNSIGNED.test(vout)) {return null;} + const value = `${txid}:${vout}`; + return { kind: 'outpoint', value, route: ['/outpoint', txid, vout], rank: 0 }; +} + +function inscriptionIdOf(text: string): UniverseIdentifier | null { + const separator = text.indexOf('i'); + if (separator !== 64) {return null;} + const txid = text.slice(0, 64); + const index = text.slice(65); + if (!TXID.test(txid) || !UNSIGNED.test(index)) {return null;} + const value = `${txid}i${index}`; + return { + kind: 'inscription-id', + value, + route: ['/inscription', value], + rank: 0, + }; +} + +/** + * Inscription numbers need an explicit marker. A bare integer is a block + * height to every Bitcoin user, and silently stealing that meaning would make + * the most common search in the product unreliable. Cursed inscriptions carry + * their own marker already, because they are negative. + */ +function inscriptionNumberOf(text: string): UniverseIdentifier | null { + const negative = text.startsWith('-'); + const body = negative ? text.slice(1) : text.replace(/^#/, ''); + if (body === text && !negative) {return null;} + if (!UNSIGNED.test(body)) {return null;} + const value = negative ? `-${body}` : body; + return { + kind: 'inscription-number', + value, + route: ['/inscription', value], + rank: 1, + }; +} + +function runeIdOf(text: string): UniverseIdentifier | null { + const parts = text.split(':'); + if (parts.length !== 2) {return null;} + const [block, index] = parts; + if (!UNSIGNED.test(block) || !UNSIGNED.test(index)) {return null;} + const value = `${block}:${index}`; + return { kind: 'rune-id', value, route: ['/rune', value], rank: 0 }; +} + +function runeNameOf(text: string): UniverseIdentifier | null { + const letters = text.replace(RUNE_SPACERS, ''); + if (!RUNE_LETTERS.test(letters)) {return null;} + // A single letter is far more likely to be a typo than a rune lookup, and + // very short names would drown out every other candidate. + if (letters.length < 3) {return null;} + return { + kind: 'rune-name', + value: letters, + route: ['/rune', letters], + rank: 2, + }; +} + +function satOf(text: string): UniverseIdentifier | null { + const match = /^sat:(0|[1-9][0-9]{0,15})$/.exec(text); + if (!match) {return null;} + if (BigInt(match[1]) > MAXIMUM_SAT) {return null;} + return { kind: 'sat', value: match[1], route: ['/sat', match[1]], rank: 0 }; +} + +function normalizeName(value: string): string { + return value.toLowerCase().replace(/[\s_-]+/g, ''); +} + +/** + * Protocol matches are prefix matches on the id, aliases, and display names, + * so typing "run" offers Runes before the user finishes the word. + */ +export function matchProtocols( + query: string, + protocols: readonly ProtocolNameSource[], + limit = 5, +): UniverseIdentifier[] { + const needle = normalizeName(query); + if (needle.length < 2) {return [];} + const matches: { identifier: UniverseIdentifier; exact: boolean }[] = []; + for (const protocol of protocols) { + const names = [ + protocol.id, + protocol.shortName ?? '', + protocol.displayName ?? '', + ...(protocol.aliases ?? []), + ].filter(Boolean); + let exact = false; + let hit = false; + for (const name of names) { + const normalized = normalizeName(name); + if (normalized === needle) { + exact = true; + hit = true; + break; + } + if (normalized.startsWith(needle)) {hit = true;} + } + if (!hit) {continue;} + matches.push({ + exact, + identifier: { + kind: 'protocol', + value: protocol.id, + route: ['/protocols', protocol.id], + rank: exact ? 1 : 3, + }, + }); + } + return matches + .sort((a, b) => { + if (a.exact !== b.exact) {return a.exact ? -1 : 1;} + return a.identifier.value.localeCompare(b.identifier.value); + }) + .slice(0, limit) + .map((match) => match.identifier); +} + +/** + * All Universe identifiers a query could name, best candidate first. + * An empty array means the query is not a Universe identifier; the caller then + * falls back to the base Bitcoin matcher. + */ +export function classifyUniverseQuery( + rawQuery: string, + protocols: readonly ProtocolNameSource[] = [], +): UniverseIdentifier[] { + const query = (rawQuery ?? '').trim(); + if (!query || query.length > 200) {return [];} + const lower = query.toLowerCase(); + const upper = query.toUpperCase(); + + const candidates: UniverseIdentifier[] = []; + const push = (identifier: UniverseIdentifier | null): void => { + if (identifier) {candidates.push(identifier);} + }; + + push(outpointOf(lower)); + push(inscriptionIdOf(lower)); + push(inscriptionNumberOf(query)); + push(runeIdOf(query)); + push(satOf(lower)); + // Rune names are case insensitive to type but always display uppercase. + push(runeNameOf(upper)); + candidates.push(...matchProtocols(query, protocols)); + + return candidates.sort((a, b) => a.rank - b.rank); +} + +/** Short human label for a candidate, used in the result list. */ +export function identifierKindLabel(kind: UniverseIdentifierKind): string { + switch (kind) { + case 'outpoint': + return $localize`:@@universe.search.kind-outpoint:Outpoint`; + case 'inscription-id': + return $localize`:@@universe.search.kind-inscription:Inscription`; + case 'inscription-number': + return $localize`:@@universe.search.kind-inscription-number:Inscription number`; + case 'rune-name': + return $localize`:@@universe.search.kind-rune:Rune`; + case 'rune-id': + return $localize`:@@universe.search.kind-rune-id:Rune ID`; + case 'sat': + return $localize`:@@universe.search.kind-sat:Sat`; + case 'protocol': + return $localize`:@@universe.search.kind-protocol:Protocol`; + default: + return ''; + } +} diff --git a/frontend/src/app/universe/universe-local.service.spec.ts b/frontend/src/app/universe/universe-local.service.spec.ts new file mode 100644 index 00000000000..b6b67b0b2ee --- /dev/null +++ b/frontend/src/app/universe/universe-local.service.spec.ts @@ -0,0 +1,183 @@ +import { beforeEach, describe, expect, it, vi } from 'vitest'; +import { UniverseLocalService } from '@app/universe/universe-local.service'; + +/** Minimal in-memory stand-in for the browser store. */ +function installStorage(seed: Record = {}): Map { + const store = new Map(Object.entries(seed)); + (globalThis as Record).localStorage = { + getItem: (key: string): string | null => (store.has(key) ? store.get(key) : null), + setItem: (key: string, value: string): void => void store.set(key, value), + removeItem: (key: string): void => void store.delete(key), + }; + return store; +} + +function service(isBrowser = true): UniverseLocalService { + return new UniverseLocalService({ isBrowser } as never); +} + +const ENTRY = { + kind: 'transaction' as const, + value: 'a'.repeat(64), + path: `/tx/${'a'.repeat(64)}`, + label: 'aaaaaaaa', +}; + +describe('UniverseLocalService', () => { + beforeEach(() => { + installStorage(); + }); + + it('does nothing at all outside a browser', () => { + const local = service(false); + local.recordVisit(ENTRY); + expect(local.recentSnapshot()).toEqual([]); + expect(local.toggleBookmark(ENTRY)).toBe(false); + }); + + it('records a visit and keeps the most recent first', () => { + const local = service(); + local.recordVisit(ENTRY); + local.recordVisit({ ...ENTRY, value: 'b'.repeat(64), label: 'bbbbbbbb' }); + expect(local.recentSnapshot().map((entry) => entry.label)).toEqual(['bbbbbbbb', 'aaaaaaaa']); + }); + + it('collapses a repeated visit into one entry', () => { + const local = service(); + local.recordVisit(ENTRY); + local.recordVisit({ ...ENTRY, value: 'b'.repeat(64) }); + local.recordVisit(ENTRY); + const recent = local.recentSnapshot(); + expect(recent).toHaveLength(2); + expect(recent[0].value).toBe(ENTRY.value); + }); + + it('caps the recent list', () => { + const local = service(); + for (let index = 0; index < 20; index += 1) { + local.recordVisit({ ...ENTRY, value: `${index}`.padStart(64, '0'), label: `entry ${index}` }); + } + expect(local.recentSnapshot().length).toBeLessThanOrEqual(8); + }); + + it('toggles a bookmark on and off', () => { + const local = service(); + expect(local.toggleBookmark(ENTRY)).toBe(true); + expect(local.isBookmarked('transaction', ENTRY.value)).toBe(true); + expect(local.toggleBookmark(ENTRY)).toBe(false); + expect(local.isBookmarked('transaction', ENTRY.value)).toBe(false); + }); + + it('treats the same value under different kinds as different entries', () => { + const local = service(); + local.toggleBookmark(ENTRY); + local.toggleBookmark({ ...ENTRY, kind: 'block', path: `/block/${ENTRY.value}` }); + expect(local.isBookmarked('transaction', ENTRY.value)).toBe(true); + expect(local.isBookmarked('block', ENTRY.value)).toBe(true); + }); + + it('refuses an entry whose path is not a local route', () => { + const local = service(); + expect(local.toggleBookmark({ ...ENTRY, path: 'https://example.invalid/tx' })).toBe(false); + expect(local.isBookmarked('transaction', ENTRY.value)).toBe(false); + }); + + it('discards stored junk instead of trusting it', () => { + installStorage({ + 'universe.recent.v1': JSON.stringify([ + { kind: 'transaction' }, + { kind: 'block', value: 'x', path: '/block/x', label: 'x', at: 1 }, + 'not an object', + ]), + }); + const local = service(); + expect(local.recentSnapshot().map((entry) => entry.value)).toEqual(['x']); + }); + + it('survives a store that throws on every access', () => { + (globalThis as Record).localStorage = { + getItem: (): string => { + throw new Error('blocked'); + }, + setItem: (): void => { + throw new Error('blocked'); + }, + removeItem: (): void => { + throw new Error('blocked'); + }, + }; + const local = service(); + expect(local.recentSnapshot()).toEqual([]); + expect(() => local.recordVisit(ENTRY)).not.toThrow(); + expect(() => local.resetAll()).not.toThrow(); + }); + + it('keeps only well formed protocol ids when pinning', () => { + const local = service(); + local.setPreferences({ pinnedProtocols: ['runes', 'ordinals'] }); + local.togglePinnedProtocol('runes'); + let pinned: readonly string[] = []; + local.preferences$.subscribe((preferences) => { + pinned = preferences.pinnedProtocols; + }).unsubscribe(); + expect(pinned).toEqual(['ordinals']); + }); + + it('rejects a stored pin that is not a protocol id', () => { + installStorage({ + 'universe.preferences.v1': JSON.stringify({ + pinnedProtocols: ['runes', 'NOT VALID', 42], + animatePulse: false, + }), + }); + const local = service(); + let pinned: readonly string[] = []; + let animate = true; + local.preferences$.subscribe((preferences) => { + pinned = preferences.pinnedProtocols; + animate = preferences.animatePulse; + }).unsubscribe(); + expect(pinned).toEqual(['runes']); + expect(animate).toBe(false); + }); + + it('forgets everything on reset', () => { + const store = installStorage(); + const local = service(); + local.recordVisit(ENTRY); + local.toggleBookmark(ENTRY); + local.togglePinnedProtocol('runes'); + local.resetAll(); + expect(local.recentSnapshot()).toEqual([]); + expect(local.isBookmarked('transaction', ENTRY.value)).toBe(false); + expect(store.has('universe.recent.v1')).toBe(false); + expect(store.has('universe.bookmarks.v1')).toBe(false); + expect(store.has('universe.preferences.v1')).toBe(false); + }); + + it('never writes anything that was not asked for', () => { + const store = installStorage(); + const local = service(); + local.recordVisit(ENTRY); + expect([...store.keys()]).toEqual(['universe.recent.v1']); + const written = JSON.parse(store.get('universe.recent.v1')); + expect(Object.keys(written[0]).sort()).toEqual(['at', 'kind', 'label', 'path', 'value']); + }); + + it('truncates an over-long label rather than storing it whole', () => { + const local = service(); + local.recordVisit({ ...ENTRY, label: 'x'.repeat(500) }); + expect(local.recentSnapshot()[0].label.length).toBe(120); + }); +}); + +describe('UniverseLocalService time handling', () => { + it('stamps entries with the current time', () => { + installStorage(); + const spy = vi.spyOn(Date, 'now').mockReturnValue(1_700_000_000_000); + const local = service(); + local.recordVisit(ENTRY); + expect(local.recentSnapshot()[0].at).toBe(1_700_000_000_000); + spy.mockRestore(); + }); +}); diff --git a/frontend/src/app/universe/universe-local.service.ts b/frontend/src/app/universe/universe-local.service.ts new file mode 100644 index 00000000000..31f2037579c --- /dev/null +++ b/frontend/src/app/universe/universe-local.service.ts @@ -0,0 +1,246 @@ +import { Injectable } from '@angular/core'; +import { BehaviorSubject, Observable } from 'rxjs'; +import { StateService } from '@app/services/state.service'; + +/** + * Local personalization for the explorer. + * + * Everything here lives in the visitor's own browser. No identifier, search + * term, or bookmark is ever sent anywhere, so returning visitors get a more + * useful product without the explorer building a profile of them. Storage can + * be unavailable (private windows, blocked site data, server-side rendering), + * so every read and write is guarded and the product works with none of it. + */ + +const RECENT_KEY = 'universe.recent.v1'; +const BOOKMARK_KEY = 'universe.bookmarks.v1'; +const PREFERENCE_KEY = 'universe.preferences.v1'; + +const MAXIMUM_RECENT = 8; +const MAXIMUM_BOOKMARKS = 250; +const MAXIMUM_LABEL_LENGTH = 120; + +export type UniverseEntryKind = + | 'transaction' + | 'block' + | 'address' + | 'outpoint' + | 'inscription' + | 'rune' + | 'sat' + | 'protocol'; + +export interface UniverseEntry { + /** Stable identity: kind plus value. */ + readonly kind: UniverseEntryKind; + readonly value: string; + /** Router path this entry opens. */ + readonly path: string; + /** What the visitor sees. Never longer than a line. */ + readonly label: string; + /** Milliseconds since the epoch, recorded when the entry was last touched. */ + readonly at: number; +} + +export interface UniversePreferences { + /** Protocol ids the visitor pinned to the top of protocol filters. */ + readonly pinnedProtocols: readonly string[]; + /** Whether the live pulse animates. Independent of the OS reduced-motion setting, which always wins. */ + readonly animatePulse: boolean; +} + +const DEFAULT_PREFERENCES: UniversePreferences = { + pinnedProtocols: [], + animatePulse: true, +}; + +function entryKey(kind: string, value: string): string { + return `${kind}:${value}`; +} + +@Injectable({ providedIn: 'root' }) +export class UniverseLocalService { + private readonly recentSubject = new BehaviorSubject([]); + private readonly bookmarkSubject = new BehaviorSubject([]); + private readonly preferenceSubject = + new BehaviorSubject(DEFAULT_PREFERENCES); + + readonly recent$: Observable = this.recentSubject.asObservable(); + readonly bookmarks$: Observable = this.bookmarkSubject.asObservable(); + readonly preferences$: Observable = this.preferenceSubject.asObservable(); + + constructor(private stateService: StateService) { + if (this.available()) { + this.recentSubject.next(this.readEntries(RECENT_KEY, MAXIMUM_RECENT)); + this.bookmarkSubject.next(this.readEntries(BOOKMARK_KEY, MAXIMUM_BOOKMARKS)); + this.preferenceSubject.next(this.readPreferences()); + } + } + + private available(): boolean { + return !!this.stateService?.isBrowser; + } + + private read(key: string): unknown { + try { + const raw = localStorage.getItem(key); + return raw ? JSON.parse(raw) : null; + } catch { + return null; + } + } + + private write(key: string, value: unknown): void { + try { + localStorage.setItem(key, JSON.stringify(value)); + } catch { + // A full or blocked store is not an error the visitor needs to see; the + // page keeps working, it just will not remember this. + } + } + + private sanitizeEntry(candidate: unknown): UniverseEntry | null { + if (typeof candidate !== 'object' || candidate === null) {return null;} + const entry = candidate as Record; + const kind = entry.kind; + const value = entry.value; + const path = entry.path; + const label = entry.label; + const at = entry.at; + if ( + typeof kind !== 'string' || !kind || + typeof value !== 'string' || !value || value.length > 200 || + typeof path !== 'string' || !path.startsWith('/') || path.length > 400 || + typeof label !== 'string' || !label || + typeof at !== 'number' || !Number.isFinite(at) + ) { + return null; + } + return { + kind: kind as UniverseEntryKind, + value, + path, + label: label.slice(0, MAXIMUM_LABEL_LENGTH), + at, + }; + } + + private readEntries(key: string, limit: number): readonly UniverseEntry[] { + const parsed = this.read(key); + if (!Array.isArray(parsed)) {return [];} + const entries: UniverseEntry[] = []; + const seen = new Set(); + for (const candidate of parsed) { + const entry = this.sanitizeEntry(candidate); + if (!entry) {continue;} + const id = entryKey(entry.kind, entry.value); + if (seen.has(id)) {continue;} + seen.add(id); + entries.push(entry); + if (entries.length >= limit) {break;} + } + return entries; + } + + private readPreferences(): UniversePreferences { + const parsed = this.read(PREFERENCE_KEY); + if (typeof parsed !== 'object' || parsed === null) {return DEFAULT_PREFERENCES;} + const record = parsed as Record; + const pinned = Array.isArray(record.pinnedProtocols) + ? record.pinnedProtocols + .filter((id): id is string => typeof id === 'string' && /^[a-z][a-z0-9_-]{0,63}$/.test(id)) + .slice(0, 24) + : []; + return { + pinnedProtocols: pinned, + animatePulse: record.animatePulse !== false, + }; + } + + /** Current recently viewed entries, without subscribing. */ + recentSnapshot(): readonly UniverseEntry[] { + return this.recentSubject.value; + } + + /** Records a visit. Most recent first, duplicates collapse to one entry. */ + recordVisit(entry: Omit): void { + if (!this.available()) {return;} + const sanitized = this.sanitizeEntry({ ...entry, at: Date.now() }); + if (!sanitized) {return;} + const id = entryKey(sanitized.kind, sanitized.value); + const next = [ + sanitized, + ...this.recentSubject.value.filter((item) => entryKey(item.kind, item.value) !== id), + ].slice(0, MAXIMUM_RECENT); + this.recentSubject.next(next); + this.write(RECENT_KEY, next); + } + + clearRecent(): void { + this.recentSubject.next([]); + if (this.available()) {this.write(RECENT_KEY, []);} + } + + isBookmarked(kind: UniverseEntryKind, value: string): boolean { + const id = entryKey(kind, value); + return this.bookmarkSubject.value.some((item) => entryKey(item.kind, item.value) === id); + } + + /** Adds or removes a bookmark. Returns the state after the change. */ + toggleBookmark(entry: Omit): boolean { + if (!this.available()) {return false;} + const sanitized = this.sanitizeEntry({ ...entry, at: Date.now() }); + if (!sanitized) {return false;} + const id = entryKey(sanitized.kind, sanitized.value); + const existing = this.bookmarkSubject.value; + const without = existing.filter((item) => entryKey(item.kind, item.value) !== id); + const added = without.length === existing.length; + const next = added ? [sanitized, ...without].slice(0, MAXIMUM_BOOKMARKS) : without; + this.bookmarkSubject.next(next); + this.write(BOOKMARK_KEY, next); + return added; + } + + removeBookmark(kind: UniverseEntryKind, value: string): void { + const id = entryKey(kind, value); + const next = this.bookmarkSubject.value.filter( + (item) => entryKey(item.kind, item.value) !== id, + ); + this.bookmarkSubject.next(next); + if (this.available()) {this.write(BOOKMARK_KEY, next);} + } + + setPreferences(patch: Partial): void { + const next: UniversePreferences = { + ...this.preferenceSubject.value, + ...patch, + pinnedProtocols: (patch.pinnedProtocols ?? this.preferenceSubject.value.pinnedProtocols) + .slice(0, 24), + }; + this.preferenceSubject.next(next); + if (this.available()) {this.write(PREFERENCE_KEY, next);} + } + + togglePinnedProtocol(protocolId: string): void { + const pinned = this.preferenceSubject.value.pinnedProtocols; + const next = pinned.includes(protocolId) + ? pinned.filter((id) => id !== protocolId) + : [...pinned, protocolId]; + this.setPreferences({ pinnedProtocols: next }); + } + + /** Forgets everything this browser has stored for the explorer. */ + resetAll(): void { + this.recentSubject.next([]); + this.bookmarkSubject.next([]); + this.preferenceSubject.next(DEFAULT_PREFERENCES); + if (!this.available()) {return;} + try { + localStorage.removeItem(RECENT_KEY); + localStorage.removeItem(BOOKMARK_KEY); + localStorage.removeItem(PREFERENCE_KEY); + } catch { + // Nothing to clean up if the store cannot be reached. + } + } +} diff --git a/frontend/src/app/universe/universe-protocol-copy.ts b/frontend/src/app/universe/universe-protocol-copy.ts new file mode 100644 index 00000000000..d0bcd2a1ba5 --- /dev/null +++ b/frontend/src/app/universe/universe-protocol-copy.ts @@ -0,0 +1,127 @@ +/** + * Human descriptions for the protocols in the registry. + * + * The registry is a machine contract: ids, authorities, release status. It + * carries no prose, and prose is what a visitor needs to understand what they + * are looking at. Each entry here is written to be true whether or not the + * explorer can currently read that protocol, and says what kind of on-chain + * action it produces rather than what it is worth. + */ + +export interface ProtocolCopy { + /** One or two sentences: what this is, in plain language. */ + readonly summary: string; + /** The action words this protocol produces on chain. */ + readonly actions: readonly string[]; + /** How to read the evidence for it on a transaction page. */ + readonly howToRead?: string; +} + +const FAMILY_COPY: Record = { + ORDINALS: { + summary: $localize`:@@universe.copy.family-ordinals:Ordinals number every satoshi and let data be inscribed onto one of them, so content and identity ride along with an ordinary bitcoin output.`, + actions: ['inscribe', 'transfer'], + }, + RUNES: { + summary: $localize`:@@universe.copy.family-runes:Runes are fungible tokens defined directly in a transaction's data output, with balances tracked against unspent outputs.`, + actions: ['etch', 'mint', 'transfer'], + }, + ALKANES: { + summary: $localize`:@@universe.copy.family-alkanes:Alkanes puts programmable contracts on Bitcoin outputs, executed by an indexer rather than by consensus.`, + actions: ['deploy', 'call', 'transfer'], + }, + STAMPS: { + summary: $localize`:@@universe.copy.family-stamps:Stamps store data inside outputs that cannot be pruned, so the content is as permanent as the UTXO set itself.`, + actions: ['stamp', 'deploy', 'mint', 'transfer'], + }, + ATOMICALS: { + summary: $localize`:@@universe.copy.family-atomicals:Atomicals assigns digital objects and names to satoshis, with tokens backed one unit per satoshi.`, + actions: ['mint', 'transfer', 'claim'], + }, + 'OP DATA': { + summary: $localize`:@@universe.copy.family-op-data:These protocols carry their instructions in a transaction's data output, which every node relays but none interprets.`, + actions: ['deploy', 'mint', 'transfer'], + }, + OTHER: { + summary: $localize`:@@universe.copy.family-other:A metaprotocol on Bitcoin: rules layered on top of ordinary transactions and enforced by an indexer, not by consensus.`, + actions: ['deploy', 'mint', 'transfer'], + }, +}; + +const PROTOCOL_COPY: Record = { + ordinals: { + summary: $localize`:@@universe.copy.ordinals:Ordinal theory numbers every satoshi in the order it was mined, which makes individual satoshis trackable. An inscription attaches content to one of them, so images, text, and other files live directly in Bitcoin's witness data.`, + actions: ['inscribe', 'reveal', 'transfer'], + howToRead: $localize`:@@universe.copy.ordinals-read:An inscription sits on a specific output. The transaction view names the output that carries it before and after the spend, so a transfer is visible as a move between outpoints rather than inferred from the transaction shape.`, + }, + rare_sats: { + summary: $localize`:@@universe.copy.rare-sats:Rare satoshis are the individual satoshis that open a block, a difficulty adjustment, a halving, or a cycle. Their rarity comes from Bitcoin's own schedule, not from any issuer.`, + actions: ['transfer'], + howToRead: $localize`:@@universe.copy.rare-sats-read:The explorer lists notable satoshis by their ordinal number and rarity on the output that holds them. Rarity is derived from the satoshi's position in Bitcoin's issuance schedule and can be recomputed by anyone.`, + }, + runes: { + summary: $localize`:@@universe.copy.runes:Runes are fungible tokens native to Bitcoin. A rune is etched once, minted according to the terms set at etching, and moved by edicts written into a transaction's data output. Balances live on unspent outputs, so a rune transfer is an ordinary bitcoin spend with instructions attached.`, + actions: ['etch', 'mint', 'transfer', 'burn'], + howToRead: $localize`:@@universe.copy.runes-read:Each output shows the rune balances the authority proves it holds, as exact whole numbers. Amounts are never converted through floating point, so large supplies stay precise.`, + }, + brc20: { + summary: $localize`:@@universe.copy.brc20:BRC-20 is a token standard written as JSON inside ordinal inscriptions. Deploys, mints, and transfers are ordinary inscriptions whose text an indexer interprets as ledger operations.`, + actions: ['deploy', 'mint', 'transfer'], + }, + stamps: { + summary: $localize`:@@universe.copy.stamps:Bitcoin Stamps encode image data into outputs that cannot be pruned from the UTXO set, which makes the content unusually durable at a higher cost per byte than an inscription.`, + actions: ['stamp', 'transfer'], + }, + src20: { + summary: $localize`:@@universe.copy.src20:SRC-20 is a token standard built on Bitcoin Stamps, with deploy, mint, and transfer instructions carried in stamp data.`, + actions: ['deploy', 'mint', 'transfer'], + }, + alkanes: { + summary: $localize`:@@universe.copy.alkanes:Alkanes runs WebAssembly contracts against Bitcoin outputs. Contract state is derived by an indexer replaying the chain, so results are reproducible from Bitcoin data alone.`, + actions: ['deploy', 'call', 'transfer'], + }, + arc20: { + summary: $localize`:@@universe.copy.arc20:ARC-20 tokens are backed one unit per satoshi, so moving the token means moving the exact satoshis that carry it.`, + actions: ['mint', 'transfer'], + }, + atomicals_nft: { + summary: $localize`:@@universe.copy.atomicals-nft:Atomicals NFTs are digital objects minted onto individual satoshis under the Atomicals rules.`, + actions: ['mint', 'transfer'], + }, + realms: { + summary: $localize`:@@universe.copy.realms:Realms are Atomicals names claimed without a suffix, written with a leading plus sign. They act as on-chain identities.`, + actions: ['claim', 'transfer'], + }, + bitmap: { + summary: $localize`:@@universe.copy.bitmap:Bitmap claims a Bitcoin block as a numbered district by inscribing its height, turning the block sequence into a scarce namespace.`, + actions: ['claim', 'transfer'], + }, + tap: { + summary: $localize`:@@universe.copy.tap:TAP extends inscription-based token rules with authority and multi-step operations, including transfers signed by a privileged key.`, + actions: ['deploy', 'mint', 'transfer'], + }, + dmt: { + summary: $localize`:@@universe.copy.dmt:Digital Matter Theory derives assets from patterns already present in Bitcoin block data, so issuance follows the chain rather than an arbitrary decision.`, + actions: ['deploy', 'mint'], + }, + op_return: { + summary: $localize`:@@universe.copy.op-return:Protocols in this group write their instructions into a transaction's data output. Bitcoin Core relays that data without interpreting it, so meaning comes entirely from the indexer that reads it.`, + actions: ['deploy', 'mint', 'transfer'], + }, + doginals: { + summary: $localize`:@@universe.copy.doginals:Doginals apply ordinal theory to Dogecoin. They are indexed on a different chain than the one this explorer serves.`, + actions: ['inscribe', 'transfer'], + }, + drc20: { + summary: $localize`:@@universe.copy.drc20:DRC-20 is the Dogecoin counterpart of inscription-based fungible tokens, indexed on a different chain than the one this explorer serves.`, + actions: ['deploy', 'mint', 'transfer'], + }, +}; + +/** Copy for one protocol, falling back to its family and then to a generic line. */ +export function protocolCopy(protocolId: string, family: string): ProtocolCopy { + const exact = PROTOCOL_COPY[protocolId]; + if (exact) {return exact;} + const normalized = (family || 'OTHER').toUpperCase().replace(/[_-]+/g, ' ').trim(); + return FAMILY_COPY[normalized] ?? FAMILY_COPY.OTHER; +} diff --git a/frontend/src/app/universe/universe-pulse.service.spec.ts b/frontend/src/app/universe/universe-pulse.service.spec.ts new file mode 100644 index 00000000000..086609a90f0 --- /dev/null +++ b/frontend/src/app/universe/universe-pulse.service.spec.ts @@ -0,0 +1,115 @@ +import { describe, expect, it } from 'vitest'; +import { protocolIdsOf } from '@app/universe/universe-pulse.service'; +import { sharesOf } from '@app/universe/pulse/pulse.component'; +import { stripEntries } from '@app/universe/protocol-strip/protocol-strip.component'; +import type { ExplorerTransactionAssetFlow } from '@app/universe/universe.types'; + +function flow(patch: Partial = {}): ExplorerTransactionAssetFlow { + return { + schemaVersion: 'universe-transaction-asset-flow-v1', + chain: 'bitcoin', + network: 'mainnet', + txid: 'a'.repeat(64), + status: 'confirmed', + inputs: [], + outputs: [], + actions: [], + sourceEvidence: [], + complete: true, + unknownAttachmentCount: 0, + outOfCoverageCount: 0, + ...patch, + }; +} + +describe('protocolIdsOf', () => { + it('finds nothing in an empty flow', () => { + expect(protocolIdsOf(flow())).toEqual([]); + }); + + it('collects protocols from both sides and from actions', () => { + const ids = protocolIdsOf( + flow({ + inputs: [{ asset: { protocolId: 'ordinals' } }] as never, + outputs: [{ asset: { protocolId: 'runes' } }] as never, + actions: [{ protocolId: 'rare_sats' }] as never, + }), + ); + expect(ids).toEqual(['ordinals', 'rare_sats', 'runes']); + }); + + it('deduplicates and sorts', () => { + const ids = protocolIdsOf( + flow({ + inputs: [{ asset: { protocolId: 'runes' } }] as never, + outputs: [{ asset: { protocolId: 'runes' } }] as never, + }), + ); + expect(ids).toEqual(['runes']); + }); + + it('tolerates missing collections', () => { + expect(protocolIdsOf({} as ExplorerTransactionAssetFlow)).toEqual([]); + }); +}); + +describe('sharesOf', () => { + const names = new Map([['runes', 'RUNES']]); + + it('floors percentages so a rare protocol is never rounded into significance', () => { + const shares = sharesOf( + { checked: 1000, protocolCounts: new Map([['runes', 4]]) } as never, + names, + ); + expect(shares[0].percent).toBe(0); + expect(shares[0].count).toBe(4); + }); + + it('reports zero percent when nothing has been checked', () => { + const shares = sharesOf( + { checked: 0, protocolCounts: new Map([['runes', 0]]) } as never, + names, + ); + expect(shares[0].percent).toBe(0); + }); + + it('sorts by count, then by id for a stable order', () => { + const shares = sharesOf( + { + checked: 10, + protocolCounts: new Map([ + ['ordinals', 3], + ['runes', 3], + ['rare_sats', 5], + ]), + } as never, + new Map(), + ); + expect(shares.map((share) => share.protocolId)).toEqual(['rare_sats', 'ordinals', 'runes']); + }); + + it('falls back to the protocol id when the registry has no name', () => { + const shares = sharesOf({ checked: 1, protocolCounts: new Map([['x', 1]]) } as never, new Map()); + expect(shares[0].displayName).toBe('x'); + }); +}); + +describe('stripEntries', () => { + const supported = [ + { id: 'runes', shortName: 'RUNES' }, + { id: 'ordinals', shortName: 'Ordinals' }, + ] as never; + + it('lists every supported protocol, including those with no activity', () => { + const entries = stripEntries(supported, { protocolCounts: new Map() } as never); + expect(entries.map((entry) => entry.protocolId).sort()).toEqual(['ordinals', 'runes']); + expect(entries.every((entry) => entry.count === 0)).toBe(true); + }); + + it('puts the busiest protocol first', () => { + const entries = stripEntries(supported, { + protocolCounts: new Map([['ordinals', 7]]), + } as never); + expect(entries[0].protocolId).toBe('ordinals'); + }); +}); diff --git a/frontend/src/app/universe/universe-pulse.service.ts b/frontend/src/app/universe/universe-pulse.service.ts new file mode 100644 index 00000000000..5eea3002912 --- /dev/null +++ b/frontend/src/app/universe/universe-pulse.service.ts @@ -0,0 +1,237 @@ +import { Injectable, OnDestroy } from '@angular/core'; +import { BehaviorSubject, Observable, Subscription, firstValueFrom, timer } from 'rxjs'; +import { StateService } from '@app/services/state.service'; +import { UniverseApiService, UNIVERSE_TRANSACTION_BATCH_LIMIT } from '@app/universe/universe-api.service'; +import { + ExplorerAssetAction, + ExplorerTransactionAssetFlow, + TransactionBatchItem, +} from '@app/universe/universe.types'; + +/** + * Live protocol activity in the mempool. + * + * The explorer backend already pushes the newest mempool arrivals over the + * existing socket. This service takes that stream, asks the asset authority + * what those transactions actually do, and keeps a running tally. + * + * Two rules keep it honest and cheap: + * + * 1. The denominator is always published. A protocol count means nothing + * without "out of how many transactions we checked", so the tally carries + * the exact number of transactions resolved since the page opened. + * 2. Work is strictly bounded. One request at a time, at most + * UNIVERSE_TRANSACTION_BATCH_LIMIT transactions per request, nothing at all + * while the tab is hidden, and a hard ceiling per session. + */ + +const POLL_INTERVAL_MS = 2500; +const MAXIMUM_QUEUE = 400; +const MAXIMUM_RECENT = 40; +/** Ceiling on resolutions per page visit, so a long session cannot drift into unbounded work. */ +const SESSION_RESOLVE_CEILING = 4000; + +export interface PulseEvent { + readonly txid: string; + readonly protocolIds: readonly string[]; + readonly actions: readonly ExplorerAssetAction[]; + readonly status: ExplorerTransactionAssetFlow['status']; + readonly seenAt: number; +} + +export interface PulseState { + /** Transactions the authority answered for since this page opened. */ + readonly checked: number; + /** Of those, how many carried at least one supported asset or action. */ + readonly withAssets: number; + /** Protocol id to number of transactions it appeared in, within `checked`. */ + readonly protocolCounts: ReadonlyMap; + readonly recent: readonly PulseEvent[]; + /** True while the authority is answering. False after repeated failures. */ + readonly authorityAnswering: boolean; + readonly startedAt: number; + /** True once the session ceiling is reached and sampling has stopped. */ + readonly ceilingReached: boolean; +} + +const EMPTY_STATE: PulseState = { + checked: 0, + withAssets: 0, + protocolCounts: new Map(), + recent: [], + authorityAnswering: true, + startedAt: 0, + ceilingReached: false, +}; + +@Injectable({ providedIn: 'root' }) +export class UniversePulseService implements OnDestroy { + private readonly stateSubject = new BehaviorSubject(EMPTY_STATE); + readonly state$: Observable = this.stateSubject.asObservable(); + + private queue: string[] = []; + private seen = new Set(); + private inFlight = false; + private consecutiveFailures = 0; + private subscriptions = new Subscription(); + /** Reference count: several surfaces can show the pulse at once. */ + private consumers = 0; + /** Mirrors the tab visibility stream so the sampling loop can read it synchronously. */ + private tabHidden = false; + + constructor( + private stateService: StateService, + private api: UniverseApiService, + ) {} + + /** + * Reference counted: every surface that shows the pulse calls start on + * enter and stop on leave, and the sampling loop runs while at least one + * of them is open. + */ + start(): void { + if (!this.stateService.isBrowser) { + return; + } + this.consumers += 1; + if (this.consumers > 1) { + return; + } + this.stateSubject.next({ ...EMPTY_STATE, startedAt: Date.now() }); + + this.subscriptions.add( + this.stateService.transactions$.subscribe((transactions) => { + if (!transactions?.length) { + return; + } + for (const transaction of transactions) { + this.enqueue(transaction?.txid); + } + }), + ); + + this.subscriptions.add( + this.stateService.isTabHidden$.subscribe((hidden) => { + this.tabHidden = !!hidden; + }), + ); + + this.subscriptions.add( + timer(0, POLL_INTERVAL_MS).subscribe(() => { + void this.drain(); + }), + ); + } + + stop(): void { + if (this.consumers === 0) {return;} + this.consumers -= 1; + if (this.consumers > 0) {return;} + this.subscriptions.unsubscribe(); + this.subscriptions = new Subscription(); + this.queue = []; + this.seen = new Set(); + this.inFlight = false; + this.consecutiveFailures = 0; + this.tabHidden = false; + this.stateSubject.next(EMPTY_STATE); + } + + ngOnDestroy(): void { + this.consumers = 1; + this.stop(); + } + + private enqueue(txid: string | undefined): void { + if (typeof txid !== 'string' || !/^[0-9a-f]{64}$/.test(txid)) {return;} + if (this.seen.has(txid)) {return;} + this.seen.add(txid); + this.queue.push(txid); + if (this.queue.length > MAXIMUM_QUEUE) { + // Under a burst the newest arrivals are the interesting ones; the tally + // stays truthful because dropped entries were never counted. + const dropped = this.queue.splice(0, this.queue.length - MAXIMUM_QUEUE); + for (const entry of dropped) {this.seen.delete(entry);} + } + } + + private async drain(): Promise { + if (!this.consumers || this.inFlight || !this.queue.length) {return;} + if (this.tabHidden) {return;} + const current = this.stateSubject.value; + if (current.checked >= SESSION_RESOLVE_CEILING) { + if (!current.ceilingReached) { + this.stateSubject.next({ ...current, ceilingReached: true }); + } + return; + } + + const batch = this.queue.splice(0, UNIVERSE_TRANSACTION_BATCH_LIMIT); + this.inFlight = true; + try { + const response = await firstValueFrom(this.api.getTransactionFlows$(batch)); + this.consecutiveFailures = 0; + this.apply(response?.results ?? []); + } catch { + this.consecutiveFailures += 1; + if (this.consecutiveFailures >= 3) { + this.stateSubject.next({ + ...this.stateSubject.value, + authorityAnswering: false, + }); + } + } finally { + this.inFlight = false; + } + } + + private apply(results: readonly TransactionBatchItem[]): void { + const previous = this.stateSubject.value; + const protocolCounts = new Map(previous.protocolCounts); + const recent = [...previous.recent]; + let checked = previous.checked; + let withAssets = previous.withAssets; + const now = Date.now(); + + for (const item of results) { + if (item.status !== 'ok' || !item.flow) {continue;} + checked += 1; + const protocolIds = protocolIdsOf(item.flow); + if (!protocolIds.length) {continue;} + withAssets += 1; + for (const protocolId of protocolIds) { + protocolCounts.set(protocolId, (protocolCounts.get(protocolId) ?? 0) + 1); + } + recent.unshift({ + txid: item.txid, + protocolIds, + actions: item.flow.actions ?? [], + status: item.flow.status, + seenAt: now, + }); + } + + this.stateSubject.next({ + checked, + withAssets, + protocolCounts, + recent: recent.slice(0, MAXIMUM_RECENT), + authorityAnswering: true, + startedAt: previous.startedAt || now, + ceilingReached: previous.ceilingReached, + }); + } +} + +/** Every protocol this flow proves involvement of, deduplicated and sorted. */ +export function protocolIdsOf(flow: ExplorerTransactionAssetFlow): string[] { + const ids = new Set(); + for (const position of [...(flow.inputs ?? []), ...(flow.outputs ?? [])]) { + const id = position?.asset?.protocolId; + if (id) {ids.add(id);} + } + for (const action of flow.actions ?? []) { + if (action?.protocolId) {ids.add(action.protocolId);} + } + return [...ids].sort(); +} diff --git a/frontend/src/app/universe/universe-routing.module.ts b/frontend/src/app/universe/universe-routing.module.ts index 7247af21484..53632456c7b 100644 --- a/frontend/src/app/universe/universe-routing.module.ts +++ b/frontend/src/app/universe/universe-routing.module.ts @@ -1,12 +1,17 @@ import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; import { ProtocolDirectoryComponent } from '@app/universe/protocol-directory/protocol-directory.component'; +import { ProtocolDetailComponent } from '@app/universe/protocol-detail/protocol-detail.component'; const routes: Routes = [ { path: '', component: ProtocolDirectoryComponent, }, + { + path: ':id', + component: ProtocolDetailComponent, + }, ]; @NgModule({ diff --git a/frontend/src/app/universe/universe-shared.module.ts b/frontend/src/app/universe/universe-shared.module.ts index c87ee972087..cc910cc0f9b 100644 --- a/frontend/src/app/universe/universe-shared.module.ts +++ b/frontend/src/app/universe/universe-shared.module.ts @@ -1,5 +1,6 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; +import { RouterModule } from '@angular/router'; import { ProtocolBadgeComponent } from '@app/universe/protocol-badge/protocol-badge.component'; import { AssetFlowComponent } from '@app/universe/asset-flow/asset-flow.component'; @@ -14,6 +15,7 @@ import { AssetFlowComponent } from '@app/universe/asset-flow/asset-flow.componen ], imports: [ CommonModule, + RouterModule, ], exports: [ ProtocolBadgeComponent, diff --git a/frontend/src/app/universe/universe.module.ts b/frontend/src/app/universe/universe.module.ts index c1abe0ce3ce..8e6b2230f20 100644 --- a/frontend/src/app/universe/universe.module.ts +++ b/frontend/src/app/universe/universe.module.ts @@ -4,10 +4,12 @@ import { SharedModule } from '@app/shared/shared.module'; import { UniverseRoutingModule } from '@app/universe/universe-routing.module'; import { UniverseSharedModule } from '@app/universe/universe-shared.module'; import { ProtocolDirectoryComponent } from '@app/universe/protocol-directory/protocol-directory.component'; +import { ProtocolDetailComponent } from '@app/universe/protocol-detail/protocol-detail.component'; @NgModule({ declarations: [ ProtocolDirectoryComponent, + ProtocolDetailComponent, ], imports: [ CommonModule, diff --git a/frontend/src/app/universe/universe.types.ts b/frontend/src/app/universe/universe.types.ts index bd837ecf806..41720d9e9cc 100644 --- a/frontend/src/app/universe/universe.types.ts +++ b/frontend/src/app/universe/universe.types.ts @@ -173,3 +173,119 @@ export interface UniverseApiError { error: string; [key: string]: unknown; } + +// --- Outpoint enrichment --- + +export type OutpointEnrichmentStatus = + 'ok' | 'unconfigured' | 'unavailable' | 'stale' | 'malformed' | 'not-indexed'; + +export interface OutpointEnrichment { + outpoint: string; + status: OutpointEnrichmentStatus; + positions: ExplorerOutpointPosition[]; + coveredProtocolIds: string[]; + unknownAttachments: boolean; + checkpoint: ExplorerEvidenceCheckpoint | null; +} + +export interface OutpointBatchResponse { + results: OutpointEnrichment[]; +} + +// --- Transaction flow batch --- + +export type TransactionBatchStatus = + 'ok' | 'invalid' | 'not-found' | 'unconfigured' | 'unavailable'; + +export interface TransactionBatchItem { + txid: string; + status: TransactionBatchStatus; + flow: ExplorerTransactionAssetFlow | null; +} + +export interface TransactionBatchResponse { + results: TransactionBatchItem[]; +} + +// --- Asset lookups --- + +export type AssetLookupStatus = + 'ok' | 'not-found' | 'unconfigured' | 'unavailable' | 'malformed'; + +export interface AssetLookupResult { + schemaVersion: string; + status: AssetLookupStatus; + authorityId: string; + checkpoint: ExplorerEvidenceCheckpoint | null; + value: T | null; +} + +export interface OrdInscriptionView { + id: string; + numberAtomic: string; + address: string | null; + contentType: string | null; + contentLengthAtomic: string | null; + heightAtomic: string | null; + feeAtomic: string | null; + valueAtomic: string | null; + satAtomic: string | null; + satpoint: string | null; + timestampAtomic: string | null; + charms: string[]; + parents: string[]; + childCountAtomic: string | null; + rune: string | null; + metaprotocol: string | null; +} + +export interface OrdRuneTermsView { + amountAtomic: string | null; + capAtomic: string | null; + heightStartAtomic: string | null; + heightEndAtomic: string | null; + offsetStartAtomic: string | null; + offsetEndAtomic: string | null; +} + +export interface OrdRuneView { + id: string; + spacedRune: string; + rune: string; + symbol: string | null; + divisibilityAtomic: string; + blockAtomic: string | null; + numberAtomic: string | null; + mintsAtomic: string; + burnedAtomic: string; + premineAtomic: string; + etchingTxid: string | null; + timestampAtomic: string | null; + turbo: boolean; + mintable: boolean; + terms: OrdRuneTermsView | null; + parentInscriptionId: string | null; +} + +export interface OrdSatView { + numberAtomic: string; + rarity: string; + name: string | null; + decimal: string | null; + degree: string | null; + percentile: string | null; + blockAtomic: string | null; + cycleAtomic: string | null; + epochAtomic: string | null; + periodAtomic: string | null; + offsetAtomic: string | null; + timestampAtomic: string | null; + satpoint: string | null; + address: string | null; + inscriptions: string[]; +} + +export interface OrdBlockInscriptionsView { + ids: string[]; + more: boolean; +} diff --git a/frontend/src/index.liquid.html b/frontend/src/index.liquid.html index caaf5f01c3b..959b95fd98e 100644 --- a/frontend/src/index.liquid.html +++ b/frontend/src/index.liquid.html @@ -7,16 +7,16 @@ - + - + - - + + diff --git a/frontend/src/index.mempool.bitb.html b/frontend/src/index.mempool.bitb.html deleted file mode 100644 index a886e5ec20d..00000000000 --- a/frontend/src/index.mempool.bitb.html +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - BITB | Bitwise Bitcoin ETF - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/frontend/src/index.mempool.meta.html b/frontend/src/index.mempool.meta.html deleted file mode 100644 index 1fd1e653105..00000000000 --- a/frontend/src/index.mempool.meta.html +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - Metaplanet Inc - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/frontend/src/index.mempool.onbtc.html b/frontend/src/index.mempool.onbtc.html deleted file mode 100644 index c2be0bf0049..00000000000 --- a/frontend/src/index.mempool.onbtc.html +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - National Bitcoin Office of El Salvador - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/frontend/src/index.mempool.river.html b/frontend/src/index.mempool.river.html deleted file mode 100644 index f6b6c2e1bd8..00000000000 --- a/frontend/src/index.mempool.river.html +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - River | Invest in Bitcoin with confidence - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/frontend/src/index.mempool.strategy.html b/frontend/src/index.mempool.strategy.html deleted file mode 100644 index c0d57580d3e..00000000000 --- a/frontend/src/index.mempool.strategy.html +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - Strategy | The world's first and largest Bitcoin Treasury Company - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/frontend/src/index.mempool.xxi.html b/frontend/src/index.mempool.xxi.html deleted file mode 100644 index 7163e7804b9..00000000000 --- a/frontend/src/index.mempool.xxi.html +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - Twenty One - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/frontend/src/resources/bimi.svg b/frontend/src/resources/bimi.svg deleted file mode 100644 index 057b7081a1b..00000000000 --- a/frontend/src/resources/bimi.svg +++ /dev/null @@ -1 +0,0 @@ -Mempool Holdings S.A. de C.V. \ No newline at end of file diff --git a/frontend/src/resources/bitb/bitb-preview.png b/frontend/src/resources/bitb/bitb-preview.png deleted file mode 100644 index da2aba024d8..00000000000 Binary files a/frontend/src/resources/bitb/bitb-preview.png and /dev/null differ diff --git a/frontend/src/resources/bitb/favicons/android-chrome-192x192.png b/frontend/src/resources/bitb/favicons/android-chrome-192x192.png deleted file mode 100644 index 82463001250..00000000000 Binary files a/frontend/src/resources/bitb/favicons/android-chrome-192x192.png and /dev/null differ diff --git a/frontend/src/resources/bitb/favicons/android-chrome-512x512.png b/frontend/src/resources/bitb/favicons/android-chrome-512x512.png deleted file mode 100644 index 5a6ed20f9c3..00000000000 Binary files a/frontend/src/resources/bitb/favicons/android-chrome-512x512.png and /dev/null differ diff --git a/frontend/src/resources/bitb/favicons/apple-touch-icon.png b/frontend/src/resources/bitb/favicons/apple-touch-icon.png deleted file mode 100644 index e93df1f495e..00000000000 Binary files a/frontend/src/resources/bitb/favicons/apple-touch-icon.png and /dev/null differ diff --git a/frontend/src/resources/bitb/favicons/favicon-16x16.png b/frontend/src/resources/bitb/favicons/favicon-16x16.png deleted file mode 100644 index 336dcda94eb..00000000000 Binary files a/frontend/src/resources/bitb/favicons/favicon-16x16.png and /dev/null differ diff --git a/frontend/src/resources/bitb/favicons/favicon-32x32.png b/frontend/src/resources/bitb/favicons/favicon-32x32.png deleted file mode 100644 index ad5589e65fe..00000000000 Binary files a/frontend/src/resources/bitb/favicons/favicon-32x32.png and /dev/null differ diff --git a/frontend/src/resources/bitb/favicons/favicon.ico b/frontend/src/resources/bitb/favicons/favicon.ico deleted file mode 100644 index 9c72cced08d..00000000000 Binary files a/frontend/src/resources/bitb/favicons/favicon.ico and /dev/null differ diff --git a/frontend/src/resources/bitb/favicons/site.webmanifest b/frontend/src/resources/bitb/favicons/site.webmanifest deleted file mode 100644 index 45dc8a20658..00000000000 --- a/frontend/src/resources/bitb/favicons/site.webmanifest +++ /dev/null @@ -1 +0,0 @@ -{"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"} \ No newline at end of file diff --git a/frontend/src/resources/bitblogo.svg b/frontend/src/resources/bitblogo.svg deleted file mode 100644 index 6c69a2a4ca5..00000000000 --- a/frontend/src/resources/bitblogo.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/frontend/src/resources/elsalvador-flag.svg b/frontend/src/resources/elsalvador-flag.svg deleted file mode 100644 index 3871872af29..00000000000 --- a/frontend/src/resources/elsalvador-flag.svg +++ /dev/null @@ -1,593 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/frontend/src/resources/elsalvador.svg b/frontend/src/resources/elsalvador.svg deleted file mode 100644 index fc5a59185a8..00000000000 --- a/frontend/src/resources/elsalvador.svg +++ /dev/null @@ -1,1110 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/frontend/src/resources/mempool-accelerator-sparkles-light.svg b/frontend/src/resources/mempool-accelerator-sparkles-light.svg deleted file mode 100644 index 8998e0c2208..00000000000 --- a/frontend/src/resources/mempool-accelerator-sparkles-light.svg +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/frontend/src/resources/mempool-block-visualization.png b/frontend/src/resources/mempool-block-visualization.png deleted file mode 100644 index 7b808a69a40..00000000000 Binary files a/frontend/src/resources/mempool-block-visualization.png and /dev/null differ diff --git a/frontend/src/resources/mempool-blocks-2-3-logo.jpeg b/frontend/src/resources/mempool-blocks-2-3-logo.jpeg deleted file mode 100644 index 9ec0525d38b..00000000000 Binary files a/frontend/src/resources/mempool-blocks-2-3-logo.jpeg and /dev/null differ diff --git a/frontend/src/resources/mempool-blocks-3-2-logo.jpeg b/frontend/src/resources/mempool-blocks-3-2-logo.jpeg deleted file mode 100644 index 298cf8a0173..00000000000 Binary files a/frontend/src/resources/mempool-blocks-3-2-logo.jpeg and /dev/null differ diff --git a/frontend/src/resources/mempool-blocks.png b/frontend/src/resources/mempool-blocks.png deleted file mode 100644 index 0f463f7d8e0..00000000000 Binary files a/frontend/src/resources/mempool-blocks.png and /dev/null differ diff --git a/frontend/src/resources/mempool-holdings.png b/frontend/src/resources/mempool-holdings.png deleted file mode 100644 index 69d459aefc0..00000000000 Binary files a/frontend/src/resources/mempool-holdings.png and /dev/null differ diff --git a/frontend/src/resources/mempool-logo-bigger.png b/frontend/src/resources/mempool-logo-bigger.png deleted file mode 100644 index 4e4dd04f99a..00000000000 Binary files a/frontend/src/resources/mempool-logo-bigger.png and /dev/null differ diff --git a/frontend/src/resources/mempool-preview.png b/frontend/src/resources/mempool-preview.png deleted file mode 100644 index 30be3acb4ac..00000000000 Binary files a/frontend/src/resources/mempool-preview.png and /dev/null differ diff --git a/frontend/src/resources/mempool-research.png b/frontend/src/resources/mempool-research.png deleted file mode 100644 index 42ee008f74a..00000000000 Binary files a/frontend/src/resources/mempool-research.png and /dev/null differ diff --git a/frontend/src/resources/mempool-space-logo-bigger.png b/frontend/src/resources/mempool-space-logo-bigger.png deleted file mode 100644 index e8b0a384ca3..00000000000 Binary files a/frontend/src/resources/mempool-space-logo-bigger.png and /dev/null differ diff --git a/frontend/src/resources/mempool-space-logo-horizontal.png b/frontend/src/resources/mempool-space-logo-horizontal.png deleted file mode 100644 index a8109c0048c..00000000000 Binary files a/frontend/src/resources/mempool-space-logo-horizontal.png and /dev/null differ diff --git a/frontend/src/resources/mempool-space-preview.png b/frontend/src/resources/mempool-space-preview.png deleted file mode 100644 index 60c8bcc6ac4..00000000000 Binary files a/frontend/src/resources/mempool-space-preview.png and /dev/null differ diff --git a/frontend/src/resources/mempool-transaction.png b/frontend/src/resources/mempool-transaction.png deleted file mode 100644 index 396f476336a..00000000000 Binary files a/frontend/src/resources/mempool-transaction.png and /dev/null differ diff --git a/frontend/src/resources/mempool-tube.png b/frontend/src/resources/mempool-tube.png deleted file mode 100644 index af2e58dacbf..00000000000 Binary files a/frontend/src/resources/mempool-tube.png and /dev/null differ diff --git a/frontend/src/resources/meta/favicons/android-chrome-192x192.png b/frontend/src/resources/meta/favicons/android-chrome-192x192.png deleted file mode 100644 index 448d5ce9115..00000000000 Binary files a/frontend/src/resources/meta/favicons/android-chrome-192x192.png and /dev/null differ diff --git a/frontend/src/resources/meta/favicons/android-chrome-512x512.png b/frontend/src/resources/meta/favicons/android-chrome-512x512.png deleted file mode 100644 index 5164c77464e..00000000000 Binary files a/frontend/src/resources/meta/favicons/android-chrome-512x512.png and /dev/null differ diff --git a/frontend/src/resources/meta/favicons/apple-touch-icon.png b/frontend/src/resources/meta/favicons/apple-touch-icon.png deleted file mode 100644 index bd5b04f4b2c..00000000000 Binary files a/frontend/src/resources/meta/favicons/apple-touch-icon.png and /dev/null differ diff --git a/frontend/src/resources/meta/favicons/favicon-16x16.png b/frontend/src/resources/meta/favicons/favicon-16x16.png deleted file mode 100644 index 2c971632513..00000000000 Binary files a/frontend/src/resources/meta/favicons/favicon-16x16.png and /dev/null differ diff --git a/frontend/src/resources/meta/favicons/favicon-32x32.png b/frontend/src/resources/meta/favicons/favicon-32x32.png deleted file mode 100644 index 6fb88e67881..00000000000 Binary files a/frontend/src/resources/meta/favicons/favicon-32x32.png and /dev/null differ diff --git a/frontend/src/resources/meta/favicons/favicon.ico b/frontend/src/resources/meta/favicons/favicon.ico deleted file mode 100644 index bd25b818f1a..00000000000 Binary files a/frontend/src/resources/meta/favicons/favicon.ico and /dev/null differ diff --git a/frontend/src/resources/meta/favicons/site.webmanifest b/frontend/src/resources/meta/favicons/site.webmanifest deleted file mode 100644 index 45dc8a20658..00000000000 --- a/frontend/src/resources/meta/favicons/site.webmanifest +++ /dev/null @@ -1 +0,0 @@ -{"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"} \ No newline at end of file diff --git a/frontend/src/resources/metalogo.svg b/frontend/src/resources/metalogo.svg deleted file mode 100644 index e3174dc62f1..00000000000 --- a/frontend/src/resources/metalogo.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/frontend/src/resources/onbtc.svg b/frontend/src/resources/onbtc.svg deleted file mode 100644 index a76cbe496a8..00000000000 --- a/frontend/src/resources/onbtc.svg +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - - - - - - - - - - - - - diff --git a/frontend/src/resources/onbtc/favicons/android-chrome-192x192.png b/frontend/src/resources/onbtc/favicons/android-chrome-192x192.png deleted file mode 100644 index 3dd14daf67c..00000000000 Binary files a/frontend/src/resources/onbtc/favicons/android-chrome-192x192.png and /dev/null differ diff --git a/frontend/src/resources/onbtc/favicons/android-chrome-512x512.png b/frontend/src/resources/onbtc/favicons/android-chrome-512x512.png deleted file mode 100644 index 980533e3a11..00000000000 Binary files a/frontend/src/resources/onbtc/favicons/android-chrome-512x512.png and /dev/null differ diff --git a/frontend/src/resources/onbtc/favicons/apple-touch-icon.png b/frontend/src/resources/onbtc/favicons/apple-touch-icon.png deleted file mode 100644 index 61284d78dcc..00000000000 Binary files a/frontend/src/resources/onbtc/favicons/apple-touch-icon.png and /dev/null differ diff --git a/frontend/src/resources/onbtc/favicons/favicon-16x16.png b/frontend/src/resources/onbtc/favicons/favicon-16x16.png deleted file mode 100644 index f9d32e8284b..00000000000 Binary files a/frontend/src/resources/onbtc/favicons/favicon-16x16.png and /dev/null differ diff --git a/frontend/src/resources/onbtc/favicons/favicon-32x32.png b/frontend/src/resources/onbtc/favicons/favicon-32x32.png deleted file mode 100644 index cf0c7841cee..00000000000 Binary files a/frontend/src/resources/onbtc/favicons/favicon-32x32.png and /dev/null differ diff --git a/frontend/src/resources/onbtc/favicons/favicon.ico b/frontend/src/resources/onbtc/favicons/favicon.ico deleted file mode 100644 index 7ba6a259671..00000000000 Binary files a/frontend/src/resources/onbtc/favicons/favicon.ico and /dev/null differ diff --git a/frontend/src/resources/onbtc/favicons/site.webmanifest b/frontend/src/resources/onbtc/favicons/site.webmanifest deleted file mode 100644 index 45dc8a20658..00000000000 --- a/frontend/src/resources/onbtc/favicons/site.webmanifest +++ /dev/null @@ -1 +0,0 @@ -{"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"} \ No newline at end of file diff --git a/frontend/src/resources/onbtc/onbtc-preview.jpg b/frontend/src/resources/onbtc/onbtc-preview.jpg deleted file mode 100644 index 5eb8e78f478..00000000000 Binary files a/frontend/src/resources/onbtc/onbtc-preview.jpg and /dev/null differ diff --git a/frontend/src/resources/onbtclogo.svg b/frontend/src/resources/onbtclogo.svg deleted file mode 100644 index c07b7661b35..00000000000 --- a/frontend/src/resources/onbtclogo.svg +++ /dev/null @@ -1,678 +0,0 @@ - - diff --git a/frontend/src/resources/previews/about.jpg b/frontend/src/resources/previews/about.jpg deleted file mode 100644 index 720245d9ca1..00000000000 Binary files a/frontend/src/resources/previews/about.jpg and /dev/null differ diff --git a/frontend/src/resources/previews/accelerator.jpg b/frontend/src/resources/previews/accelerator.jpg deleted file mode 100644 index 3a10b722136..00000000000 Binary files a/frontend/src/resources/previews/accelerator.jpg and /dev/null differ diff --git a/frontend/src/resources/previews/blocks.jpg b/frontend/src/resources/previews/blocks.jpg deleted file mode 100644 index 91c44f0deaf..00000000000 Binary files a/frontend/src/resources/previews/blocks.jpg and /dev/null differ diff --git a/frontend/src/resources/previews/dashboard.png b/frontend/src/resources/previews/dashboard.png deleted file mode 100644 index 60c8bcc6ac4..00000000000 Binary files a/frontend/src/resources/previews/dashboard.png and /dev/null differ diff --git a/frontend/src/resources/previews/docs-api.jpg b/frontend/src/resources/previews/docs-api.jpg deleted file mode 100644 index a24333291d5..00000000000 Binary files a/frontend/src/resources/previews/docs-api.jpg and /dev/null differ diff --git a/frontend/src/resources/previews/enterprise.jpg b/frontend/src/resources/previews/enterprise.jpg deleted file mode 100644 index 293f39e0b81..00000000000 Binary files a/frontend/src/resources/previews/enterprise.jpg and /dev/null differ diff --git a/frontend/src/resources/previews/faq.jpg b/frontend/src/resources/previews/faq.jpg deleted file mode 100644 index 4e198ed49e8..00000000000 Binary files a/frontend/src/resources/previews/faq.jpg and /dev/null differ diff --git a/frontend/src/resources/previews/lightning.jpg b/frontend/src/resources/previews/lightning.jpg deleted file mode 100644 index 59431708c40..00000000000 Binary files a/frontend/src/resources/previews/lightning.jpg and /dev/null differ diff --git a/frontend/src/resources/previews/lightning.png b/frontend/src/resources/previews/lightning.png deleted file mode 100644 index 4686b0ef086..00000000000 Binary files a/frontend/src/resources/previews/lightning.png and /dev/null differ diff --git a/frontend/src/resources/previews/mempool-space-preview.jpg b/frontend/src/resources/previews/mempool-space-preview.jpg deleted file mode 100644 index ca76ba008a1..00000000000 Binary files a/frontend/src/resources/previews/mempool-space-preview.jpg and /dev/null differ diff --git a/frontend/src/resources/previews/mining.jpg b/frontend/src/resources/previews/mining.jpg deleted file mode 100644 index f36f0ae57df..00000000000 Binary files a/frontend/src/resources/previews/mining.jpg and /dev/null differ diff --git a/frontend/src/resources/previews/mining.png b/frontend/src/resources/previews/mining.png deleted file mode 100644 index 6a2aa1b41b3..00000000000 Binary files a/frontend/src/resources/previews/mining.png and /dev/null differ diff --git a/frontend/src/resources/previews/privacy-policy.jpg b/frontend/src/resources/previews/privacy-policy.jpg deleted file mode 100644 index f6d32bf69e6..00000000000 Binary files a/frontend/src/resources/previews/privacy-policy.jpg and /dev/null differ diff --git a/frontend/src/resources/previews/rbf.jpg b/frontend/src/resources/previews/rbf.jpg deleted file mode 100644 index f96cf59cbd2..00000000000 Binary files a/frontend/src/resources/previews/rbf.jpg and /dev/null differ diff --git a/frontend/src/resources/previews/research.jpg b/frontend/src/resources/previews/research.jpg deleted file mode 100644 index 341f5de1d8c..00000000000 Binary files a/frontend/src/resources/previews/research.jpg and /dev/null differ diff --git a/frontend/src/resources/previews/research.png b/frontend/src/resources/previews/research.png deleted file mode 100644 index 976d1aaa4cd..00000000000 Binary files a/frontend/src/resources/previews/research.png and /dev/null differ diff --git a/frontend/src/resources/previews/sponsor.jpg b/frontend/src/resources/previews/sponsor.jpg deleted file mode 100644 index cef41f46a6a..00000000000 Binary files a/frontend/src/resources/previews/sponsor.jpg and /dev/null differ diff --git a/frontend/src/resources/previews/terms-of-service.jpg b/frontend/src/resources/previews/terms-of-service.jpg deleted file mode 100644 index 26865848b20..00000000000 Binary files a/frontend/src/resources/previews/terms-of-service.jpg and /dev/null differ diff --git a/frontend/src/resources/previews/trademark-policy.jpg b/frontend/src/resources/previews/trademark-policy.jpg deleted file mode 100644 index d9fd24155e6..00000000000 Binary files a/frontend/src/resources/previews/trademark-policy.jpg and /dev/null differ diff --git a/frontend/src/resources/previews/tx-push.jpg b/frontend/src/resources/previews/tx-push.jpg deleted file mode 100644 index f035f9d80ad..00000000000 Binary files a/frontend/src/resources/previews/tx-push.jpg and /dev/null differ diff --git a/frontend/src/resources/profile/bisq.svg b/frontend/src/resources/profile/bisq.svg deleted file mode 100644 index a0ea96c6e66..00000000000 --- a/frontend/src/resources/profile/bisq.svg +++ /dev/null @@ -1,18 +0,0 @@ - - - - bisq_logo_green - Created with Sketch. - - - - - - - - - - - - - diff --git a/frontend/src/resources/profile/bisq_network.png b/frontend/src/resources/profile/bisq_network.png deleted file mode 100644 index 93b7410b908..00000000000 Binary files a/frontend/src/resources/profile/bisq_network.png and /dev/null differ diff --git a/frontend/src/resources/profile/bitcoin-s.svg b/frontend/src/resources/profile/bitcoin-s.svg deleted file mode 100644 index 1f4210e4b29..00000000000 --- a/frontend/src/resources/profile/bitcoin-s.svg +++ /dev/null @@ -1,52 +0,0 @@ - - - - - - - - - - - - diff --git a/frontend/src/resources/profile/bitkey.svg b/frontend/src/resources/profile/bitkey.svg deleted file mode 100644 index 875436402ba..00000000000 --- a/frontend/src/resources/profile/bitkey.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/frontend/src/resources/profile/blixt.png b/frontend/src/resources/profile/blixt.png deleted file mode 100644 index da7b8e23b84..00000000000 Binary files a/frontend/src/resources/profile/blixt.png and /dev/null differ diff --git a/frontend/src/resources/profile/bluewallet.png b/frontend/src/resources/profile/bluewallet.png deleted file mode 100644 index 30d6493a44f..00000000000 Binary files a/frontend/src/resources/profile/bluewallet.png and /dev/null differ diff --git a/frontend/src/resources/profile/blw.png b/frontend/src/resources/profile/blw.png deleted file mode 100644 index 015d8677749..00000000000 Binary files a/frontend/src/resources/profile/blw.png and /dev/null differ diff --git a/frontend/src/resources/profile/boltz.svg b/frontend/src/resources/profile/boltz.svg deleted file mode 100644 index 713209500e4..00000000000 --- a/frontend/src/resources/profile/boltz.svg +++ /dev/null @@ -1,24 +0,0 @@ - - - - Group - Created with Sketch. - - - - - - - - - - - - - \ No newline at end of file diff --git a/frontend/src/resources/profile/btcpayserver.svg b/frontend/src/resources/profile/btcpayserver.svg deleted file mode 100644 index 1c18a4cfe31..00000000000 --- a/frontend/src/resources/profile/btcpayserver.svg +++ /dev/null @@ -1 +0,0 @@ -BTCPayServer diff --git a/frontend/src/resources/profile/cake-wallet.svg b/frontend/src/resources/profile/cake-wallet.svg deleted file mode 100644 index 2b3f84f07c4..00000000000 --- a/frontend/src/resources/profile/cake-wallet.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/frontend/src/resources/profile/coldcard.png b/frontend/src/resources/profile/coldcard.png deleted file mode 100644 index 1f4118747cd..00000000000 Binary files a/frontend/src/resources/profile/coldcard.png and /dev/null differ diff --git a/frontend/src/resources/profile/copa.png b/frontend/src/resources/profile/copa.png deleted file mode 100644 index 49616d70014..00000000000 Binary files a/frontend/src/resources/profile/copa.png and /dev/null differ diff --git a/frontend/src/resources/profile/edge.svg b/frontend/src/resources/profile/edge.svg deleted file mode 100644 index 1bd8f4e706f..00000000000 --- a/frontend/src/resources/profile/edge.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/frontend/src/resources/profile/electrum.png b/frontend/src/resources/profile/electrum.png deleted file mode 100644 index ca24d5f45f6..00000000000 Binary files a/frontend/src/resources/profile/electrum.png and /dev/null differ diff --git a/frontend/src/resources/profile/galoy.svg b/frontend/src/resources/profile/galoy.svg deleted file mode 100644 index a833d7d4d36..00000000000 --- a/frontend/src/resources/profile/galoy.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/frontend/src/resources/profile/gnuagplv3.svg b/frontend/src/resources/profile/gnuagplv3.svg deleted file mode 100644 index 505d940dbcd..00000000000 --- a/frontend/src/resources/profile/gnuagplv3.svg +++ /dev/null @@ -1,51 +0,0 @@ - -Layer 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/frontend/src/resources/profile/grumpy.svg b/frontend/src/resources/profile/grumpy.svg deleted file mode 100644 index 5de128db1d6..00000000000 --- a/frontend/src/resources/profile/grumpy.svg +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - diff --git a/frontend/src/resources/profile/leather.svg b/frontend/src/resources/profile/leather.svg deleted file mode 100644 index a909606fa0a..00000000000 --- a/frontend/src/resources/profile/leather.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/frontend/src/resources/profile/liquid.svg b/frontend/src/resources/profile/liquid.svg deleted file mode 100644 index f0dd684f5a9..00000000000 --- a/frontend/src/resources/profile/liquid.svg +++ /dev/null @@ -1,39 +0,0 @@ - - - brand/logo-products/liquid - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/frontend/src/resources/profile/lnbits.svg b/frontend/src/resources/profile/lnbits.svg deleted file mode 100644 index 0969df92785..00000000000 --- a/frontend/src/resources/profile/lnbits.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/frontend/src/resources/profile/marina.svg b/frontend/src/resources/profile/marina.svg deleted file mode 100644 index 6a45790a3ba..00000000000 --- a/frontend/src/resources/profile/marina.svg +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - diff --git a/frontend/src/resources/profile/mercury.svg b/frontend/src/resources/profile/mercury.svg deleted file mode 100644 index 35af2b8a734..00000000000 --- a/frontend/src/resources/profile/mercury.svg +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - diff --git a/frontend/src/resources/profile/mutiny.svg b/frontend/src/resources/profile/mutiny.svg deleted file mode 100644 index 676c4d72cf5..00000000000 --- a/frontend/src/resources/profile/mutiny.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/frontend/src/resources/profile/muun.png b/frontend/src/resources/profile/muun.png deleted file mode 100644 index 91079d821f6..00000000000 Binary files a/frontend/src/resources/profile/muun.png and /dev/null differ diff --git a/frontend/src/resources/profile/mynodebtc.png b/frontend/src/resources/profile/mynodebtc.png deleted file mode 100644 index db31786ce2b..00000000000 Binary files a/frontend/src/resources/profile/mynodebtc.png and /dev/null differ diff --git a/frontend/src/resources/profile/nirvati.svg b/frontend/src/resources/profile/nirvati.svg deleted file mode 100644 index 3089d1d4c94..00000000000 --- a/frontend/src/resources/profile/nirvati.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/frontend/src/resources/profile/nix-bitcoin.png b/frontend/src/resources/profile/nix-bitcoin.png deleted file mode 100644 index cd8d3e9d726..00000000000 Binary files a/frontend/src/resources/profile/nix-bitcoin.png and /dev/null differ diff --git a/frontend/src/resources/profile/nunchuk.svg b/frontend/src/resources/profile/nunchuk.svg deleted file mode 100644 index 0b46b53558f..00000000000 --- a/frontend/src/resources/profile/nunchuk.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/frontend/src/resources/profile/onbtc-full.svg b/frontend/src/resources/profile/onbtc-full.svg deleted file mode 100644 index 2c299969232..00000000000 --- a/frontend/src/resources/profile/onbtc-full.svg +++ /dev/null @@ -1,318 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/frontend/src/resources/profile/onramp.png b/frontend/src/resources/profile/onramp.png deleted file mode 100644 index fc3a37f1cb1..00000000000 Binary files a/frontend/src/resources/profile/onramp.png and /dev/null differ diff --git a/frontend/src/resources/profile/phoenix.svg b/frontend/src/resources/profile/phoenix.svg deleted file mode 100644 index 917bd4fbaf9..00000000000 --- a/frontend/src/resources/profile/phoenix.svg +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - - - - diff --git a/frontend/src/resources/profile/raspiblitz.svg b/frontend/src/resources/profile/raspiblitz.svg deleted file mode 100644 index 3b335e56a73..00000000000 --- a/frontend/src/resources/profile/raspiblitz.svg +++ /dev/null @@ -1 +0,0 @@ -RaspiBlitz_Logo_Icon_Negative diff --git a/frontend/src/resources/profile/raspibolt.jpg b/frontend/src/resources/profile/raspibolt.jpg deleted file mode 100644 index 2f626e56351..00000000000 Binary files a/frontend/src/resources/profile/raspibolt.jpg and /dev/null differ diff --git a/frontend/src/resources/profile/ronindojo.png b/frontend/src/resources/profile/ronindojo.png deleted file mode 100644 index 1c3776de326..00000000000 Binary files a/frontend/src/resources/profile/ronindojo.png and /dev/null differ diff --git a/frontend/src/resources/profile/satpile.jpg b/frontend/src/resources/profile/satpile.jpg deleted file mode 100644 index 0bdd2dc2a13..00000000000 Binary files a/frontend/src/resources/profile/satpile.jpg and /dev/null differ diff --git a/frontend/src/resources/profile/schildbach.svg b/frontend/src/resources/profile/schildbach.svg deleted file mode 100644 index 976deec8865..00000000000 --- a/frontend/src/resources/profile/schildbach.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/frontend/src/resources/profile/softsimon.jpg b/frontend/src/resources/profile/softsimon.jpg deleted file mode 100644 index 0671f663b2b..00000000000 Binary files a/frontend/src/resources/profile/softsimon.jpg and /dev/null differ diff --git a/frontend/src/resources/profile/sparrow.png b/frontend/src/resources/profile/sparrow.png deleted file mode 100644 index cff0fd30258..00000000000 Binary files a/frontend/src/resources/profile/sparrow.png and /dev/null differ diff --git a/frontend/src/resources/profile/specter.png b/frontend/src/resources/profile/specter.png deleted file mode 100644 index 3dc6e822a1f..00000000000 Binary files a/frontend/src/resources/profile/specter.png and /dev/null differ diff --git a/frontend/src/resources/profile/start9.png b/frontend/src/resources/profile/start9.png deleted file mode 100644 index 345a9869cf3..00000000000 Binary files a/frontend/src/resources/profile/start9.png and /dev/null differ diff --git a/frontend/src/resources/profile/umbrel.png b/frontend/src/resources/profile/umbrel.png deleted file mode 100644 index 32b0ad63d1e..00000000000 Binary files a/frontend/src/resources/profile/umbrel.png and /dev/null differ diff --git a/frontend/src/resources/profile/unknown.svg b/frontend/src/resources/profile/unknown.svg deleted file mode 100644 index 236f054c45a..00000000000 --- a/frontend/src/resources/profile/unknown.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/frontend/src/resources/profile/wiz.png b/frontend/src/resources/profile/wiz.png deleted file mode 100644 index 537eb5552b3..00000000000 Binary files a/frontend/src/resources/profile/wiz.png and /dev/null differ diff --git a/frontend/src/resources/profile/wizardhat.png b/frontend/src/resources/profile/wizardhat.png deleted file mode 100644 index d385a56fa5c..00000000000 Binary files a/frontend/src/resources/profile/wizardhat.png and /dev/null differ diff --git a/frontend/src/resources/profile/zeus.png b/frontend/src/resources/profile/zeus.png deleted file mode 100644 index 363b93b66cd..00000000000 Binary files a/frontend/src/resources/profile/zeus.png and /dev/null differ diff --git a/frontend/src/resources/promo-video/mempool-promo.jpg b/frontend/src/resources/promo-video/mempool-promo.jpg deleted file mode 100644 index 40715b507fb..00000000000 Binary files a/frontend/src/resources/promo-video/mempool-promo.jpg and /dev/null differ diff --git a/frontend/src/resources/river/android-chrome-192x192.png b/frontend/src/resources/river/android-chrome-192x192.png deleted file mode 100644 index d93e04f571b..00000000000 Binary files a/frontend/src/resources/river/android-chrome-192x192.png and /dev/null differ diff --git a/frontend/src/resources/river/android-chrome-512x512.png b/frontend/src/resources/river/android-chrome-512x512.png deleted file mode 100644 index 6fe2c476bea..00000000000 Binary files a/frontend/src/resources/river/android-chrome-512x512.png and /dev/null differ diff --git a/frontend/src/resources/river/apple-touch-icon.png b/frontend/src/resources/river/apple-touch-icon.png deleted file mode 100644 index f6d00003986..00000000000 Binary files a/frontend/src/resources/river/apple-touch-icon.png and /dev/null differ diff --git a/frontend/src/resources/river/favicon-16x16.png b/frontend/src/resources/river/favicon-16x16.png deleted file mode 100644 index 9820793f1b3..00000000000 Binary files a/frontend/src/resources/river/favicon-16x16.png and /dev/null differ diff --git a/frontend/src/resources/river/favicon-32x32.png b/frontend/src/resources/river/favicon-32x32.png deleted file mode 100644 index 49ac8b1b0af..00000000000 Binary files a/frontend/src/resources/river/favicon-32x32.png and /dev/null differ diff --git a/frontend/src/resources/river/favicon.ico b/frontend/src/resources/river/favicon.ico deleted file mode 100644 index 7d109754b72..00000000000 Binary files a/frontend/src/resources/river/favicon.ico and /dev/null differ diff --git a/frontend/src/resources/river/river-preview.png b/frontend/src/resources/river/river-preview.png deleted file mode 100644 index 71ac9867346..00000000000 Binary files a/frontend/src/resources/river/river-preview.png and /dev/null differ diff --git a/frontend/src/resources/river/site.webmanifest b/frontend/src/resources/river/site.webmanifest deleted file mode 100644 index 45dc8a20658..00000000000 --- a/frontend/src/resources/river/site.webmanifest +++ /dev/null @@ -1 +0,0 @@ -{"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"} \ No newline at end of file diff --git a/frontend/src/resources/riverlogo.svg b/frontend/src/resources/riverlogo.svg deleted file mode 100644 index 3a6e28ce8a1..00000000000 --- a/frontend/src/resources/riverlogo.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/frontend/src/resources/screenshots/v2.1.0-dashboard.png b/frontend/src/resources/screenshots/v2.1.0-dashboard.png deleted file mode 100644 index 768d99918dc..00000000000 Binary files a/frontend/src/resources/screenshots/v2.1.0-dashboard.png and /dev/null differ diff --git a/frontend/src/resources/screenshots/v2.2.0-dashboard.png b/frontend/src/resources/screenshots/v2.2.0-dashboard.png deleted file mode 100644 index a9b49c6f0b5..00000000000 Binary files a/frontend/src/resources/screenshots/v2.2.0-dashboard.png and /dev/null differ diff --git a/frontend/src/resources/screenshots/v2.2.1-dashboard.png b/frontend/src/resources/screenshots/v2.2.1-dashboard.png deleted file mode 100644 index c0b92740623..00000000000 Binary files a/frontend/src/resources/screenshots/v2.2.1-dashboard.png and /dev/null differ diff --git a/frontend/src/resources/screenshots/v2.3.0-dashboard.png b/frontend/src/resources/screenshots/v2.3.0-dashboard.png deleted file mode 100644 index 1bef6eedc2c..00000000000 Binary files a/frontend/src/resources/screenshots/v2.3.0-dashboard.png and /dev/null differ diff --git a/frontend/src/resources/screenshots/v2.4.0-dashboard.png b/frontend/src/resources/screenshots/v2.4.0-dashboard.png deleted file mode 100644 index 472e6f6159a..00000000000 Binary files a/frontend/src/resources/screenshots/v2.4.0-dashboard.png and /dev/null differ diff --git a/frontend/src/resources/strategy/favicons/android-chrome-192x192.png b/frontend/src/resources/strategy/favicons/android-chrome-192x192.png deleted file mode 100644 index 364971248c1..00000000000 Binary files a/frontend/src/resources/strategy/favicons/android-chrome-192x192.png and /dev/null differ diff --git a/frontend/src/resources/strategy/favicons/android-chrome-512x512.png b/frontend/src/resources/strategy/favicons/android-chrome-512x512.png deleted file mode 100644 index c6b800ada99..00000000000 Binary files a/frontend/src/resources/strategy/favicons/android-chrome-512x512.png and /dev/null differ diff --git a/frontend/src/resources/strategy/favicons/apple-touch-icon.png b/frontend/src/resources/strategy/favicons/apple-touch-icon.png deleted file mode 100644 index dd9e1bdfcf7..00000000000 Binary files a/frontend/src/resources/strategy/favicons/apple-touch-icon.png and /dev/null differ diff --git a/frontend/src/resources/strategy/favicons/favicon-16x16.png b/frontend/src/resources/strategy/favicons/favicon-16x16.png deleted file mode 100644 index c01de5c3a14..00000000000 Binary files a/frontend/src/resources/strategy/favicons/favicon-16x16.png and /dev/null differ diff --git a/frontend/src/resources/strategy/favicons/favicon-32x32.png b/frontend/src/resources/strategy/favicons/favicon-32x32.png deleted file mode 100644 index 8dd48037df7..00000000000 Binary files a/frontend/src/resources/strategy/favicons/favicon-32x32.png and /dev/null differ diff --git a/frontend/src/resources/strategy/favicons/favicon.ico b/frontend/src/resources/strategy/favicons/favicon.ico deleted file mode 100644 index 083692ec8b7..00000000000 Binary files a/frontend/src/resources/strategy/favicons/favicon.ico and /dev/null differ diff --git a/frontend/src/resources/strategy/favicons/site.webmanifest b/frontend/src/resources/strategy/favicons/site.webmanifest deleted file mode 100644 index 45dc8a20658..00000000000 --- a/frontend/src/resources/strategy/favicons/site.webmanifest +++ /dev/null @@ -1 +0,0 @@ -{"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"} \ No newline at end of file diff --git a/frontend/src/resources/strategy/strategy-preview.png b/frontend/src/resources/strategy/strategy-preview.png deleted file mode 100644 index 83e4b3d04a6..00000000000 Binary files a/frontend/src/resources/strategy/strategy-preview.png and /dev/null differ diff --git a/frontend/src/resources/strategylogo.png b/frontend/src/resources/strategylogo.png deleted file mode 100644 index a5b06bd1c62..00000000000 Binary files a/frontend/src/resources/strategylogo.png and /dev/null differ diff --git a/frontend/src/resources/wiz.png b/frontend/src/resources/wiz.png deleted file mode 100644 index 1058f0b5c8c..00000000000 Binary files a/frontend/src/resources/wiz.png and /dev/null differ diff --git a/frontend/src/resources/xxi/favicons/android-chrome-192x192.png b/frontend/src/resources/xxi/favicons/android-chrome-192x192.png deleted file mode 100644 index c435b91dabc..00000000000 Binary files a/frontend/src/resources/xxi/favicons/android-chrome-192x192.png and /dev/null differ diff --git a/frontend/src/resources/xxi/favicons/android-chrome-512x512.png b/frontend/src/resources/xxi/favicons/android-chrome-512x512.png deleted file mode 100644 index 8421218be70..00000000000 Binary files a/frontend/src/resources/xxi/favicons/android-chrome-512x512.png and /dev/null differ diff --git a/frontend/src/resources/xxi/favicons/apple-touch-icon.png b/frontend/src/resources/xxi/favicons/apple-touch-icon.png deleted file mode 100644 index 7b4c8a622c3..00000000000 Binary files a/frontend/src/resources/xxi/favicons/apple-touch-icon.png and /dev/null differ diff --git a/frontend/src/resources/xxi/favicons/favicon-16x16.png b/frontend/src/resources/xxi/favicons/favicon-16x16.png deleted file mode 100644 index 63d8ccf1a6f..00000000000 Binary files a/frontend/src/resources/xxi/favicons/favicon-16x16.png and /dev/null differ diff --git a/frontend/src/resources/xxi/favicons/favicon-32x32.png b/frontend/src/resources/xxi/favicons/favicon-32x32.png deleted file mode 100644 index bc275639ced..00000000000 Binary files a/frontend/src/resources/xxi/favicons/favicon-32x32.png and /dev/null differ diff --git a/frontend/src/resources/xxi/favicons/favicon.ico b/frontend/src/resources/xxi/favicons/favicon.ico deleted file mode 100644 index b7ea1f5cd2a..00000000000 Binary files a/frontend/src/resources/xxi/favicons/favicon.ico and /dev/null differ diff --git a/frontend/src/resources/xxi/favicons/site.webmanifest b/frontend/src/resources/xxi/favicons/site.webmanifest deleted file mode 100644 index 45dc8a20658..00000000000 --- a/frontend/src/resources/xxi/favicons/site.webmanifest +++ /dev/null @@ -1 +0,0 @@ -{"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"} \ No newline at end of file diff --git a/frontend/src/resources/xxi/xxi-preview.jpg b/frontend/src/resources/xxi/xxi-preview.jpg deleted file mode 100644 index ce1d822cf1b..00000000000 Binary files a/frontend/src/resources/xxi/xxi-preview.jpg and /dev/null differ diff --git a/frontend/src/resources/xxi/xxilogo.png b/frontend/src/resources/xxi/xxilogo.png deleted file mode 100644 index a6a59415095..00000000000 Binary files a/frontend/src/resources/xxi/xxilogo.png and /dev/null differ diff --git a/frontend/src/styles.scss b/frontend/src/styles.scss index 4225662c618..7cd70cf981b 100644 --- a/frontend/src/styles.scss +++ b/frontend/src/styles.scss @@ -1,4 +1,6 @@ @use "sass:color"; +@use "styles/universe-tokens" as universe; +@use "styles/universe-bootstrap-bridge" as universe-bridge; /* Theme */ $bg: #11131f; @@ -91,63 +93,16 @@ $dropdown-link-active-bg: $active-bg; border: 1px solid #20263e !important; } +// Light is the default experience, so it is defined here on :root rather than +// in a stylesheet that has to be fetched. That is what makes the primary theme +// paint on first frame with no flash of a colour the visitor did not choose. :root { - --bg: #{$bg}; - --active-bg: #{$active-bg}; - --hover-bg: #{$hover-bg}; - --fg: #{$fg}; - --nav-bg: #{$nav-bg}; - --title-fg: #{$title-fg}; - - --primary: #{$primary}; - --secondary: #{$secondary}; - --tertiary: #{$tertiary}; - --success: #{$success}; - --info: #{$info}; - --link-color: #{$link-color}; - --link-hover-color: #{$link-hover-color}; - --icon: #f1f1f1; - --skeleton-bg: #2e324e; - --skeleton-bg-light: #5d6182; - - --box-bg: #171c2a; - --stat-box-bg: #0b1018; - --alert-bg: #3a1c61; - --navbar-bg: #212121; - --transparent-fg: #ffffffbb; - --fade-out-box-bg-start: rgba(23, 28, 42, 0); - --fade-out-box-bg-end: rgba(23, 28, 42, 1); - --opacity: 0.57; - - --testnet: #1d486f; - --signet: #6f1d5d; - --regtest: #7d7d7d; - --liquid: #116761; - --liquidtestnet: #494a4a; - - --mainnet-alt: #9339f4; - --testnet-alt: #183550; - --signet-alt: #471850; - --regtest-alt: #4a4a4a; - --liquidtestnet-alt: #272e46; - - --taproot: #eba814; - --taproot-light: #d5a90a; - --taproot-dark: #9d7c05; - - --green: #83fd00; - --red: #ff3d00; - --yellow: #fff000; - --grey: #7e7e7e; - --tooltip-grey: #b1b1b1; - --orange: #ff9f00; - - --search-button: #4d2d77; - --search-button-border: #472a6e; - --search-button-focus: #533180; - --search-button-shadow: #7c58ab80; + @include universe.universe-invariant-tokens; + @include universe.universe-light-tokens; + @include universe.universe-legacy-bridge; } + html, body { height: 100%; } @@ -1451,3 +1406,6 @@ a { button { touch-action: manipulation; } + +// Repaint the inherited Bootstrap layer from the tokens above. Must stay last. +@include universe-bridge.universe-bootstrap-bridge; diff --git a/frontend/src/styles/_universe-bootstrap-bridge.scss b/frontend/src/styles/_universe-bootstrap-bridge.scss new file mode 100644 index 00000000000..7c4081ad32a --- /dev/null +++ b/frontend/src/styles/_universe-bootstrap-bridge.scss @@ -0,0 +1,344 @@ +// Repaint the inherited Bootstrap 4 layer from Universe tokens. +// +// Bootstrap is compiled once, so its component rules carry literal colours that +// no theme file can reach. Every surface it paints is restated here in terms of +// --u-* tokens and loaded after it, which is what makes a theme swap repaint +// cards, tables, dropdowns, and form controls instead of leaving dark rectangles +// on a light page. +// +// Scope is deliberately narrow: only the components this product actually +// renders, and only the properties that carry colour. Layout, spacing, and +// behaviour are left to Bootstrap. + +@mixin universe-bootstrap-bridge { + // --- Page ------------------------------------------------------------------ + + body { + background-color: var(--u-surface-page); + color: var(--u-text-primary); + font-family: var(--u-font-text); + } + + hr { + border-top-color: var(--u-divider); + } + + a { + color: var(--u-brand); + + &:hover, + &:focus { + color: var(--u-brand-hover); + } + } + + // --- Cards ----------------------------------------------------------------- + + .card { + background-color: var(--u-surface-raised); + border: 1px solid var(--u-border); + color: var(--u-text-primary); + } + + .card-header, + .card-footer { + background-color: var(--u-surface-sunken); + border-color: var(--u-border); + } + + // --- Tables ---------------------------------------------------------------- + + .table { + color: var(--u-text-primary); + + th, + td { + border-top-color: var(--u-divider); + } + + thead th { + border-bottom-color: var(--u-border); + color: var(--u-text-muted); + } + } + + .table-striped tbody tr:nth-of-type(odd) { + background-color: var(--u-surface-hover); + } + + .table-hover tbody tr:hover { + background-color: var(--u-surface-hover); + color: var(--u-text-primary); + } + + // --- Forms ----------------------------------------------------------------- + + .form-control { + background-color: var(--u-surface-raised); + border-color: var(--u-border-strong); + color: var(--u-text-primary); + + &::placeholder { + color: var(--u-text-muted); + opacity: 1; + } + + &:focus { + background-color: var(--u-surface-raised); + border-color: var(--u-brand); + color: var(--u-text-primary); + box-shadow: 0 0 0 3px var(--u-brand-border); + } + + &:disabled, + &[readonly] { + background-color: var(--u-surface-inset); + color: var(--u-text-muted); + } + } + + .custom-select { + background-color: var(--u-surface-raised); + border-color: var(--u-border-strong); + color: var(--u-text-primary); + } + + .input-group-text { + background-color: var(--u-surface-sunken) !important; + border: 1px solid var(--u-border-strong) !important; + color: var(--u-text-secondary); + } + + // --- Dropdowns ------------------------------------------------------------- + + .dropdown-menu { + background-color: var(--u-surface-raised); + border: 1px solid var(--u-border); + box-shadow: var(--u-shadow-lg); + color: var(--u-text-primary); + } + + .dropdown-item { + color: var(--u-text-primary); + + &:hover, + &:focus { + background-color: var(--u-surface-hover); + color: var(--u-text-primary); + } + + &.active, + &:active { + background-color: var(--u-brand-subtle); + color: var(--u-brand); + } + } + + .dropdown-divider { + border-top-color: var(--u-divider); + } + + // --- Buttons --------------------------------------------------------------- + + .btn-primary { + background-color: var(--u-brand); + border-color: var(--u-brand); + color: var(--u-brand-contrast); + + &:hover, + &:focus, + &:not(:disabled):not(.disabled):active { + background-color: var(--u-brand-hover); + border-color: var(--u-brand-hover); + color: var(--u-brand-contrast); + } + } + + .btn-secondary { + background-color: var(--u-surface-inset); + border-color: var(--u-border-strong); + color: var(--u-text-primary); + + &:hover, + &:focus, + &:not(:disabled):not(.disabled):active { + background-color: var(--u-surface-active); + border-color: var(--u-border-strong); + color: var(--u-text-primary); + } + } + + .btn-link { + color: var(--u-brand); + + &:hover { + color: var(--u-brand-hover); + } + } + + // --- Badges ---------------------------------------------------------------- + // + // Bootstrap badges arrive as flat colour blocks with no words of their own. + // Every status treatment in this product pairs a tint with a border so it stays + // legible where colour alone would not carry, including in print. + + .badge-primary { + border: 1px solid; + font-weight: var(--u-weight-semibold); + background-color: var(--u-brand-subtle); + border-color: var(--u-brand-border); + color: var(--u-brand); + } + + .badge-secondary { + border: 1px solid; + font-weight: var(--u-weight-semibold); + background-color: var(--u-state-neutral-surface); + border-color: var(--u-state-neutral-border); + color: var(--u-state-neutral); + } + + .badge-success { + border: 1px solid; + font-weight: var(--u-weight-semibold); + background-color: var(--u-state-proven-surface); + border-color: var(--u-state-proven-border); + color: var(--u-state-proven); + } + + .badge-info { + border: 1px solid; + font-weight: var(--u-weight-semibold); + background-color: var(--u-state-pending-surface); + border-color: var(--u-state-pending-border); + color: var(--u-state-pending); + } + + .badge-warning { + border: 1px solid; + font-weight: var(--u-weight-semibold); + background-color: var(--u-state-partial-surface); + border-color: var(--u-state-partial-border); + color: var(--u-state-partial); + } + + .badge-danger { + border: 1px solid; + font-weight: var(--u-weight-semibold); + background-color: var(--u-state-unavailable-surface); + border-color: var(--u-state-unavailable-border); + color: var(--u-state-unavailable); + } + + // --- Overlays -------------------------------------------------------------- + + .modal-content { + background-color: var(--u-surface-raised); + border: 1px solid var(--u-border); + color: var(--u-text-primary); + } + + .modal-header, + .modal-footer { + border-color: var(--u-border); + } + + .close { + color: var(--u-text-secondary); + text-shadow: none; + + &:hover { + color: var(--u-text-primary); + } + } + + .tooltip-inner, + .popover { + background-color: var(--u-surface-raised); + border: 1px solid var(--u-border); + box-shadow: var(--u-shadow-md); + color: var(--u-text-primary); + } + + .popover-body { + color: var(--u-text-primary); + } + + // --- Navigation ------------------------------------------------------------ + + .nav-tabs { + border-bottom-color: var(--u-border); + + .nav-link { + color: var(--u-text-secondary); + + &:hover { + border-color: transparent transparent var(--u-border-strong); + color: var(--u-text-primary); + } + + &.active { + background-color: var(--u-surface-raised); + border-color: var(--u-border) var(--u-border) var(--u-surface-raised); + color: var(--u-text-primary); + } + } + } + + .pagination { + .page-link { + background-color: var(--u-surface-raised); + border-color: var(--u-border); + color: var(--u-brand); + + &:hover { + background-color: var(--u-surface-hover); + border-color: var(--u-border-strong); + } + } + + .page-item.active .page-link { + background-color: var(--u-brand); + border-color: var(--u-brand); + color: var(--u-brand-contrast); + } + + .page-item.disabled .page-link { + background-color: var(--u-surface-inset); + border-color: var(--u-border); + color: var(--u-text-muted); + } + } + + .list-group-item { + background-color: var(--u-surface-raised); + border-color: var(--u-border); + color: var(--u-text-primary); + } + + // --- Progress -------------------------------------------------------------- + + .progress { + background-color: var(--u-surface-inset); + } + + // --- Focus ----------------------------------------------------------------- + // + // One visible focus treatment for every interactive element. Bootstrap 4 hides + // focus on several controls; keyboard users need it back, and it must be + // visible against both themes, which is why the ring is not the brand colour. + + :focus-visible { + outline: 2px solid var(--u-focus-ring); + outline-offset: 2px; + } + + .btn:focus-visible, + .form-control:focus-visible, + .dropdown-item:focus-visible, + .page-link:focus-visible, + .nav-link:focus-visible { + outline: 2px solid var(--u-focus-ring); + outline-offset: 2px; + } +} diff --git a/frontend/src/styles/_universe-tokens.scss b/frontend/src/styles/_universe-tokens.scss new file mode 100644 index 00000000000..e1807b7cd10 --- /dev/null +++ b/frontend/src/styles/_universe-tokens.scss @@ -0,0 +1,370 @@ +// Universe Explorer design tokens. +// +// One source for colour, type, space, motion, and layer across the whole +// application. Everything here is emitted as CSS custom properties so a theme +// swap is a variable swap, never a rebuild of component styles. +// +// Two rules hold the system together: +// +// 1. Colour carries evidence state, never protocol identity on its own. +// Protocol hues live in their own scale and always appear next to a +// protocol name. Evidence states always carry a word. That separation is +// why a protocol's colour can never be mistaken for "confirmed" or +// "failed". +// +// 2. Light is the primary experience. The light palette is defined on :root +// so it needs no stylesheet fetch and cannot flash. Dark restates the same +// token names with its own values and is held to the same contrast floor. +// +// Contrast: every text token below clears WCAG 2.2 AA (4.5:1 for body, 3:1 for +// large text and non-text indicators) against the surface it is designed for. + +// --------------------------------------------------------------------------- +// Scales that do not change between themes +// --------------------------------------------------------------------------- + +@mixin universe-invariant-tokens { + // Space. A 4px base keeps dense financial tables on a predictable rhythm. + --u-space-1: 0.25rem; + --u-space-2: 0.5rem; + --u-space-3: 0.75rem; + --u-space-4: 1rem; + --u-space-5: 1.5rem; + --u-space-6: 2rem; + --u-space-7: 3rem; + + // Radius. Restrained on purpose: this is an instrument, not a card gallery. + --u-radius-sm: 3px; + --u-radius-md: 5px; + --u-radius-lg: 8px; + --u-radius-pill: 999px; + + // Type. A readable text face and a purposeful data face. Both resolve to + // system stacks so nothing is fetched from a third-party font host. + --u-font-text: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", + Arial, "Noto Sans", sans-serif; + --u-font-data: ui-monospace, "SF Mono", "Cascadia Mono", "Segoe UI Mono", + "Roboto Mono", Menlo, Consolas, monospace; + + --u-text-2xs: 0.6875rem; + --u-text-xs: 0.75rem; + --u-text-sm: 0.8125rem; + --u-text-base: 0.9375rem; + --u-text-md: 1rem; + --u-text-lg: 1.125rem; + --u-text-xl: 1.375rem; + --u-text-2xl: 1.75rem; + + --u-leading-tight: 1.2; + --u-leading-snug: 1.35; + --u-leading-normal: 1.55; + + --u-weight-normal: 400; + --u-weight-medium: 500; + --u-weight-semibold: 600; + --u-weight-bold: 700; + + // Motion. Durations are short because every animation here reports a fact + // (a transaction arrived, a block confirmed, a fee moved). Nothing decorative + // is allowed to delay reading the number underneath it. + --u-duration-instant: 90ms; + --u-duration-fast: 160ms; + --u-duration-base: 240ms; + --u-duration-slow: 420ms; + --u-ease-out: cubic-bezier(0.22, 0.61, 0.36, 1); + --u-ease-in-out: cubic-bezier(0.65, 0, 0.35, 1); + + // Layout + --u-width-prose: 68ch; + --u-width-page: 1320px; + + // Layers. Named so a new overlay never has to guess a number. + --u-z-base: 0; + --u-z-sticky: 100; + --u-z-header: 200; + --u-z-dropdown: 300; + --u-z-overlay: 400; + --u-z-toast: 500; +} + +// --------------------------------------------------------------------------- +// Light theme: the primary experience +// --------------------------------------------------------------------------- + +@mixin universe-light-tokens { + color-scheme: light; + + // Surfaces run from the page floor up. Cards are white so elevation reads + // without a shadow, which keeps dense tables crisp. + --u-surface-page: #f4f6f9; + --u-surface-raised: #ffffff; + --u-surface-sunken: #e9edf3; + --u-surface-inset: #dfe5ee; + --u-surface-hover: #eef2f7; + --u-surface-active: #e3e9f2; + + // Text. Primary is near-black with a cool cast so it sits with the blues + // rather than fighting them. + --u-text-primary: #10151f; // 16.8:1 on raised + --u-text-secondary: #414d61; // 8.9:1 on raised + --u-text-muted: #5c6879; // 5.7:1 on raised + --u-text-inverse: #ffffff; + + --u-border: #d5dce6; + --u-border-strong: #b6c1d0; + --u-divider: #e4e9f0; + + // Brand. Ultramarine rather than the crypto-default violet: it reads as + // instrumentation, and it is far enough from every status hue to be used for + // structure (links, active nav, focus) without ever implying a state. + --u-brand: #2438b8; + --u-brand-hover: #1b2b93; + --u-brand-contrast: #ffffff; + --u-brand-subtle: #e7ebfb; + --u-brand-border: #c3ccf3; + + // Focus. Deliberately not the brand colour so a focused brand-coloured + // control still shows a ring. + --u-focus-ring: #0a7ea4; + --u-focus-ring-offset: #ffffff; + + // Evidence states. These four must never be confusable: the product's whole + // claim rests on the difference between proven and merely observed. + --u-state-proven: #0f6b3a; + --u-state-proven-surface: #e3f4ea; + --u-state-proven-border: #a9d9bf; + + --u-state-partial: #8a5100; + --u-state-partial-surface: #fdf0dd; + --u-state-partial-border: #e6c491; + + --u-state-pending: #15547f; + --u-state-pending-surface: #e2eef7; + --u-state-pending-border: #a5c8e0; + + --u-state-unavailable: #a12420; + --u-state-unavailable-surface: #fbe8e7; + --u-state-unavailable-border: #eab3b0; + + --u-state-neutral: #55617a; + --u-state-neutral-surface: #eaeef4; + --u-state-neutral-border: #c6cfdd; + + // Protocol identity. Held apart from the state hues above, and only ever + // rendered beside a protocol name. Values are tuned for a light surface. + --u-protocol-ordinals: #9a4a06; + --u-protocol-runes: #0a6a7d; + --u-protocol-alkanes: #5b3bb5; + --u-protocol-stamps: #a3246b; + --u-protocol-atomicals: #0d6560; + --u-protocol-op-data: #7a3572; + --u-protocol-fallback: #4a5568; + + // Chart series. Ordered for categorical use and checked so neighbouring + // series stay distinguishable for the common colour vision deficiencies. + --u-chart-1: #2438b8; + --u-chart-2: #0a7ea4; + --u-chart-3: #9a4a06; + --u-chart-4: #0f6b3a; + --u-chart-5: #7a3572; + --u-chart-6: #a3246b; + --u-chart-7: #55617a; + --u-chart-grid: #dde3ec; + --u-chart-axis: #5c6879; + + // Elevation. Soft and low: this is a data surface, not a floating card deck. + --u-shadow-sm: 0 1px 2px rgba(16, 21, 31, 0.07); + --u-shadow-md: 0 2px 8px rgba(16, 21, 31, 0.09); + --u-shadow-lg: 0 8px 24px rgba(16, 21, 31, 0.13); + + // A wash used behind live regions so an update is noticeable without a flash. + --u-highlight-arrive: rgba(36, 56, 184, 0.09); + + // Loading placeholders. Low contrast on purpose: a skeleton must read as + // absent, never as content. + --u-skeleton: #dde3ec; + --u-skeleton-sheen: #eef2f7; + + // Network identity. Mainnet takes the brand; the test networks are visibly + // different from it and from each other so a testnet page can never be + // mistaken for mainnet. + --u-network-mainnet: #2438b8; + --u-network-testnet: #0a6a7d; + --u-network-testnet4: #0d6560; + --u-network-signet: #a3246b; + --u-network-regtest: #55617a; + --u-network-liquid: #0f6b3a; + --u-network-liquidtestnet: #5c6879; + + --u-taproot: #8a5100; + + // A translucent foreground for de-emphasised text over unknown backdrops. + --u-text-translucent: rgba(16, 21, 31, 0.62); + --u-fade-start: rgba(255, 255, 255, 0); + --u-fade-end: rgba(255, 255, 255, 1); +} + +// --------------------------------------------------------------------------- +// Dark theme: full parity, same token names, same contrast floor +// --------------------------------------------------------------------------- + +@mixin universe-dark-tokens { + color-scheme: dark; + + --u-surface-page: #12141f; + --u-surface-raised: #1a1e2d; + --u-surface-sunken: #0d0f18; + --u-surface-inset: #232838; + --u-surface-hover: #232839; + --u-surface-active: #2b3146; + + --u-text-primary: #f2f4f8; // 14.9:1 on raised + --u-text-secondary: #c0c8d8; // 8.7:1 on raised + --u-text-muted: #98a2b6; // 5.4:1 on raised + --u-text-inverse: #10151f; + + --u-border: #2e3549; + --u-border-strong: #414a63; + --u-divider: #262c3d; + + --u-brand: #8fa2ff; + --u-brand-hover: #adbaff; + --u-brand-contrast: #10151f; + --u-brand-subtle: #1e2340; + --u-brand-border: #384169; + + --u-focus-ring: #4fc3e8; + --u-focus-ring-offset: #1a1e2d; + + --u-state-proven: #5fd39a; + --u-state-proven-surface: #123227; + --u-state-proven-border: #2c6d51; + + --u-state-partial: #f0be62; + --u-state-partial-surface: #33260f; + --u-state-partial-border: #6d5527; + + --u-state-pending: #7cc0f0; + --u-state-pending-surface: #12283a; + --u-state-pending-border: #2b5878; + + --u-state-unavailable: #f2918a; + --u-state-unavailable-surface: #391b1a; + --u-state-unavailable-border: #743935; + + --u-state-neutral: #a3adc2; + --u-state-neutral-surface: #212735; + --u-state-neutral-border: #3c445a; + + --u-protocol-ordinals: #f0a463; + --u-protocol-runes: #6fcfe2; + --u-protocol-alkanes: #b6a5f5; + --u-protocol-stamps: #f19ac4; + --u-protocol-atomicals: #6fd3c9; + --u-protocol-op-data: #d79ad0; + --u-protocol-fallback: #b3bccd; + + --u-chart-1: #8fa2ff; + --u-chart-2: #4fc3e8; + --u-chart-3: #f0a463; + --u-chart-4: #5fd39a; + --u-chart-5: #d79ad0; + --u-chart-6: #f19ac4; + --u-chart-7: #a3adc2; + --u-chart-grid: #2a3145; + --u-chart-axis: #98a2b6; + + --u-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4); + --u-shadow-md: 0 2px 8px rgba(0, 0, 0, 0.45); + --u-shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.55); + + --u-highlight-arrive: rgba(143, 162, 255, 0.14); + + --u-skeleton: #262c3d; + --u-skeleton-sheen: #333b52; + + --u-network-mainnet: #8fa2ff; + --u-network-testnet: #6fcfe2; + --u-network-testnet4: #6fd3c9; + --u-network-signet: #f19ac4; + --u-network-regtest: #a3adc2; + --u-network-liquid: #5fd39a; + --u-network-liquidtestnet: #98a2b6; + + --u-taproot: #f0be62; + + --u-text-translucent: rgba(242, 244, 248, 0.66); + --u-fade-start: rgba(26, 30, 45, 0); + --u-fade-end: rgba(26, 30, 45, 1); +} + +// --------------------------------------------------------------------------- +// Bridge to the inherited variable names +// --------------------------------------------------------------------------- +// +// The application it grew from names its colours --bg, --box-bg, --fg and so +// on, and several hundred component rules read them. Mapping those names onto +// the tokens above is what lets a single theme swap repaint the whole product +// instead of requiring every component to be rewritten first. New work should +// use the --u-* tokens directly; these remain so nothing is left unpainted. + +@mixin universe-legacy-bridge { + --bg: var(--u-surface-page); + --active-bg: var(--u-surface-active); + --hover-bg: var(--u-surface-hover); + --fg: var(--u-text-primary); + --nav-bg: var(--u-surface-raised); + --navbar-bg: var(--u-surface-raised); + --title-fg: var(--u-brand); + + --box-bg: var(--u-surface-raised); + --stat-box-bg: var(--u-surface-sunken); + --alert-bg: var(--u-brand-subtle); + + --primary: var(--u-brand); + --secondary: var(--u-surface-inset); + --tertiary: var(--u-brand); + --success: var(--u-state-proven); + --info: var(--u-state-pending); + --link-color: var(--u-brand); + --link-hover-color: var(--u-brand-hover); + --icon: var(--u-text-secondary); + + --green: var(--u-state-proven); + --red: var(--u-state-unavailable); + --yellow: var(--u-state-partial); + --orange: var(--u-protocol-ordinals); + --grey: var(--u-state-neutral); + --tooltip-grey: var(--u-text-muted); + + --search-button: var(--u-brand); + --search-button-border: var(--u-brand); + --search-button-focus: var(--u-brand-hover); + --search-button-shadow: var(--u-brand-border); + + --font-mono: var(--u-font-data); + + --skeleton-bg: var(--u-skeleton); + --skeleton-bg-light: var(--u-skeleton-sheen); + --transparent-fg: var(--u-text-translucent); + --fade-out-box-bg-start: var(--u-fade-start); + --fade-out-box-bg-end: var(--u-fade-end); + --opacity: 0.57; + + --testnet: var(--u-network-testnet); + --testnet4: var(--u-network-testnet4); + --signet: var(--u-network-signet); + --regtest: var(--u-network-regtest); + --liquid: var(--u-network-liquid); + --liquidtestnet: var(--u-network-liquidtestnet); + + --mainnet-alt: var(--u-network-mainnet); + --testnet-alt: var(--u-network-testnet); + --signet-alt: var(--u-network-signet); + --regtest-alt: var(--u-network-regtest); + --liquidtestnet-alt: var(--u-network-liquidtestnet); + + --taproot: var(--u-taproot); + --taproot-light: var(--u-taproot); + --taproot-dark: var(--u-taproot); +} diff --git a/frontend/src/theme-contrast.scss b/frontend/src/theme-contrast.scss index 2a2d3f1a238..0a08d21d6da 100644 --- a/frontend/src/theme-contrast.scss +++ b/frontend/src/theme-contrast.scss @@ -1,116 +1,50 @@ -@use "sass:color"; +// Universe Explorer, high contrast. +// +// Dark with the contrast pushed well past the AA floor, for reading dense fee +// and transaction tables in bright rooms or on low-quality panels. It inherits +// the dark tokens and then raises only what needs raising: text against +// surface, borders, and the four evidence states, which are the colours a +// misread would actually cost something. -/* Theme */ -$bg: #11131f; -$active-bg: #000000; -$hover-bg: #12131e; -$fg: #fff; -$nav-bg: $bg; -$title-fg: #2055e3; - -$taproot: #eba814; -$taproot-light: #d5a90a; -$taproot-dark: #9d7c05; - -/* Bootstrap */ -$body-bg: $bg; -$body-color: $fg; -$gray-800: $bg; -$gray-700: $fg; - -$nav-tabs-link-active-bg: $active-bg; - -$primary: #007cfa; -$secondary: #272f4e; -$tertiary: #6225b2; -$success: #0aab2f; -$info: #00ddff; - -$h5-font-size: 1.15rem !default; - -$pagination-bg: $body-bg; -$pagination-border-color: $gray-800; -$pagination-disabled-bg: $fg; -$pagination-disabled-border-color: $bg; -$pagination-active-color: $fg; -$pagination-active-bg: $tertiary; -$pagination-hover-bg: $hover-bg; -$pagination-hover-border-color: $bg; -$pagination-disabled-bg: $bg; - -$custom-select-indicator-color: $fg; - -.input-group-text { - background-color: #1c2031 !important; - border: 1px solid #20263e !important; -} - -$link-color: $info; -$link-decoration: none !default; -$link-hover-color: color.adjust($link-color, $lightness: -15%) !default; -$link-hover-decoration: underline !default; - -$dropdown-bg: $bg; -$dropdown-link-color: $fg; - -$dropdown-link-hover-color: $fg; -$dropdown-link-hover-bg: $active-bg; - -$dropdown-link-active-color: $fg; -$dropdown-link-active-bg: $active-bg; +@use "styles/universe-tokens" as universe; :root { - --bg: #{$bg}; - --active-bg: #{$active-bg}; - --hover-bg: #{$hover-bg}; - --fg: #{$fg}; - --nav-bg: #{$nav-bg}; - --title-fg: #{$title-fg}; + @include universe.universe-invariant-tokens; + @include universe.universe-dark-tokens; + + // Push the surfaces apart and the text up. Text on raised reaches ~19:1. + --u-surface-page: #05070d; + --u-surface-raised: #0e1118; + --u-surface-sunken: #000000; + --u-surface-inset: #1a1f2b; + --u-surface-hover: #1c2230; + --u-surface-active: #252c3d; + + --u-text-primary: #ffffff; + --u-text-secondary: #dce3ee; + --u-text-muted: #b3bccd; + + --u-border: #48526b; + --u-border-strong: #6b7691; + --u-divider: #3a4258; + + --u-brand: #a8b8ff; + --u-brand-hover: #c8d2ff; + --u-brand-subtle: #171d33; + --u-brand-border: #4d5885; + + --u-focus-ring: #6fe0ff; + --u-focus-ring-offset: #0e1118; + + // Evidence states, raised. These four carry the product's core claim, so they + // get the most headroom. + --u-state-proven: #7dea9f; + --u-state-partial: #ffd27a; + --u-state-pending: #9ed4ff; + --u-state-unavailable: #ffa8a0; + --u-state-neutral: #c2cbdb; + + @include universe.universe-legacy-bridge; - --primary: #{$primary}; - --secondary: #{$secondary}; - --tertiary: #{$tertiary}; - --success: #{$success}; - --info: #{$info}; - --link-color: #{$link-color}; - --link-hover-color: #{$link-hover-color}; - --icon: #f1f1f1; - --skeleton-bg: #2e324e; - --skeleton-bg-light: #5d6182; - - --box-bg: #171c2a; - --stat-box-bg: #0b1018; - --alert-bg: #3a1c61; - --transparent-fg: #ffffffbb; - --fade-out-box-bg-start: rgba(23, 28, 42, 0); - --fade-out-box-bg-end: rgba(23, 28, 42, 1); --opacity: 0.9; - - --testnet: #1d486f; - --signet: #6f1d5d; - --regtest: #7d7d7d; - --liquid: #116761; - --liquidtestnet: #494a4a; - - --mainnet-alt: #9339f4; - --testnet-alt: #183550; - --signet-alt: #471850; - --regtest-alt: #4a4a4a; - --liquidtestnet-alt: #272e46; - - --taproot: #eba814; - --taproot-light: #d5a90a; - --taproot-dark: #9d7c05; - - --green: #83fd00; - --red: #ff3d00; - --yellow: #fff000; - --grey: #7e7e7e; - --tooltip-grey: #b1b1b1; - --orange: #ff9f00; - - --search-button: #4d2d77; - --search-button-border: #472a6e; - --search-button-focus: #533180; - --search-button-shadow: #7c58ab80; } diff --git a/frontend/src/theme-dark.scss b/frontend/src/theme-dark.scss new file mode 100644 index 00000000000..716a4a48959 --- /dev/null +++ b/frontend/src/theme-dark.scss @@ -0,0 +1,17 @@ +// Universe Explorer, dark. +// +// Full parity with light: the same token names, the same contrast floor, the +// same components. Nothing is dropped or simplified here, because a visitor who +// prefers dark is not choosing a lesser version of the product. +// +// This file only restates variables. Every component rule and the Bootstrap +// bridge live in the main stylesheet and read these names, so the swap is a +// variable swap rather than a second set of styles to keep in step. + +@use "styles/universe-tokens" as universe; + +:root { + @include universe.universe-invariant-tokens; + @include universe.universe-dark-tokens; + @include universe.universe-legacy-bridge; +} diff --git a/frontend/sync-assets.js b/frontend/sync-assets.js index 447557a51ef..c57fbb751d8 100644 --- a/frontend/sync-assets.js +++ b/frontend/sync-assets.js @@ -9,7 +9,6 @@ const CONFIG_FILE_NAME = 'mempool-frontend-config.json'; const config = { verbose: parseInt(process.env.VERBOSE) === 1, - mempoolCDN: parseInt(process.env.MEMPOOL_CDN) === 1, dryRun: parseInt(process.env.DRY_RUN) === 1, githubToken: process.env.GITHUB_TOKEN, }; @@ -22,7 +21,6 @@ if (parseInt(process.env.SKIP_SYNC) === 1) { // Log configuration if (config.verbose) console.log(`${LOG_TAG} VERBOSE is set, logs will be more verbose`); -if (config.mempoolCDN) console.log(`${LOG_TAG} MEMPOOL_CDN is set, assets will be downloaded from mempool.space`); if (config.dryRun) console.log(`${LOG_TAG} DRY_RUN is set, not downloading any assets`); // Setup assets path @@ -139,7 +137,10 @@ const createGitHubOptions = (repoPath) => { // Utility: Replace URL for CDN const getCDNUrl = (url, replacePattern) => { - return config.mempoolCDN ? url.replace(replacePattern.from, replacePattern.to) : url; + // Upstream can rewrite asset downloads to its hosted CDN. This fork always + // uses the original source, so no third-party mirror is involved. + void replacePattern; + return url; }; // Utility: Ensure directory exists @@ -241,10 +242,6 @@ const downloadMiningPoolLogos = async () => { filePath: `${ASSETS_PATH}/mining-pools/${poolLogo.name}`, remoteHash: poolLogo.sha, downloadUrl: poolLogo.download_url, - cdnPattern: { - from: "raw.githubusercontent.com/mempool/mining-pool-logos/master", - to: "mempool.space/resources/mining-pools" - }, itemName: poolLogo.name, downloadDir: `${ASSETS_PATH}/mining-pools/` }); @@ -277,10 +274,6 @@ const downloadPromoVideoSubtitles = async () => { filePath: `${ASSETS_PATH}/promo-video/${subtitle.name}`, remoteHash: subtitle.sha, downloadUrl: subtitle.download_url, - cdnPattern: { - from: "raw.githubusercontent.com/mempool/mempool-promo/master/subtitles", - to: "mempool.space/resources/promo-video" - }, itemName: subtitle.name, downloadDir: `${ASSETS_PATH}/promo-video/` }); @@ -311,10 +304,6 @@ const downloadPromoVideo = async () => { filePath: `${ASSETS_PATH}/promo-video/mempool-promo.mp4`, remoteHash: videoItem.sha, downloadUrl: videoItem.download_url, - cdnPattern: { - from: "raw.githubusercontent.com/mempool/mempool-promo/master/promo.mp4", - to: "mempool.space/resources/promo-video/mempool-promo.mp4" - }, itemName: 'mempool-promo.mp4', downloadDir: `${ASSETS_PATH}/promo-video/` }); diff --git a/nginx-mempool.conf b/nginx-mempool.conf index 4b12ed71400..2532a7082be 100644 --- a/nginx-mempool.conf +++ b/nginx-mempool.conf @@ -58,9 +58,6 @@ proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; } - location /api/v1/services { - proxy_pass https://mempool.space; - } location /api/v1 { proxy_pass http://127.0.0.1:8999/api/v1; } diff --git a/production/README.md b/production/README.md index 39777966ab0..fa474cd1463 100644 --- a/production/README.md +++ b/production/README.md @@ -2,7 +2,7 @@ These instructions are for setting up a serious production Mempool website for Bitcoin (mainnet, testnet, signet), Liquid (mainnet, testnet). -Again, this setup is no joke—home users should use [one of the other installation methods](../#installation-methods). Support is only provided to project sponsors through [Mempool Enterprise®](https://mempool.space/enterprise). +Again, this setup is no joke: home users should use [one of the other installation methods](../#installation-methods). Support is only provided to project sponsors through [Mempool Enterprise®](https://mempool.space/enterprise). You can also have the mempool.space team run a highly-performant and highly-available instance of Mempool for you on their own global ISP infrastructure. See Mempool Enterprise® for more details. @@ -18,7 +18,7 @@ I recommend a beefy server: ### HDD vs SSD vs NVMe -If you don't have a fast SSD or NVMe-backed disk, that's fine—go online and buy some fast new NVMe drives. When they arrive, install them, throw away your old HDDs, and then proceed with the rest of this guide. +If you don't have a fast SSD or NVMe-backed disk, that's fine: go online and buy some fast new NVMe drives. When they arrive, install them, throw away your old HDDs, and then proceed with the rest of this guide. ## FreeBSD 13 diff --git a/rust/gbt/README.md b/rust/gbt/README.md index c6b3cc21f06..d8c85530176 100644 --- a/rust/gbt/README.md +++ b/rust/gbt/README.md @@ -94,7 +94,7 @@ This file. ### gbt.\[TARGET_TRIPLE\].node -The Node addon—i.e., a binary Node module—generated by building the project. This is the main module for this package, as dictated by the `"main"` key in `package.json`. +The Node addon: i.e., a binary Node module: generated by building the project. This is the main module for this package, as dictated by the `"main"` key in `package.json`. Under the hood, a [Node addon](https://nodejs.org/api/addons.html) is a [dynamically-linked shared object](https://en.wikipedia.org/wiki/Library_(computing)#Shared_libraries). The `"build"` script produces this file by copying it from within the `target/` directory, which is where the Rust build produces the shared object. diff --git a/scripts/get_backend_hash.sh b/scripts/get_backend_hash.sh deleted file mode 100644 index 1e39355574a..00000000000 --- a/scripts/get_backend_hash.sh +++ /dev/null @@ -1,7 +0,0 @@ -for LOCATION in fmt va1 fra tk7 -do - for NODE in 201 202 203 204 205 206 - do - echo $(curl -sk https://node$NODE.$LOCATION.mempool.space/api/v1/backend-info) - done -done \ No newline at end of file diff --git a/scripts/get_block_tip_height.sh b/scripts/get_block_tip_height.sh deleted file mode 100644 index 603193bb89c..00000000000 --- a/scripts/get_block_tip_height.sh +++ /dev/null @@ -1,25 +0,0 @@ -BASE_HEIGHT=$(curl -sk https://node202.tk7.mempool.space/api/v1/blocks/tip/height) -IN_SYNC=true -echo "Base height (node202.tk7): $BASE_HEIGHT" - -for LOCATION in fmt va1 fra tk7 -do - for NODE in 201 202 203 204 205 206 - do - NODE_HEIGHT=$(curl -sk https://node$NODE.$LOCATION.mempool.space/api/v1/blocks/tip/height) - echo $(echo node$NODE.$LOCATION.mempool.space) - $NODE_HEIGHT - if [ "$NODE_HEIGHT" -ne "$BASE_HEIGHT" ]; then - COUNT=$((BASE_HEIGHT-NODE_HEIGHT)) - echo $(echo node$NODE.$LOCATION.mempool.space) is not in sync. delta: $COUNT - IN_SYNC=false - fi - done -done - -if [ "$IN_SYNC" = false ]; then - echo "One or more servers are out of sync. Check the logs." - exit -1 -else - echo "All servers are in sync." -fi - diff --git a/scripts/universe/check-branding.mjs b/scripts/universe/check-branding.mjs new file mode 100644 index 00000000000..af3ef0ea972 --- /dev/null +++ b/scripts/universe/check-branding.mjs @@ -0,0 +1,195 @@ +#!/usr/bin/env node +/** + * Branding gate: no obsolete upstream product marks. + * + * This fork keeps the upstream code and the upstream licence. It does not keep + * the upstream product identity. This gate fails when a Mempool Holdings mark + * appears anywhere except the small set of places where it is legally required + * or factually necessary. + * + * Usage: + * node scripts/universe/check-branding.mjs [path ...] + * + * The release workflow runs it twice: once over the source tree, and once over + * `frontend/dist`, because an unreachable lazy chunk still ships. + */ + +import { readdirSync, readFileSync, statSync } from 'node:fs'; +import { join, relative, resolve, sep } from 'node:path'; + +const REPOSITORY_ROOT = resolve(import.meta.dirname, '..', '..'); + +const SKIPPED_DIRECTORIES = new Set([ + '.git', 'node_modules', 'target', 'coverage', '.angular', '.cache', +]); + +/** + * Build output is skipped when scanning the tree, because a stale bundle from a + * previous build would fail the gate for code that no longer exists. Scanning a + * bundle is a separate, explicit run against a named directory. + */ +const SKIPPED_WHEN_WALKING_ROOT = new Set(['dist', 'build']); + +/** Product marks that must not appear in Universe Explorer's own surface. */ +const FORBIDDEN = [ + 'mempool.space', + 'Mempool Open Source Project', + 'Mempool Enterprise', + 'Mempool Accelerator', + 'Mempool Wallet', + 'Mempool Goggles', + 'Be your own explorer', + 'Explore the full Bitcoin ecosystem', + 'stats.mempool.space', +]; + +/** + * Where an upstream reference is allowed, and why. + * + * Each entry is a path prefix plus the reason it is exempt. Nothing outside + * this list may name an upstream product, so a new exemption is a deliberate, + * reviewable act. + */ +const ALLOWED = [ + { prefix: 'COPYING.md', reason: 'upstream licence text, preserved verbatim' }, + { prefix: 'LICENSE', reason: 'licence text' }, + { prefix: 'UPSTREAM.md', reason: 'fork provenance record' }, + { prefix: 'upstream-base.json', reason: 'fork provenance record' }, + { prefix: 'CONTRIBUTING.md', reason: 'inherited contribution guide' }, + { prefix: 'contributors/', reason: 'upstream contributor records' }, + { prefix: 'docs/legal/', reason: 'trademark and licence compliance records' }, + { prefix: 'docs/research/', reason: 'competitor research naming the competitor' }, + { prefix: 'docs/operations/UPSTREAM-SYNC.md', reason: 'upstream synchronization procedure' }, + { prefix: 'docs/architecture/', reason: 'records which upstream subsystems are modified' }, + { prefix: 'scripts/universe/check-branding.mjs', reason: 'this gate lists the marks it bans' }, + { prefix: 'frontend/src/locale/', reason: 'upstream translation catalogues, not built by this deployment' }, + { prefix: 'frontend/src/app/docs/api-docs/api-docs.component.html', reason: 'fork attribution statement required by the licence' }, + { prefix: 'backend/README.md', reason: 'inherited developer notes' }, + { prefix: 'frontend/README.md', reason: 'inherited developer notes' }, + { prefix: 'production/', reason: 'inherited operator notes for upstream-style deployments' }, + { prefix: 'docker/', reason: 'inherited container notes' }, + { prefix: 'rust/', reason: 'inherited crate notes' }, + { prefix: 'audits/', reason: 'dated audit records' }, + { prefix: 'README.md', reason: 'fork attribution required by the licence' }, + { prefix: 'scripts/universe/check-origins.mjs', reason: 'the origin gate lists the hosts it bans' }, + { prefix: 'frontend/cypress/', reason: 'inherited upstream end-to-end suite and recorded fixtures, not shipped' }, + { prefix: '.github/workflows/', reason: 'inherited upstream CI definitions; Universe CI is separate' }, +]; + +/** + * Attribution sentences this product deliberately publishes. + * + * The licence requires that the upstream work be credited and that the + * corresponding source be available. Naming the upstream project inside one of + * these exact sentences is the point of them. They are listed here as whole + * phrases so that a bundle scan can recognise them after minification, where + * the source file they came from is no longer knowable. + */ +const ATTRIBUTION_PHRASES = [ + 'an independent instance of the AGPL-licensed Mempool Open Source Project codebase, operated for the Bitcoin Universe ecosystem. It is not affiliated with or endorsed by mempool.space.', + 'Universe Explorer is free software built on the Mempool Open Source Project.', +]; + +const TEXT_EXTENSIONS = new Set([ + '.ts', '.tsx', '.js', '.mjs', '.cjs', '.json', '.html', '.scss', '.css', + '.md', '.yml', '.yaml', '.txt', '.sh', '.rs', '.sql', '.conf', '.xlf', '.map', +]); + +/** Character ranges covered by an attribution sentence in this file. */ +function attributionSpans(contents) { + const spans = []; + for (const phrase of ATTRIBUTION_PHRASES) { + let index = contents.indexOf(phrase); + while (index !== -1) { + spans.push([index, index + phrase.length]); + index = contents.indexOf(phrase, index + phrase.length); + } + } + return spans; +} + +function hasTextExtension(name) { + const dot = name.lastIndexOf('.'); + return dot > 0 && TEXT_EXTENSIONS.has(name.slice(dot)); +} + +function allowanceFor(relativePath) { + const posix = relativePath.split(sep).join('/'); + return ALLOWED.find((entry) => posix.startsWith(entry.prefix)) ?? null; +} + +function* walk(directory, skipBuildOutput) { + for (const entry of readdirSync(directory, { withFileTypes: true })) { + const full = join(directory, entry.name); + if (entry.isDirectory()) { + if (SKIPPED_DIRECTORIES.has(entry.name)) continue; + if (skipBuildOutput && SKIPPED_WHEN_WALKING_ROOT.has(entry.name)) continue; + yield* walk(full, skipBuildOutput); + } else if (entry.isFile() && hasTextExtension(entry.name)) { + yield full; + } + } +} + +function findings(file) { + const relativePath = relative(REPOSITORY_ROOT, file); + if (allowanceFor(relativePath)) return []; + let contents; + try { + contents = readFileSync(file, 'utf8'); + } catch { + return []; + } + const spans = attributionSpans(contents); + const inAttribution = (index) => + spans.some(([start, end]) => index >= start && index < end); + + const hits = []; + for (const mark of FORBIDDEN) { + let index = contents.indexOf(mark); + while (index !== -1) { + if (!inAttribution(index)) { + const line = contents.slice(0, index).split('\n').length; + hits.push({ file: relativePath, line, mark }); + if (hits.length > 20) return hits; + } + index = contents.indexOf(mark, index + mark.length); + } + } + return hits; +} + +const explicitTargets = process.argv.slice(2); + +function targets(argv) { + if (argv.length === 0) return [REPOSITORY_ROOT]; + return argv.map((entry) => resolve(REPOSITORY_ROOT, entry)); +} + +const problems = []; +for (const target of targets(explicitTargets)) { + let stats; + try { + stats = statSync(target); + } catch { + console.error(`Branding gate: ${target} does not exist.`); + process.exit(1); + } + if (stats.isDirectory()) { + for (const file of walk(target, explicitTargets.length === 0)) problems.push(...findings(file)); + } else { + problems.push(...findings(target)); + } +} + +if (problems.length > 0) { + console.error(`Obsolete upstream product marks found in ${problems.length} place(s):`); + for (const problem of problems.slice(0, 50)) { + console.error(` ${problem.file}:${problem.line}: ${problem.mark}`); + } + console.error('\nIf a reference is legally required or names a competitor in research,'); + console.error('add it to ALLOWED in scripts/universe/check-branding.mjs with a reason.'); + process.exit(1); +} + +console.log('Branding gate passed: no obsolete upstream product marks outside the allowlist.'); diff --git a/scripts/universe/check-origins.mjs b/scripts/universe/check-origins.mjs new file mode 100644 index 00000000000..4f8bd166c02 --- /dev/null +++ b/scripts/universe/check-origins.mjs @@ -0,0 +1,210 @@ +#!/usr/bin/env node +/** + * Third-party data origin gate. + * + * Every figure this explorer publishes comes from infrastructure Bitcoin + * Universe runs. A single call to a hosted blockchain API, public explorer, or + * analytics service breaks that promise, and it is the kind of thing that slips + * in through a well-meaning fallback. So it is checked. + * + * Usage: + * node scripts/universe/check-origins.mjs [path ...] + * + * The release workflow runs it over the source tree and over `frontend/dist`. + */ + +import { readdirSync, readFileSync, statSync } from 'node:fs'; +import { join, relative, resolve, sep } from 'node:path'; + +const REPOSITORY_ROOT = resolve(import.meta.dirname, '..', '..'); + +const SKIPPED_DIRECTORIES = new Set([ + '.git', 'node_modules', 'target', 'coverage', '.angular', '.cache', +]); + +/** + * Build output is skipped when scanning the tree, because a stale bundle from a + * previous build would fail the gate for code that no longer exists. Scanning a + * bundle is a separate, explicit run against a named directory. + */ +const SKIPPED_WHEN_WALKING_ROOT = new Set(['dist', 'build']); + +/** + * Hosts that must never appear as a runtime data source. + * + * Public blockchain APIs and explorers, hosted protocol indexers, analytics, + * and remote font and script CDNs. + */ +const FORBIDDEN_HOSTS = [ + 'mempool.space', + 'blockstream.info', + 'blockchain.info', + 'blockchair.com', + 'btc.com', + 'oklink.com', + 'unisat.io', + 'ordiscan.com', + 'ordinals.com', + 'hiro.so', + 'geniidata.com', + 'bestinslot.xyz', + 'openstamp.io', + 'stampchain.io', + 'magiceden.io', + 'esplora.blockstream.com', + 'google-analytics.com', + 'googletagmanager.com', + 'fonts.googleapis.com', + 'fonts.gstatic.com', + 'cdn.jsdelivr.net', + 'cdnjs.cloudflare.com', + 'unpkg.com', +]; + +/** + * Places a host name may legitimately appear: research that names competitors, + * fork provenance, this gate's own list, and documentation about the policy. + */ +const ALLOWED = [ + 'frontend/src/app/docs/api-docs/api-docs.component.html', + 'docs/research/', + 'docs/legal/', + 'docs/architecture/', + 'docs/operations/UPSTREAM-SYNC.md', + 'UPSTREAM.md', + 'upstream-base.json', + 'COPYING.md', + 'CONTRIBUTING.md', + 'README.md', + 'contributors/', + 'audits/', + 'scripts/universe/check-origins.mjs', + 'scripts/universe/check-branding.mjs', + 'frontend/src/locale/', + 'backend/README.md', + 'frontend/README.md', + 'production/', + 'docker/', + 'rust/', + // Upstream test fixtures and sample configuration, never a runtime path. + 'backend/src/__fixtures__/', + 'frontend/cypress/', + '.github/workflows/', + 'nginx.conf', + 'nginx-mempool.conf', +]; + +/** + * Sentences that name a host in order to disclaim it rather than call it. + * Recognised as whole phrases so a bundle scan still sees them after + * minification. + */ +const DISCLAIMER_PHRASES = [ + 'It is not affiliated with or endorsed by mempool.space.', +]; + +const TEXT_EXTENSIONS = new Set([ + '.ts', '.tsx', '.js', '.mjs', '.cjs', '.json', '.html', '.scss', '.css', + '.md', '.yml', '.yaml', '.txt', '.sh', '.rs', '.sql', '.conf', '.map', +]); + +/** Character ranges covered by a disclaimer sentence in this file. */ +function disclaimerSpans(contents) { + const spans = []; + for (const phrase of DISCLAIMER_PHRASES) { + let index = contents.indexOf(phrase); + while (index !== -1) { + spans.push([index, index + phrase.length]); + index = contents.indexOf(phrase, index + phrase.length); + } + } + return spans; +} + +function hasTextExtension(name) { + const dot = name.lastIndexOf('.'); + return dot > 0 && TEXT_EXTENSIONS.has(name.slice(dot)); +} + +function isAllowed(relativePath) { + const posix = relativePath.split(sep).join('/'); + return ALLOWED.some((prefix) => posix.startsWith(prefix)); +} + +function* walk(directory, skipBuildOutput) { + for (const entry of readdirSync(directory, { withFileTypes: true })) { + const full = join(directory, entry.name); + if (entry.isDirectory()) { + if (SKIPPED_DIRECTORIES.has(entry.name)) continue; + if (skipBuildOutput && SKIPPED_WHEN_WALKING_ROOT.has(entry.name)) continue; + yield* walk(full, skipBuildOutput); + } else if (entry.isFile() && hasTextExtension(entry.name)) { + yield full; + } + } +} + +function findings(file) { + const relativePath = relative(REPOSITORY_ROOT, file); + if (isAllowed(relativePath)) return []; + let contents; + try { + contents = readFileSync(file, 'utf8'); + } catch { + return []; + } + const spans = disclaimerSpans(contents); + const hits = []; + for (const host of FORBIDDEN_HOSTS) { + // A host only counts when it stands on its own. Without the boundaries a + // filename like `btc.component.html` reads as the host `btc.com`, and a + // spec citation like `docs.ordinals.com` reads as `ordinals.com`. + const pattern = new RegExp( + `(? match.index >= start && match.index < end)) { + continue; + } + const line = contents.slice(0, match.index).split('\n').length; + hits.push({ file: relativePath, line, host }); + if (hits.length > 20) return hits; + } + } + return hits; +} + +const explicitTargets = process.argv.slice(2); + +function targets(argv) { + if (argv.length === 0) return [REPOSITORY_ROOT]; + return argv.map((entry) => resolve(REPOSITORY_ROOT, entry)); +} + +const problems = []; +for (const target of targets(explicitTargets)) { + let stats; + try { + stats = statSync(target); + } catch { + console.error(`Origin gate: ${target} does not exist.`); + process.exit(1); + } + if (stats.isDirectory()) { + for (const file of walk(target, explicitTargets.length === 0)) problems.push(...findings(file)); + } else { + problems.push(...findings(target)); + } +} + +if (problems.length > 0) { + console.error(`Third-party origins found in ${problems.length} place(s):`); + for (const problem of problems.slice(0, 50)) { + console.error(` ${problem.file}:${problem.line}: ${problem.host}`); + } + console.error('\nRuntime data must come from Bitcoin Universe infrastructure only.'); + process.exit(1); +} + +console.log('Origin gate passed: no third-party data origins found.'); diff --git a/scripts/universe/check-text.mjs b/scripts/universe/check-text.mjs new file mode 100644 index 00000000000..dea16a3f48b --- /dev/null +++ b/scripts/universe/check-text.mjs @@ -0,0 +1,120 @@ +#!/usr/bin/env node +/** + * Text gate: no em dash anywhere. + * + * U+2014 is banned in this repository's source, copy, documentation, tests, + * fixtures, and metadata. The rule is easy to break by accident, so it is + * enforced rather than remembered. + * + * Usage: + * node scripts/universe/check-text.mjs [path ...] + * + * With no arguments it scans the whole repository, skipping directories that + * are not ours to police (dependencies, build output, git internals). + */ + +import { readdirSync, readFileSync, statSync } from 'node:fs'; +import { join, relative, resolve, sep } from 'node:path'; + +const REPOSITORY_ROOT = resolve(import.meta.dirname, '..', '..'); + +const SKIPPED_DIRECTORIES = new Set([ + '.git', + 'node_modules', + 'dist', + 'build', + 'target', + 'coverage', + '.angular', + '.cache', +]); + +/** + * Files we do not author. Upstream translation catalogues carry the upstream + * copy verbatim, including its punctuation; they are not shipped by this + * deployment's build and are regenerated when locales are re-enabled. + */ +const ALLOWED_PATHS = [ + 'frontend/src/locale/', +]; + +const TEXT_EXTENSIONS = new Set([ + '.ts', '.tsx', '.js', '.mjs', '.cjs', '.json', '.html', '.scss', '.css', + '.md', '.yml', '.yaml', '.txt', '.sh', '.rs', '.sql', '.conf', '.xlf', +]); + +// Built from its code point so this file does not contain the character it bans. +const EM_DASH = String.fromCharCode(0x2014); + +function isSkipped(name) { + return SKIPPED_DIRECTORIES.has(name); +} + +function isAllowed(relativePath) { + const posix = relativePath.split(sep).join('/'); + return ALLOWED_PATHS.some((prefix) => posix.startsWith(prefix)); +} + +function hasTextExtension(name) { + const dot = name.lastIndexOf('.'); + return dot > 0 && TEXT_EXTENSIONS.has(name.slice(dot)); +} + +function* walk(directory) { + for (const entry of readdirSync(directory, { withFileTypes: true })) { + const full = join(directory, entry.name); + if (entry.isDirectory()) { + if (isSkipped(entry.name)) continue; + yield* walk(full); + } else if (entry.isFile() && hasTextExtension(entry.name)) { + yield full; + } + } +} + +function findings(file) { + const relativePath = relative(REPOSITORY_ROOT, file); + if (isAllowed(relativePath)) return []; + let contents; + try { + contents = readFileSync(file, 'utf8'); + } catch { + return []; + } + if (!contents.includes(EM_DASH)) return []; + const hits = []; + contents.split(/\r?\n/).forEach((line, index) => { + if (line.includes(EM_DASH)) { + hits.push({ file: relativePath, line: index + 1, text: line.trim().slice(0, 120) }); + } + }); + return hits; +} + +function targets(argv) { + if (argv.length === 0) return [REPOSITORY_ROOT]; + return argv.map((entry) => resolve(REPOSITORY_ROOT, entry)); +} + +const problems = []; +for (const target of targets(process.argv.slice(2))) { + const stats = statSync(target); + if (stats.isDirectory()) { + for (const file of walk(target)) problems.push(...findings(file)); + } else { + problems.push(...findings(target)); + } +} + +if (problems.length > 0) { + console.error(`Em dash found in ${problems.length} place(s). Use a colon, a comma, or two sentences.`); + for (const problem of problems.slice(0, 50)) { + console.error(` ${problem.file}:${problem.line}: ${problem.text}`); + } + if (problems.length > 50) { + console.error(` ... and ${problems.length - 50} more`); + } + process.exit(1); +} + +console.log('Text gate passed: no em dash found.'); diff --git a/scripts/universe/gateway.mjs b/scripts/universe/gateway.mjs new file mode 100644 index 00000000000..1a70480cc14 --- /dev/null +++ b/scripts/universe/gateway.mjs @@ -0,0 +1,383 @@ +#!/usr/bin/env node +/** + * Universe Explorer gateway. + * + * One loopback listener that fronts the whole product: + * + * /api/v1/universe/* -> the protocol overlay + * /api/* -> the explorer backend, including WebSocket upgrades + * everything else -> the built frontend, with SPA fallback + * + * It exists so the public origin has a single upstream to point at, and so the + * indexer host needs no additional system packages. Everything it does is + * deliberately small: no rewriting of bodies, no caching layer of its own, no + * configuration language. + * + * Configuration, all optional: + * UNIVERSE_GATEWAY_HOST default 127.0.0.1 + * UNIVERSE_GATEWAY_PORT default 8099 + * UNIVERSE_GATEWAY_BACKEND default http://127.0.0.1:8996 + * UNIVERSE_GATEWAY_OVERLAY default http://127.0.0.1:3400 + * UNIVERSE_GATEWAY_ROOT default ./frontend/dist/mempool/browser + */ + +import http from 'node:http'; +import net from 'node:net'; +import { createHash } from 'node:crypto'; +import { createReadStream, existsSync, readFileSync, statSync } from 'node:fs'; +import { extname, join, normalize, resolve, sep } from 'node:path'; + +const HOST = process.env.UNIVERSE_GATEWAY_HOST || '127.0.0.1'; +const PORT = Number(process.env.UNIVERSE_GATEWAY_PORT || 8099); +const BACKEND = new URL(process.env.UNIVERSE_GATEWAY_BACKEND || 'http://127.0.0.1:8996'); +const OVERLAY = new URL(process.env.UNIVERSE_GATEWAY_OVERLAY || 'http://127.0.0.1:3400'); +const ROOT = resolve(process.env.UNIVERSE_GATEWAY_ROOT || 'frontend/dist/mempool/browser'); + +/** Upstream request budget. Long enough for a cold index read, short enough to fail fast. */ +const UPSTREAM_TIMEOUT_MS = 30_000; + +const CONTENT_TYPES = new Map(Object.entries({ + '.html': 'text/html; charset=utf-8', + '.js': 'text/javascript; charset=utf-8', + '.mjs': 'text/javascript; charset=utf-8', + '.css': 'text/css; charset=utf-8', + '.json': 'application/json; charset=utf-8', + '.svg': 'image/svg+xml', + '.png': 'image/png', + '.jpg': 'image/jpeg', + '.jpeg': 'image/jpeg', + '.gif': 'image/gif', + '.webp': 'image/webp', + '.avif': 'image/avif', + '.ico': 'image/x-icon', + '.woff': 'font/woff', + '.woff2': 'font/woff2', + '.ttf': 'font/ttf', + '.txt': 'text/plain; charset=utf-8', + '.map': 'application/json; charset=utf-8', + '.webmanifest': 'application/manifest+json', + '.xml': 'application/xml; charset=utf-8', + '.mp4': 'video/mp4', + '.wasm': 'application/wasm', +})); + +/** + * Security headers applied to every response. + * + * The referrer policy is the one that matters most here: a page URL on this + * site contains an address, a transaction, or an output, so leaking it to any + * site a visitor clicks through to would undo the rest of the privacy work. + */ +const SECURITY_HEADERS = { + 'x-content-type-options': 'nosniff', + 'x-frame-options': 'DENY', + 'referrer-policy': 'no-referrer', + 'cross-origin-opener-policy': 'same-origin', + 'permissions-policy': + 'accelerometer=(), camera=(), display-capture=(), geolocation=(), ' + + 'gyroscope=(), magnetometer=(), microphone=(), payment=(), usb=()', + 'strict-transport-security': 'max-age=31536000; includeSubDomains', +}; + +/** + * Content policy for the document itself. + * + * Everything the page loads is served from this origin. Angular injects + * component styles at runtime and writes style attributes for bound values, so + * inline styles are permitted; inline script is not, and nothing is fetched + * from anywhere else. + */ +const CONTENT_SECURITY_POLICY_PARTS = [ + "default-src 'self'", + "script-src 'self'", + "style-src 'self' 'unsafe-inline'", + "img-src 'self' data: blob:", + "font-src 'self' data:", + "connect-src 'self'", + "media-src 'self'", + "worker-src 'self' blob:", + "frame-src 'none'", + "object-src 'none'", + "frame-ancestors 'none'", + "base-uri 'self'", + "form-action 'self'", + 'upgrade-insecure-requests', +]; + +/** + * The build injects one inline script into the document to name the theme + * files, and its content changes with every build. Rather than weaken the + * policy with 'unsafe-inline', its hash is computed once at start-up and + * allowed by name. Anything else inline stays blocked. + */ +function inlineScriptHashes() { + const index = join(ROOT, 'index.html'); + if (!existsSync(index)) return []; + let html; + try { + html = readFileSync(index, 'utf8'); + } catch { + return []; + } + const hashes = []; + for (const match of html.matchAll(/]*)>([\s\S]*?)<\/script>/g)) { + if (/\ssrc\s*=/.test(match[1])) continue; + const body = match[2]; + if (!body) continue; + hashes.push(`'sha256-${createHash('sha256').update(body, 'utf8').digest('base64')}'`); + } + return hashes; +} + +const CONTENT_SECURITY_POLICY = (() => { + const hashes = inlineScriptHashes(); + return CONTENT_SECURITY_POLICY_PARTS.map((part) => + part.startsWith('script-src') && hashes.length + ? `${part} ${hashes.join(' ')}` + : part, + ).join('; '); +})(); + +function withSecurityHeaders(headers, isDocument) { + const merged = { ...headers, ...SECURITY_HEADERS }; + if (isDocument) merged['content-security-policy'] = CONTENT_SECURITY_POLICY; + return merged; +} + +/** Requests for a mining pool logo the build does not carry. */ +const MINING_POOL_LOGO = /^\/resources\/mining-pools\/[A-Za-z0-9._-]+\.svg$/; + +/** Build output is content hashed, so it can be cached hard. Entry points cannot. */ +const HASHED_ASSET = /\.[0-9a-f]{16,}\.(?:js|css|woff2?|ttf|png|jpe?g|svg|webp|avif|wasm)$/i; + +/** + * Which upstream serves a path, and what path it should see. + * + * The explorer backend registers every route under its own `/api/v1/` prefix, + * while clients and the Esplora-compatible surface address them as `/api/`. + * Upstream resolves that in nginx; this does the same rewrite, because getting + * it wrong silently 404s the entire chain API while the site still loads. + */ +export function routeFor(pathname, originalUrl) { + if (pathname === '/api/v1/universe' || pathname.startsWith('/api/v1/universe/')) { + return { upstream: OVERLAY, path: originalUrl }; + } + if (pathname === '/api/v1' || pathname.startsWith('/api/v1/')) { + return { upstream: BACKEND, path: originalUrl }; + } + if (pathname.startsWith('/api/')) { + return { upstream: BACKEND, path: `/api/v1/${originalUrl.slice('/api/'.length)}` }; + } + if (pathname === '/api') { + return { upstream: BACKEND, path: '/api/v1/' }; + } + return null; +} + +function proxy(request, response, route) { + const upstream = route.upstream; + const options = { + protocol: upstream.protocol, + hostname: upstream.hostname, + port: upstream.port, + method: request.method, + path: route.path, + headers: { ...request.headers, host: upstream.host }, + timeout: UPSTREAM_TIMEOUT_MS, + }; + const proxied = http.request(options, (upstreamResponse) => { + // API responses are data, never documents, so they get the headers without + // a content policy. + response.writeHead( + upstreamResponse.statusCode || 502, + withSecurityHeaders(upstreamResponse.headers, false), + ); + upstreamResponse.pipe(response); + }); + proxied.on('timeout', () => proxied.destroy(new Error('upstream timeout'))); + proxied.on('error', () => { + if (response.headersSent) { + response.destroy(); + return; + } + // A dead upstream is reported as a gateway failure, never as an empty + // success: a caller must be able to tell the two apart. + response.writeHead(502, { 'content-type': 'application/json; charset=utf-8' }); + response.end(JSON.stringify({ error: 'upstream-unavailable' })); + }); + request.pipe(proxied); +} + +/** Resolves a request path to a file inside the root, or null. */ +function staticFile(pathname) { + let decoded; + try { + decoded = decodeURIComponent(pathname); + } catch { + return null; + } + if (decoded.includes('\0')) return null; + const candidate = resolve(join(ROOT, normalize(decoded))); + if (candidate !== ROOT && !candidate.startsWith(ROOT + sep)) return null; + if (!existsSync(candidate)) return null; + const stats = statSync(candidate); + if (stats.isDirectory()) { + const index = join(candidate, 'index.html'); + return existsSync(index) ? index : null; + } + return candidate; +} + +function serveFile(response, file, status = 200) { + const extension = extname(file).toLowerCase(); + const headers = { + 'content-type': CONTENT_TYPES.get(extension) || 'application/octet-stream', + 'x-content-type-options': 'nosniff', + 'cache-control': HASHED_ASSET.test(file) + ? 'public, max-age=31536000, immutable' + : 'no-cache', + }; + try { + headers['content-length'] = String(statSync(file).size); + } catch { + // A file that vanished between the check and the read is a 404, not a crash. + response.writeHead(404, { 'content-type': 'text/plain; charset=utf-8' }); + response.end('Not found'); + return; + } + response.writeHead( + status, + withSecurityHeaders(headers, headers['content-type'].startsWith('text/html')), + ); + const stream = createReadStream(file); + stream.on('error', () => response.destroy()); + stream.pipe(response); +} + +const server = http.createServer((request, response) => { + let pathname; + try { + pathname = new URL(request.url, 'http://gateway.invalid').pathname; + } catch { + response.writeHead(400, { 'content-type': 'text/plain; charset=utf-8' }); + response.end('Bad request'); + return; + } + + if (pathname === '/__gateway/health') { + response.writeHead(200, { + 'content-type': 'application/json; charset=utf-8', + 'cache-control': 'no-store', + }); + response.end(JSON.stringify({ status: 'ok', root: ROOT })); + return; + } + + const route = routeFor(pathname, request.url); + if (route) { + proxy(request, response, route); + return; + } + + if (request.method !== 'GET' && request.method !== 'HEAD') { + response.writeHead(405, { allow: 'GET, HEAD' }); + response.end(); + return; + } + + const file = staticFile(pathname); + if (file) { + serveFile(response, file); + return; + } + + // A mining pool with no bundled logo is expected, not an error. The page + // already falls back to the default mark, so serving it here keeps a dozen + // 404s per page load out of the console and off the wire. + if (MINING_POOL_LOGO.test(pathname)) { + const fallback = join(ROOT, 'resources', 'mining-pools', 'default.svg'); + if (existsSync(fallback)) { + serveFile(response, fallback); + return; + } + } + + // Single page application: an unknown path is a client route, not a 404, + // unless it looks like a missing asset request. + if (extname(pathname)) { + response.writeHead(404, { 'content-type': 'text/plain; charset=utf-8' }); + response.end('Not found'); + return; + } + const index = join(ROOT, 'index.html'); + if (existsSync(index)) { + serveFile(response, index); + return; + } + response.writeHead(503, { 'content-type': 'text/plain; charset=utf-8' }); + response.end('Frontend build not present'); +}); + +/** + * WebSocket upgrades belong to the explorer backend, which attaches its socket + * server to the whole HTTP server rather than to one path, so the path passes + * through unchanged. + */ +server.on('upgrade', (request, socket, head) => { + const upstream = BACKEND; + const proxied = net.connect(Number(upstream.port), upstream.hostname, () => { + const lines = [`${request.method} ${request.url} HTTP/1.1`]; + for (const [name, value] of Object.entries(request.headers)) { + if (name.toLowerCase() === 'host') continue; + for (const item of Array.isArray(value) ? value : [value]) { + lines.push(`${name}: ${item}`); + } + } + lines.push(`Host: ${upstream.host}`, '', ''); + proxied.write(lines.join('\r\n')); + if (head?.length) proxied.write(head); + proxied.pipe(socket); + socket.pipe(proxied); + }); + const close = () => { + socket.destroy(); + proxied.destroy(); + }; + proxied.on('error', close); + socket.on('error', close); +}); + +server.headersTimeout = 60_000; +server.requestTimeout = 0; +server.keepAliveTimeout = 65_000; + +/** + * Listening is the default. A test that imports this file for its routing + * table sets UNIVERSE_GATEWAY_NO_LISTEN so no socket is opened. + * + * The flag is explicit rather than a comparison against process.argv, because + * the release directory is reached through a symlink and the two paths never + * match there. That mistake takes the gateway down silently, with a clean exit + * code and no error to read. + */ +if (process.env.UNIVERSE_GATEWAY_NO_LISTEN !== '1') { + server.listen(PORT, HOST, () => { + process.stdout.write( + `Universe Explorer gateway listening on ${HOST}:${PORT} +` + + ` overlay ${OVERLAY.origin} +` + + ` backend ${BACKEND.origin} +` + + ` static ${ROOT} +`, + ); + }); + + for (const signal of ['SIGTERM', 'SIGINT']) { + process.on(signal, () => { + server.close(() => process.exit(0)); + setTimeout(() => process.exit(0), 5000).unref(); + }); + } +} diff --git a/scripts/universe/gateway.test.mjs b/scripts/universe/gateway.test.mjs new file mode 100644 index 00000000000..79cea9baa40 --- /dev/null +++ b/scripts/universe/gateway.test.mjs @@ -0,0 +1,84 @@ +import test from 'node:test'; +import assert from 'node:assert/strict'; + +// Importing the gateway must not open a socket. +process.env.UNIVERSE_GATEWAY_NO_LISTEN = '1'; +const { routeFor } = await import('./gateway.mjs'); + +/** + * The path rewrite is load bearing. The explorer backend registers every route + * under its own `/api/v1/` prefix while clients address them as `/api/`, so a + * mistake here 404s the whole chain API while the site still loads, which is + * exactly the kind of failure that reaches production unnoticed. + */ + +const OVERLAY_PORT = '3400'; +const BACKEND_PORT = '8996'; + +function port(route) { + return route === null ? null : route.upstream.port; +} + +test('protocol overlay routes reach the overlay unchanged', () => { + for (const url of [ + '/api/v1/universe', + '/api/v1/universe/status', + '/api/v1/universe/transactions/' + 'a'.repeat(64), + '/api/v1/universe/protocols?chain=bitcoin', + ]) { + const pathname = new URL(url, 'http://x.invalid').pathname; + const route = routeFor(pathname, url); + assert.equal(port(route), OVERLAY_PORT, url); + assert.equal(route.path, url, url); + } +}); + +test('explicit v1 routes reach the backend unchanged', () => { + for (const url of ['/api/v1', '/api/v1/fees/recommended', '/api/v1/backend-info']) { + const pathname = new URL(url, 'http://x.invalid').pathname; + const route = routeFor(pathname, url); + assert.equal(port(route), BACKEND_PORT, url); + assert.equal(route.path, url, url); + } +}); + +test('unprefixed api routes are rewritten onto the backend prefix', () => { + const cases = [ + ['/api/blocks/tip/height', '/api/v1/blocks/tip/height'], + ['/api/block-height/800000', '/api/v1/block-height/800000'], + ['/api/address/bc1qexample/utxo', '/api/v1/address/bc1qexample/utxo'], + ['/api/tx/' + 'b'.repeat(64), '/api/v1/tx/' + 'b'.repeat(64)], + ]; + for (const [url, expected] of cases) { + const pathname = new URL(url, 'http://x.invalid').pathname; + const route = routeFor(pathname, url); + assert.equal(port(route), BACKEND_PORT, url); + assert.equal(route.path, expected, url); + } +}); + +test('a query string survives the rewrite', () => { + const url = '/api/address/bc1qexample/txs?after_txid=abc'; + const route = routeFor('/api/address/bc1qexample/txs', url); + assert.equal(route.path, '/api/v1/address/bc1qexample/txs?after_txid=abc'); +}); + +test('the bare api path reaches the backend index', () => { + const route = routeFor('/api', '/api'); + assert.equal(port(route), BACKEND_PORT); + assert.equal(route.path, '/api/v1/'); +}); + +test('a universe path that is not under the v1 prefix is not sent to the overlay', () => { + // `/api/universe/...` is rewritten like any other unprefixed API path, which + // lands it on the overlay's own prefix and keeps one meaning per path. + const route = routeFor('/api/universe/status', '/api/universe/status'); + assert.equal(route.path, '/api/v1/universe/status'); +}); + +test('everything outside the api tree is left for the static handler', () => { + for (const url of ['/', '/protocols', '/tx/abc', '/resources/config.js', '/apixyz']) { + const pathname = new URL(url, 'http://x.invalid').pathname; + assert.equal(routeFor(pathname, url), null, url); + } +}); diff --git a/scripts/universe/visual-qa/capture.mjs b/scripts/universe/visual-qa/capture.mjs new file mode 100644 index 00000000000..7d66bd925bb --- /dev/null +++ b/scripts/universe/visual-qa/capture.mjs @@ -0,0 +1,302 @@ +#!/usr/bin/env node +/** + * Universe Explorer visual, accessibility, and cross-browser matrix. + * + * Drives the running application across routes, themes, viewports, and data + * states, and records what it finds. Every API call is answered from fixtures, + * so a difference between two runs means the interface changed, not that the + * chain moved or that a backend went down mid-review. + * + * What each run asserts, per route and state: + * - no horizontal overflow at the viewport width + * - no console errors + * - no images that failed to load + * - no accessibility violations at WCAG 2.2 A/AA + * and writes a screenshot for the visual comparison. + * + * Usage: + * node capture.mjs full matrix, chromium + * node capture.mjs --browser=firefox another engine + * node capture.mjs --routes=home,tx a subset while iterating + * node capture.mjs --states=populated skip the failure states + * node capture.mjs --out= where to write + */ + +import { mkdirSync, writeFileSync } from 'node:fs'; +import { dirname, join, resolve } from 'node:path'; +import { fileURLToPath } from 'node:url'; +import AxeBuilder from '@axe-core/playwright'; +import * as playwright from 'playwright'; +import { addressFixtures, fixtures, sampleIds, stateOverrides } from './fixtures.mjs'; + +const HERE = dirname(fileURLToPath(import.meta.url)); + +const args = Object.fromEntries( + process.argv.slice(2).map((a) => { + const [k, v] = a.replace(/^--/, '').split('='); + return [k, v ?? true]; + }), +); + +const BASE = args.base || 'http://localhost:4200'; +const OUT = resolve(args.out || join(HERE, 'artifacts')); +const BROWSER = args.browser || 'chromium'; + +/** Routes under review. `wide` marks pages that legitimately scroll a table. */ +const ROUTES = [ + { id: 'home', path: '/', name: 'Homepage' }, + { id: 'blocks', path: '/blocks', name: 'Blocks list' }, + { id: 'block', path: `/block/${sampleIds.BLOCK_HASH}`, name: 'Block detail' }, + { id: 'mempool-block', path: '/mempool-block/0', name: 'Projected block' }, + { id: 'tx', path: `/tx/${sampleIds.TXID_A}`, name: 'Transaction detail' }, + { id: 'address', path: `/address/${sampleIds.ADDRESS}`, name: 'Address' }, + { id: 'protocols', path: '/protocols', name: 'Protocol directory' }, + { id: 'pulse', path: '/pulse', name: 'Universe Pulse' }, + { id: 'rbf', path: '/rbf', name: 'Replacements' }, + { id: 'graphs', path: '/graphs/mempool', name: 'Graphs' }, + { id: 'mining', path: '/mining', name: 'Mining dashboard' }, + { id: 'docs', path: '/docs/api', name: 'API docs' }, + { id: 'source', path: '/source', name: 'Source and licenses' }, +]; + +const VIEWPORTS = [ + { id: '320', width: 320, height: 900 }, + { id: '375', width: 375, height: 900 }, + { id: '768', width: 768, height: 1024 }, + { id: '1024', width: 1024, height: 900 }, + { id: '1280', width: 1280, height: 900 }, + { id: '1440', width: 1440, height: 900 }, + { id: '1920', width: 1920, height: 1080 }, +]; + +const THEMES = ['default', 'dark', 'contrast']; + +const STATES = ['populated', ...Object.keys(stateOverrides)]; + +function pick(list, key, idKey = 'id') { + if (!args[key]) return list; + const wanted = String(args[key]).split(','); + return list.filter((entry) => wanted.includes(typeof entry === 'string' ? entry : entry[idKey])); +} + +/** Answer every API call from fixtures, applying the state's overrides. */ +async function installFixtures(context, state) { + const overrides = stateOverrides[state] || {}; + const table = { ...fixtures, ...addressFixtures }; + + await context.route('**/api/**', async (route) => { + const url = new URL(route.request().url()); + const path = url.pathname; + + if (overrides['**']?.hang) return; // never fulfil: hold the loading state + + const override = + overrides[path] ?? + Object.entries(overrides).find(([k]) => k !== '**' && path.startsWith(k))?.[1]; + + if (override) { + if (override.hang) return; + if (override.status) { + return route.fulfill({ status: override.status, contentType: 'text/plain', body: 'fixture error' }); + } + return route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify(override.body) }); + } + + const exact = table[path]; + if (exact !== undefined) { + return route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify(exact) }); + } + + const prefix = Object.keys(table).find((k) => path.startsWith(k)); + if (prefix) { + return route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify(table[prefix]) }); + } + + // Anything not pinned returns an empty list rather than reaching the + // network, so a run is never at the mercy of a live backend. + if (process.env.LOG_UNMATCHED) console.log('unmatched: ' + path); + return route.fulfill({ status: 200, contentType: 'application/json', body: '[]' }); + }); + + // Most live surfaces on this product are fed by the socket, not by REST, so + // a screenshot with the socket cut is a screenshot of skeletons. Answer it + // from the same fixtures instead: the client sends {action:'want'}, and one + // push carries the whole initial state. + const down = state === 'chain-down' || overrides['**']?.hang; + await context.routeWebSocket('**/api/v1/ws', (ws) => { + if (down) return; // connected but silent: the reconnecting and loading states + const push = () => ws.send(JSON.stringify(socketState())); + ws.onMessage(() => push()); + push(); + }); +} + +/** One socket push carrying the initial live state, from the same fixtures. */ +function socketState() { + return { + mempoolInfo: { loaded: true, size: 31_204, bytes: 118_442_881, usage: 118_442_881, maxmempool: 300_000_000, mempoolminfee: 0.00001, minrelaytxfee: 0.00001, fullrbf: true }, + vBytesPerSecond: 1_884, + fees: fixtures['/api/v1/fees/recommended'], + da: fixtures['/api/v1/difficulty-adjustment'], + blocks: fixtures['/api/v1/blocks'], + 'mempool-blocks': fixtures['/api/v1/fees/mempool-blocks'], + transactions: fixtures['/api/mempool/recent'], + rbfLatestSummary: fixtures['rbf-latest-summary'], + conversions: { USD: 96_400, EUR: 89_100, time: 1_772_100_000 }, + loadingIndicators: { mempool: 100, blocks: 100 }, + backendInfo: { hostname: 'universe-explorer', version: '3.3.1', gitCommit: 'fixture0', lightning: false }, + }; +} + +async function run() { + const routes = pick(ROUTES, 'routes'); + const viewports = pick(VIEWPORTS, 'viewports'); + const themes = pick(THEMES.map((id) => ({ id })), 'themes').map((t) => t.id); + const states = pick(STATES.map((id) => ({ id })), 'states').map((s) => s.id); + + mkdirSync(OUT, { recursive: true }); + const browser = await playwright[BROWSER].launch(); + const findings = []; + let shots = 0; + + for (const state of states) { + for (const theme of themes) { + for (const viewport of viewports) { + const context = await browser.newContext({ + viewport: { width: viewport.width, height: viewport.height }, + deviceScaleFactor: 1, + reducedMotion: args.reducedMotion ? 'reduce' : 'no-preference', + }); + await installFixtures(context, state); + await context.addInitScript((t) => { + try { + localStorage.setItem('theme-preference', t); + } catch { /* private mode: the default theme is fine */ } + }, theme); + + for (const route of routes) { + const page = await context.newPage(); + const consoleErrors = []; + page.on('console', (m) => { if (m.type() === 'error') consoleErrors.push(m.text()); }); + page.on('pageerror', (e) => consoleErrors.push(String(e))); + + const label = `${route.id}__${state}__${theme}__${viewport.id}`; + try { + await page.goto(BASE + route.path, { waitUntil: 'domcontentloaded', timeout: 45_000 }); + await page.waitForTimeout(state === 'loading' ? 1_200 : 2_600); + + const overflow = await page.evaluate(() => { + const d = document.documentElement; + return { scrollWidth: d.scrollWidth, clientWidth: d.clientWidth }; + }); + const overflowBy = overflow.scrollWidth - overflow.clientWidth; + + const brokenImages = await page.evaluate(() => + Array.from(document.images) + .filter((i) => i.complete && i.naturalWidth === 0 && i.currentSrc) + .map((i) => i.currentSrc), + ); + + let violations = []; + if (!args.skipAxe) { + try { + const axe = await new AxeBuilder({ page }) + .withTags(['wcag2a', 'wcag2aa', 'wcag21a', 'wcag21aa', 'wcag22aa']) + .analyze(); + violations = axe.violations.map((v) => ({ + id: v.id, + impact: v.impact, + count: v.nodes.length, + help: v.help, + sample: v.nodes[0]?.target?.join(' ') ?? '', + })); + } catch (e) { + violations = [{ id: 'axe-failed', impact: 'unknown', count: 0, help: String(e).slice(0, 200), sample: '' }]; + } + } + + await page.screenshot({ path: join(OUT, `${label}.png`), fullPage: Boolean(args.fullPage) }); + shots++; + + findings.push({ + route: route.id, routeName: route.name, state, theme, viewport: viewport.id, + overflowBy, consoleErrors, brokenImages, violations, + }); + } catch (error) { + findings.push({ + route: route.id, routeName: route.name, state, theme, viewport: viewport.id, + error: String(error).slice(0, 400), + }); + } finally { + await page.close(); + } + } + await context.close(); + } + } + } + + await browser.close(); + + const report = { browser: BROWSER, base: BASE, screenshots: shots, findings }; + writeFileSync(join(OUT, `report-${BROWSER}.json`), JSON.stringify(report, null, 2)); + summarise(report); +} + +function summarise(report) { + const overflow = report.findings.filter((f) => f.overflowBy > 0); + const errors = report.findings.filter((f) => f.consoleErrors?.length); + const images = report.findings.filter((f) => f.brokenImages?.length); + const failed = report.findings.filter((f) => f.error); + const a11y = report.findings.filter((f) => f.violations?.length); + + const byRule = new Map(); + for (const f of a11y) { + for (const v of f.violations) { + const e = byRule.get(v.id) || { id: v.id, impact: v.impact, help: v.help, places: 0, routes: new Set() }; + e.places += v.count; + e.routes.add(f.route); + byRule.set(v.id, e); + } + } + + console.log(`\n=== ${report.browser} : ${report.screenshots} screenshots -> ${OUT}\n`); + console.log(`horizontal overflow : ${overflow.length}`); + console.log(`console errors : ${errors.length}`); + console.log(`broken images : ${images.length}`); + console.log(`navigation failures : ${failed.length}`); + console.log(`a11y rules violated : ${byRule.size}\n`); + + if (overflow.length) { + console.log('-- overflow --'); + for (const f of overflow.slice(0, 20)) { + console.log(` ${f.route} ${f.state} ${f.theme} @${f.viewport}px overflows by ${f.overflowBy}px`); + } + } + if (byRule.size) { + console.log('\n-- accessibility --'); + for (const r of [...byRule.values()].sort((a, b) => b.places - a.places)) { + console.log(` ${String(r.impact).padEnd(8)} ${r.id.padEnd(34)} ${String(r.places).padStart(4)} places [${[...r.routes].join(', ')}]`); + console.log(` ${r.help}`); + } + } + if (errors.length) { + console.log('\n-- console --'); + const seen = new Set(); + for (const f of errors) { + for (const e of f.consoleErrors) { + const key = e.slice(0, 120); + if (seen.has(key)) continue; + seen.add(key); + console.log(` [${f.route}] ${key}`); + } + } + } + if (failed.length) { + console.log('\n-- navigation --'); + for (const f of failed.slice(0, 15)) console.log(` ${f.route} ${f.state} ${f.theme} @${f.viewport}: ${f.error}`); + } + console.log(''); +} + +run().catch((e) => { console.error(e); process.exit(1); }); diff --git a/scripts/universe/visual-qa/fixtures.mjs b/scripts/universe/visual-qa/fixtures.mjs new file mode 100644 index 00000000000..996b62c8290 --- /dev/null +++ b/scripts/universe/visual-qa/fixtures.mjs @@ -0,0 +1,171 @@ +// Deterministic API fixtures for the Universe Explorer visual and +// accessibility matrix. +// +// The production API is not a usable source of truth for a design review: it +// changes every block, and it cannot be asked to produce an empty address, a +// stalled authority, or a 40-deep replacement chain on demand. These fixtures +// pin every state the matrix has to prove, so a screenshot difference means the +// interface changed rather than the chain moved. +// +// Values are shaped like the real payloads and are internally consistent +// (fees match weights, counts match arrays). They are not real user data. + +const TXID_A = '9f4a1c7e5b2d8036a1f4c9e7b3d5081a2c6e4f9b7d3a1c58e26f0b4d9a7c3e15'; +const TXID_B = '3b7e9d1a5c8f2064e9b3d7a1c5f8026b4d9e7a3c1f5b8d260e4a9c7f3b1d5e82'; +const TXID_C = 'c1e5a9d3f7b2408e6a1c5d9f3b7e0246a8c2e6f0b4d8a26ce0f4b8d2a6c0e4f8'; +const ADDRESS = 'bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq'; +const BLOCK_HASH = '00000000000000000002a7c4c1e8b7d3f9a5c2e6b0d4f8a1c5e9b3d7f1a5c9e3'; + +export const fixtures = { + '/api/v1/fees/recommended': { + fastestFee: 14, + halfHourFee: 11, + hourFee: 8, + economyFee: 4, + minimumFee: 1, + }, + + '/api/v1/fees/mempool-blocks': [ + { blockSize: 1_402_881, blockVSize: 997_431, nTx: 2841, totalFees: 14_882_301, medianFee: 13.4, feeRange: [4.1, 8.2, 11.0, 13.4, 18.7, 24.9, 61.2] }, + { blockSize: 1_399_204, blockVSize: 996_002, nTx: 3120, totalFees: 9_120_774, medianFee: 8.1, feeRange: [3.0, 5.2, 7.1, 8.1, 10.4, 13.8, 22.6] }, + { blockSize: 1_401_119, blockVSize: 998_210, nTx: 3488, totalFees: 6_002_118, medianFee: 5.2, feeRange: [2.1, 3.4, 4.6, 5.2, 6.8, 8.9, 14.1] }, + ], + + '/api/v1/blocks': [ + { id: BLOCK_HASH, height: 887_412, version: 536_870_912, timestamp: 1_772_100_000, tx_count: 3_104, size: 1_612_884, weight: 3_993_112, merkle_root: TXID_A, previousblockhash: TXID_B, mediantime: 1_772_099_400, nonce: 1_884_223_901, bits: 386_101_681, difficulty: 110_568_428_300_952, extras: { totalFees: 12_884_901, medianFee: 11.2, feeRange: [1, 4, 8, 11, 17, 25, 88], reward: 325_884_901, pool: { id: 111, name: 'Universe Pool', slug: 'universe-pool' }, avgFeeRate: 12, coinbaseRaw: '', orphans: [], matchRate: 99.4, expectedFees: 12_700_000, expectedWeight: 3_992_000, similarity: 0.994 } }, + { id: TXID_B, height: 887_411, version: 536_870_912, timestamp: 1_772_099_400, tx_count: 2_881, size: 1_598_112, weight: 3_988_004, merkle_root: TXID_C, previousblockhash: TXID_C, mediantime: 1_772_098_800, nonce: 774_223_100, bits: 386_101_681, difficulty: 110_568_428_300_952, extras: { totalFees: 9_112_004, medianFee: 8.4, feeRange: [1, 3, 6, 8, 12, 19, 61], reward: 322_112_004, pool: { id: 112, name: 'Orbit Mining', slug: 'orbit-mining' }, avgFeeRate: 9, coinbaseRaw: '', orphans: [], matchRate: 98.8, expectedFees: 9_000_000, expectedWeight: 3_987_000, similarity: 0.988 } }, + ], + + '/api/v1/difficulty-adjustment': { + progressPercent: 62.4, + difficultyChange: 3.18, + estimatedRetargetDate: 1_772_700_000_000, + remainingBlocks: 758, + remainingTime: 447_600_000, + previousRetarget: -1.42, + previousTime: 1_771_400_000, + nextRetargetHeight: 888_170, + timeAvg: 590_000, + adjustedTimeAvg: 588_000, + timeOffset: 0, + expectedBlocks: 1_290, + }, + + '/api/v1/statistics/2h': buildMempoolStats(), + + '/api/v1/replacements': [ + { tx: { txid: TXID_A, fee: 4_120, vsize: 141, value: 1_882_004, rate: 29.2, time: 1_772_099_900, rbf: true, fullRbf: false }, time: 1_772_099_900, fullRbf: false, replaces: [{ tx: { txid: TXID_B, fee: 1_410, vsize: 141, value: 1_884_714, rate: 10.0, time: 1_772_099_100, rbf: true }, time: 1_772_099_100, replaces: [], interval: 800 }], interval: 800, mined: false }, + { tx: { txid: TXID_C, fee: 9_880, vsize: 247, value: 12_004_881, rate: 40.0, time: 1_772_099_700, rbf: true, fullRbf: true }, time: 1_772_099_700, fullRbf: true, replaces: [{ tx: { txid: TXID_A, fee: 2_470, vsize: 247, value: 12_012_291, rate: 10.0, time: 1_772_098_900, rbf: true }, time: 1_772_098_900, replaces: [], interval: 800 }], interval: 800, mined: true }, + ], + + // The socket's replacement summary is flat, unlike the REST replacement + // tree above. The dashboard reads these fields directly. + 'rbf-latest-summary': [ + { txid: TXID_A, oldFee: 1_410, newFee: 4_120, oldVsize: 141, newVsize: 141, mined: false, fullRbf: false }, + { txid: TXID_C, oldFee: 2_470, newFee: 9_880, oldVsize: 247, newVsize: 247, mined: true, fullRbf: true }, + { txid: TXID_B, oldFee: 880, newFee: 3_960, oldVsize: 220, newVsize: 220, mined: false, fullRbf: false }, + ], + + '/api/mempool/recent': [ + { txid: TXID_A, fee: 4_120, vsize: 141, value: 1_882_004 }, + { txid: TXID_B, fee: 1_988, vsize: 222, value: 44_120_887 }, + { txid: TXID_C, fee: 9_880, vsize: 247, value: 12_004_881 }, + ], + + '/api/v1/mining/pools/1w': { + pools: [ + { poolId: 111, name: 'Universe Pool', link: '', blockCount: 214, rank: 1, emptyBlocks: 0, slug: 'universe-pool', avgMatchRate: 99.2, avgFeeDelta: '0.004', poolUniqueId: 111 }, + { poolId: 112, name: 'Orbit Mining', link: '', blockCount: 188, rank: 2, emptyBlocks: 1, slug: 'orbit-mining', avgMatchRate: 98.6, avgFeeDelta: '0.006', poolUniqueId: 112 }, + ], + blockCount: 402, + lastEstimatedHashrate: 812_004_881_002_991_000_000, + }, + + '/api/v1/universe/protocols': { + registryVersion: '2026.08.1', + protocols: [ + { protocolId: 'ordinals', displayName: 'Ordinals', chain: 'bitcoin', family: 'inscriptions', releaseStatus: 'production_verified', authority: 'ord 0.29', coverage: { fromHeight: 767_430, toHeight: 887_412 } }, + { protocolId: 'runes', displayName: 'Runes', chain: 'bitcoin', family: 'fungible', releaseStatus: 'production_verified', authority: 'ord 0.29', coverage: { fromHeight: 840_000, toHeight: 887_412 } }, + { protocolId: 'alkanes', displayName: 'Alkanes', chain: 'bitcoin', family: 'contracts', releaseStatus: 'verified_read_only', authority: 'metashrew', coverage: { fromHeight: 880_000, toHeight: 887_412 } }, + { protocolId: 'stamps', displayName: 'Stamps', chain: 'bitcoin', family: 'inscriptions', releaseStatus: 'experimental', authority: 'stampchain', coverage: { fromHeight: 779_652, toHeight: 886_900 } }, + { protocolId: 'atomicals', displayName: 'Atomicals', chain: 'bitcoin', family: 'fungible', releaseStatus: 'blocked', authority: null, coverage: null }, + ], + }, + + '/api/v1/universe/pulse': { + checked: 512, + authorityAnswering: true, + counts: { ordinals: 41, runes: 12, alkanes: 3, stamps: 0 }, + }, +}; + +/** Address with history, and its transactions. */ +export const addressFixtures = { + [`/api/address/${ADDRESS}`]: { + address: ADDRESS, + chain_stats: { funded_txo_count: 42, funded_txo_sum: 184_002_881, spent_txo_count: 38, spent_txo_sum: 171_004_002, tx_count: 51 }, + mempool_stats: { funded_txo_count: 1, funded_txo_sum: 220_000, spent_txo_count: 0, spent_txo_sum: 0, tx_count: 1 }, + }, +}; + +/** + * States the matrix has to prove beyond the populated one. Each entry maps a + * URL pattern to a response, so a run can assert that the interface says + * something true when the answer is missing rather than showing a confident + * zero. + */ +export const stateOverrides = { + // Every Universe authority call fails. The interface must say it could not + // reach the authority, and must not report "0 protocols" as if that were an + // answer. + 'authority-down': { + '/api/v1/universe/protocols': { status: 502 }, + '/api/v1/universe/pulse': { status: 502 }, + }, + + // The registry answers, but with nothing in it. + 'authority-empty': { + '/api/v1/universe/protocols': { body: { registryVersion: '2026.08.1', protocols: [] } }, + }, + + // Core chain data is unavailable. + 'chain-down': { + '/api/v1/fees/recommended': { status: 502 }, + '/api/v1/blocks': { status: 502 }, + '/api/v1/difficulty-adjustment': { status: 502 }, + }, + + // Requests never resolve, so every surface stays in its loading state. + loading: { '**': { hang: true } }, + + // An address that has never been used. + 'address-empty': { + [`/api/address/${ADDRESS}`]: { + body: { + address: ADDRESS, + chain_stats: { funded_txo_count: 0, funded_txo_sum: 0, spent_txo_count: 0, spent_txo_sum: 0, tx_count: 0 }, + mempool_stats: { funded_txo_count: 0, funded_txo_sum: 0, spent_txo_count: 0, spent_txo_sum: 0, tx_count: 0 }, + }, + }, + [`/api/address/${ADDRESS}/txs`]: { body: [] }, + }, +}; + +export const sampleIds = { TXID_A, TXID_B, TXID_C, ADDRESS, BLOCK_HASH }; + +function buildMempoolStats() { + const now = Math.floor(Date.now() / 1000); + const points = []; + for (let i = 120; i >= 0; i--) { + const drift = Math.sin(i / 9) * 40 + Math.cos(i / 4) * 12; + points.push({ + added: now - i * 60, + count: Math.round(28_000 + drift * 120), + vbytes_per_second: Math.round(1_600 + drift * 6), + total_fee: Math.round(88_000_000 + drift * 200_000), + mempool_byte_weight: Math.round(112_000_000 + drift * 400_000), + vsizes: Array.from({ length: 38 }, (_, band) => Math.round(Math.max(0, 900 - band * 22 + drift))), + }); + } + return points; +} diff --git a/scripts/universe/visual-qa/package-lock.json b/scripts/universe/visual-qa/package-lock.json new file mode 100644 index 00000000000..33a81a00c44 --- /dev/null +++ b/scripts/universe/visual-qa/package-lock.json @@ -0,0 +1,86 @@ +{ + "name": "universe-visual-qa", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "universe-visual-qa", + "version": "1.0.0", + "devDependencies": { + "@axe-core/playwright": "^4.10.0", + "playwright": "^1.49.0" + } + }, + "node_modules/@axe-core/playwright": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/@axe-core/playwright/-/playwright-4.13.0.tgz", + "integrity": "sha512-6YLx+kxXu5GJceG4ozFg+33a2EMTdjYwWGloJ3sb9Kta5pp+ZNS53uxGVog5JetIY8s++P5UrtX+cri+u0VAVg==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "axe-core": "~4.13.0" + }, + "peerDependencies": { + "playwright-core": ">= 1.0.0" + } + }, + "node_modules/axe-core": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.13.0.tgz", + "integrity": "sha512-UzGt8zg7Ny8djbYMhxl2zuEevVa7r2gJjYY5Lwr1xM7+XU2nd6CkIWFTVcCIbAP63vSz71NaVyyuSk9lHKcy0A==", + "dev": true, + "license": "MPL-2.0", + "engines": { + "node": ">=4" + } + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/playwright": { + "version": "1.62.1", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.62.1.tgz", + "integrity": "sha512-0M+L3LAD8/nm554LOla9Ayx0j0tmFZ0FBcoQ7F1VuVHpM/XpiC8RcDzBQB8W5+hA8L22THxELzeF+2WcUzvcLg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "playwright-core": "1.62.1" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=20" + }, + "optionalDependencies": { + "fsevents": "2.3.2" + } + }, + "node_modules/playwright-core": { + "version": "1.62.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.62.1.tgz", + "integrity": "sha512-wPYSwEBJY9GHraISXqyqtx0na0LpO3XEX7jNDhntbex7tzUS7kLnZsOlFruFJB4Hi/rhDMjXGqHewDZ68nYZVw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=20" + } + } + } +} diff --git a/scripts/universe/visual-qa/package.json b/scripts/universe/visual-qa/package.json new file mode 100644 index 00000000000..af912120125 --- /dev/null +++ b/scripts/universe/visual-qa/package.json @@ -0,0 +1,11 @@ +{ + "name": "universe-visual-qa", + "version": "1.0.0", + "private": true, + "description": "Visual regression, accessibility, and cross-browser checks for Universe Explorer.", + "type": "module", + "devDependencies": { + "@axe-core/playwright": "^4.10.0", + "playwright": "^1.49.0" + } +}